[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