Commit 169de131 authored by Rodrigo Vivi's avatar Rodrigo Vivi Committed by Daniel Vetter

drm/i915: PSR: Flush means invalidate + flush

Since flush actually means invalidate + flush we need to force psr
exit on PSR flush.

On Core platforms there is no way to disable hw tracking and
do the pure sw tracking so we simulate it by fully disable psr and
reschedule a enable back.
So a good idea is to minimize sequential disable/enable in cases we
know that HW tracking like when flush has been originated by a flip.
Also flip had just invalidated it already.

It also uses origin to minimize the a bit the amount of
disable/enabled, mainly when flip already had invalidated.

With this patch in place it is possible to do a flush on dirty areas
properly in a following patch.

v2: Remove duplicated exit on HSW+Sprites as pointed out by Paulo.

Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent de152b62
...@@ -1329,7 +1329,8 @@ void intel_psr_disable(struct intel_dp *intel_dp); ...@@ -1329,7 +1329,8 @@ void intel_psr_disable(struct intel_dp *intel_dp);
void intel_psr_invalidate(struct drm_device *dev, void intel_psr_invalidate(struct drm_device *dev,
unsigned frontbuffer_bits); unsigned frontbuffer_bits);
void intel_psr_flush(struct drm_device *dev, void intel_psr_flush(struct drm_device *dev,
unsigned frontbuffer_bits); unsigned frontbuffer_bits,
enum fb_op_origin origin);
void intel_psr_init(struct drm_device *dev); void intel_psr_init(struct drm_device *dev);
void intel_psr_single_frame_update(struct drm_device *dev, void intel_psr_single_frame_update(struct drm_device *dev,
unsigned frontbuffer_bits); unsigned frontbuffer_bits);
......
...@@ -128,7 +128,7 @@ void intel_frontbuffer_flush(struct drm_device *dev, ...@@ -128,7 +128,7 @@ void intel_frontbuffer_flush(struct drm_device *dev,
return; return;
intel_edp_drrs_flush(dev, frontbuffer_bits); intel_edp_drrs_flush(dev, frontbuffer_bits);
intel_psr_flush(dev, frontbuffer_bits); intel_psr_flush(dev, frontbuffer_bits, origin);
intel_fbc_flush(dev_priv, frontbuffer_bits); intel_fbc_flush(dev_priv, frontbuffer_bits);
} }
......
...@@ -680,6 +680,7 @@ void intel_psr_invalidate(struct drm_device *dev, ...@@ -680,6 +680,7 @@ void intel_psr_invalidate(struct drm_device *dev,
* intel_psr_flush - Flush PSR * intel_psr_flush - Flush PSR
* @dev: DRM device * @dev: DRM device
* @frontbuffer_bits: frontbuffer plane tracking bits * @frontbuffer_bits: frontbuffer plane tracking bits
* @origin: which operation caused the flush
* *
* Since the hardware frontbuffer tracking has gaps we need to integrate * Since the hardware frontbuffer tracking has gaps we need to integrate
* with the software frontbuffer tracking. This function gets called every * with the software frontbuffer tracking. This function gets called every
...@@ -689,7 +690,7 @@ void intel_psr_invalidate(struct drm_device *dev, ...@@ -689,7 +690,7 @@ void intel_psr_invalidate(struct drm_device *dev,
* Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits. * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
*/ */
void intel_psr_flush(struct drm_device *dev, void intel_psr_flush(struct drm_device *dev,
unsigned frontbuffer_bits) unsigned frontbuffer_bits, enum fb_op_origin origin)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -707,24 +708,25 @@ void intel_psr_flush(struct drm_device *dev, ...@@ -707,24 +708,25 @@ void intel_psr_flush(struct drm_device *dev,
frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits; dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
if (HAS_DDI(dev)) {
/* /*
* On Haswell sprite plane updates don't result in a psr invalidating * By definition every flush should mean invalidate + flush,
* signal in the hardware. Which means we need to manually fake this in * however on core platforms let's minimize the
* software for all flushes, not just when we've seen a preceding * disable/re-enable so we can avoid the invalidate when flip
* invalidation through frontbuffer rendering. * originated the flush.
*/ */
if (IS_HASWELL(dev) && if (frontbuffer_bits && origin != ORIGIN_FLIP)
(frontbuffer_bits & INTEL_FRONTBUFFER_SPRITE(pipe)))
intel_psr_exit(dev); intel_psr_exit(dev);
} else {
/* /*
* On Valleyview and Cherryview we don't use hardware tracking so * On Valleyview and Cherryview we don't use hardware tracking
* any plane updates or cursor moves don't result in a PSR * so any plane updates or cursor moves don't result in a PSR
* invalidating. Which means we need to manually fake this in * invalidating. Which means we need to manually fake this in
* software for all flushes, not just when we've seen a preceding * software for all flushes.
* invalidation through frontbuffer rendering. */ */
if (frontbuffer_bits && !HAS_DDI(dev)) if (frontbuffer_bits)
intel_psr_exit(dev); intel_psr_exit(dev);
}
if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
schedule_delayed_work(&dev_priv->psr.work, schedule_delayed_work(&dev_priv->psr.work,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment