[PATCH v4 17/21] drm/i915/flipq: Implement Wa_18034343758
Ville Syrjala
ville.syrjala at linux.intel.com
Mon Jun 9 14:10:42 UTC 2025
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Implement the driver side of Wa_18034343758, which is supposed to
prevent the DSB and DMC from accessing registers in parallel, and
thus potentially corrupting the registers due to a hardware issue
(which should be fixed in PTL-B0).
The w/a sequence goes as follows:
DMC starts the DSB
| \
DMC halts itself | DSB waits a while for DMC to have time to halt
. | DSB executes normally
. | DSB unhalts the DMC at the very end
. /
DMC resumes execution
v2: PTL-B0+ firmware no longer has the w/a since the hw got fixed
v3: Do the w/a on all PTL for now since we only have the A0 firmware
binaries which issues the halt instructions unconditionally
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/i915/display/intel_display.c | 8 ++++++
drivers/gpu/drm/i915/display/intel_flipq.c | 27 ++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_flipq.h | 2 ++
3 files changed, 37 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 04492cb9446a..4b69121ed9b7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7238,6 +7238,10 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state,
}
if (new_crtc_state->use_flipq || new_crtc_state->use_dsb) {
+ /* Wa_18034343758 */
+ if (new_crtc_state->use_flipq)
+ intel_flipq_wait_dmc_halt(new_crtc_state->dsb_commit, crtc);
+
if (intel_crtc_needs_color_update(new_crtc_state))
intel_color_commit_noarm(new_crtc_state->dsb_commit,
new_crtc_state);
@@ -7268,6 +7272,10 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state,
if (DISPLAY_VER(display) >= 9)
skl_detach_scalers(new_crtc_state->dsb_commit,
new_crtc_state);
+
+ /* Wa_18034343758 */
+ if (new_crtc_state->use_flipq)
+ intel_flipq_unhalt_dmc(new_crtc_state->dsb_commit, crtc);
}
if (intel_color_uses_chained_dsb(new_crtc_state))
diff --git a/drivers/gpu/drm/i915/display/intel_flipq.c b/drivers/gpu/drm/i915/display/intel_flipq.c
index 2f5100c47059..3a5a1fdb876b 100644
--- a/drivers/gpu/drm/i915/display/intel_flipq.c
+++ b/drivers/gpu/drm/i915/display/intel_flipq.c
@@ -386,3 +386,30 @@ void intel_flipq_add(struct intel_crtc *crtc,
intel_flipq_sw_dmc_wake(crtc);
}
+
+/* Wa_18034343758 */
+static bool need_dmc_halt_wa(struct intel_display *display)
+{
+ /*
+ * FIXME exclude PTL-B0+ once we have firmware
+ * for it without the halt instructions.
+ */
+ return DISPLAY_VER(display) == 20 ||
+ DISPLAY_VER(display) == 30;
+}
+
+void intel_flipq_wait_dmc_halt(struct intel_dsb *dsb, struct intel_crtc *crtc)
+{
+ struct intel_display *display = to_intel_display(crtc);
+
+ if (need_dmc_halt_wa(display))
+ intel_dsb_wait_usec(dsb, 2);
+}
+
+void intel_flipq_unhalt_dmc(struct intel_dsb *dsb, struct intel_crtc *crtc)
+{
+ struct intel_display *display = to_intel_display(crtc);
+
+ if (need_dmc_halt_wa(display))
+ intel_dsb_reg_write(dsb, PIPEDMC_CTL(crtc->pipe), 0);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_flipq.h b/drivers/gpu/drm/i915/display/intel_flipq.h
index 195ff0dd83f5..2d4386a16197 100644
--- a/drivers/gpu/drm/i915/display/intel_flipq.h
+++ b/drivers/gpu/drm/i915/display/intel_flipq.h
@@ -29,5 +29,7 @@ void intel_flipq_add(struct intel_crtc *crtc,
enum intel_dsb_id dsb_id,
struct intel_dsb *dsb);
int intel_flipq_exec_time_us(struct intel_display *display);
+void intel_flipq_wait_dmc_halt(struct intel_dsb *dsb, struct intel_crtc *crtc);
+void intel_flipq_unhalt_dmc(struct intel_dsb *dsb, struct intel_crtc *crtc);
#endif /* __INTEL_FLIPQ_H__ */
--
2.49.0
More information about the Intel-xe
mailing list