[PATCH] drm/i915: wait PSR state back to idle when turn PSR off

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Driver should refer to commit 'b2fc2252ce41 ("drm/i915/psr:
Always wait for idle state when disabling PSR")' to wait for
idle state when turn PSR off. But it did not follow
previous method. Driver just call intel_psr_exit() in
intel_psr_invalidate() and psr_force_hw_tracking_exit().
Then leave the function right away.

After PSR disabled, we found some user space applications
would enabled PSR again immediately. That caused particular
TCON to get into incorrect state machine and can't recognize
video data from source properly.

Add this change to wait PSR idle state in intel_psr_invalidate()
and psr_force_hw_tracking_exit(). This symptom is not able
to replicate anymore.

Fixes: b2fc2252ce41 (drm/i915/psr: Always wait for idle state
when disabling PSR).

Cc: Manasi Navare <manasi.d.navare@xxxxxxxxx>
Cc: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx>
Cc: Ville Syrjala <ville.syrjala@xxxxxxxxxxxxxxx>
Cc: José Roberto de Souza <jose.souza@xxxxxxxxx>
Cc: Cooper Chiou <cooper.chiou@xxxxxxxxx>
Cc: Khaled Almahallawy <khaled.almahallawy@xxxxxxxxx>
Signed-off-by: Lee Shawn C <shawn.c.lee@xxxxxxxxx>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 43 ++++++++++++++----------
 1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index a591a475f148..83b642a5567e 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1036,6 +1036,25 @@ void intel_psr_enable(struct intel_dp *intel_dp,
 	mutex_unlock(&dev_priv->psr.lock);
 }
 
+static void intel_psr_wait_idle(struct drm_i915_private *dev_priv)
+{
+	i915_reg_t psr_status;
+	u32 psr_status_mask;
+
+	if (dev_priv->psr.psr2_enabled) {
+		psr_status = EDP_PSR2_STATUS(dev_priv->psr.transcoder);
+		psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
+	} else {
+		psr_status = EDP_PSR_STATUS(dev_priv->psr.transcoder);
+		psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
+	}
+
+	/* Wait till PSR is idle */
+	if (intel_de_wait_for_clear(dev_priv, psr_status,
+				    psr_status_mask, 2000))
+		drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n");
+}
+
 static void intel_psr_exit(struct drm_i915_private *dev_priv)
 {
 	u32 val;
@@ -1076,8 +1095,6 @@ static void intel_psr_exit(struct drm_i915_private *dev_priv)
 static void intel_psr_disable_locked(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	i915_reg_t psr_status;
-	u32 psr_status_mask;
 
 	lockdep_assert_held(&dev_priv->psr.lock);
 
@@ -1088,19 +1105,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
 		    dev_priv->psr.psr2_enabled ? "2" : "1");
 
 	intel_psr_exit(dev_priv);
-
-	if (dev_priv->psr.psr2_enabled) {
-		psr_status = EDP_PSR2_STATUS(dev_priv->psr.transcoder);
-		psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
-	} else {
-		psr_status = EDP_PSR_STATUS(dev_priv->psr.transcoder);
-		psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
-	}
-
-	/* Wait till PSR is idle */
-	if (intel_de_wait_for_clear(dev_priv, psr_status,
-				    psr_status_mask, 2000))
-		drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n");
+	intel_psr_wait_idle(dev_priv);
 
 	/* WA 1408330847 */
 	if (dev_priv->psr.psr2_sel_fetch_enabled &&
@@ -1158,12 +1163,14 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
 		 * pipe.
 		 */
 		intel_de_write(dev_priv, CURSURFLIVE(dev_priv->psr.pipe), 0);
-	else
+	else {
 		/*
 		 * A write to CURSURFLIVE do not cause HW tracking to exit PSR
 		 * on older gens so doing the manual exit instead.
 		 */
 		intel_psr_exit(dev_priv);
+		intel_psr_wait_idle(dev_priv);
+	}
 }
 
 void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
@@ -1593,8 +1600,10 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv,
 	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe);
 	dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
 
-	if (frontbuffer_bits)
+	if (frontbuffer_bits) {
 		intel_psr_exit(dev_priv);
+		intel_psr_wait_idle(dev_priv);
+	}
 
 	mutex_unlock(&dev_priv->psr.lock);
 }
-- 
2.17.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux