[RFC PATCH 6/6] drm/i915/psr: Implement Wa_14017110345 / Wa_14016945873

Jouni Högander jouni.hogander at intel.com
Tue Feb 7 12:03:26 UTC 2023


Bspec: 55378, 52890, 54369, 66624

Signed-off-by: Jouni Högander <jouni.hogander at intel.com>
---
 drivers/gpu/drm/i915/display/intel_cursor.c   | 18 ++++++-
 .../drm/i915/display/intel_display_types.h    |  2 +
 drivers/gpu/drm/i915/display/intel_psr.c      | 49 ++++++++++++++++++-
 3 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 87c654b20a83..b90dd6f6b7df 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -489,13 +489,13 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
 					     const struct intel_crtc_state *crtc_state,
 					     const struct intel_plane_state *plane_state)
 {
-	struct drm_i915_private *i915 = to_i915(plane->base.dev);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
 
 	if (!crtc_state->enable_psr2_sel_fetch)
 		return;
 
-	intel_de_write_fw(i915, PLANE_SEL_FETCH_CTL(pipe, plane->id),
+	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
 			  plane_state->ctl);
 }
 
@@ -509,6 +509,14 @@ static void i9xx_cursor_disable_sel_fetch_noarm(struct intel_plane *plane,
 		return;
 
 	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), 0);
+
+	/*
+	 * Wa_14017110345
+	 * Wa_14016945873
+	 */
+	plane->cursor.cntl_restore = plane->cursor.cntl;
+	plane->cursor.cntl = 0;
+	intel_de_write_fw(dev_priv, CURCNTR(pipe), 0);
 }
 
 /* TODO: split into noarm+arm pair */
@@ -574,6 +582,12 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
 		plane->cursor.base = base;
 		plane->cursor.size = fbc_ctl;
 		plane->cursor.cntl = cntl;
+
+		/*
+		 * Wa_14017110345
+		 * Wa_14016945873
+		 */
+		plane->cursor.cntl_restore = cntl;
 	} else {
 		intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
 		intel_de_write_fw(dev_priv, CURBASE(pipe), base);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 26e24e18ec2c..9e33b211d83f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1451,6 +1451,8 @@ struct intel_plane {
 
 	struct {
 		u32 base, cntl, size;
+		/* Wa_14016945873 */
+		u32 cntl_restore;
 	} cursor;
 
 	struct intel_fbc *fbc;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 087575f408f0..d0099bc60ee9 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1266,6 +1266,32 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
 	intel_psr_activate(intel_dp);
 }
 
+/*
+ * Wa_14017110345
+ * Wa_14016945873
+ */
+static void intel_psr_cursor_restore(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct intel_crtc *intel_crtc;
+	struct intel_plane *intel_plane;
+
+	for_each_intel_crtc(&dev_priv->drm, intel_crtc) {
+		if (intel_crtc->pipe != intel_dp->psr.pipe)
+			continue;
+
+		for_each_intel_plane_on_crtc(&dev_priv->drm, intel_crtc,
+					     intel_plane) {
+			if (intel_plane->id != PLANE_CURSOR)
+				continue;
+
+			if (intel_plane->cursor.cntl_restore != intel_plane->cursor.cntl)
+				intel_de_write_fw(dev_priv, CURCNTR(intel_crtc->pipe),
+						  intel_plane->cursor.cntl_restore);
+		}
+	}
+}
+
 static void intel_psr_exit(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1287,6 +1313,12 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
 
 	if (intel_dp->psr.psr2_enabled) {
 		tgl_disallow_dc3co_on_psr2_exit(intel_dp);
+
+		/*
+		 * Wa_14017110345
+		 * Wa_14016945873
+		 */
+		intel_psr_cursor_restore(intel_dp);
 		val = intel_de_read(dev_priv,
 				    EDP_PSR2_CTL(intel_dp->psr.transcoder));
 		drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE));
@@ -1498,13 +1530,19 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-	if (intel_dp->psr.psr2_sel_fetch_enabled)
+	if (intel_dp->psr.psr2_sel_fetch_enabled) {
+		/*
+		 * Wa_14017110345
+		 * Wa_14016945873
+		 */
+		intel_psr_cursor_restore(intel_dp);
 		intel_de_write(dev_priv,
 			       PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
 			       man_trk_ctl_enable_bit_get(dev_priv) |
 			       man_trk_ctl_partial_frame_bit_get(dev_priv) |
 			       man_trk_ctl_single_full_frame_bit_get(dev_priv) |
 			       man_trk_ctl_continuos_full_frame(dev_priv));
+	}
 
 	/*
 	 * Display WA #0884: skl+
@@ -1813,6 +1851,10 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 	}
 
 skip_sel_fetch_set_loop:
+	/* Due to WA we need to ensure cursor plane is re-enabled on full_update */
+	if (full_update)
+		crtc_state->update_planes |= BIT(PLANE_CURSOR);
+
 	psr2_man_trk_ctl_calc(crtc_state, &pipe_clip, full_update);
 	return 0;
 }
@@ -2153,6 +2195,11 @@ static void _psr_invalidate_handle(struct intel_dp *intel_dp)
 			return;
 		}
 
+		/*
+		 * Wa_14017110345
+		 * Wa_14016945873
+		 */
+		intel_psr_cursor_restore(intel_dp);
 		val = man_trk_ctl_enable_bit_get(dev_priv) |
 		      man_trk_ctl_partial_frame_bit_get(dev_priv) |
 		      man_trk_ctl_continuos_full_frame(dev_priv);
-- 
2.34.1



More information about the Intel-gfx-trybot mailing list