From: Ville Syrjälä <[email protected]>

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

TODO: figure out if PTL-B0+ firmware still implements the w/a

Signed-off-by: Ville Syrjälä <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_display.c |  8 ++++++++
 drivers/gpu/drm/i915/display/intel_flipq.c   | 10 ++++++++++
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 3a42536247d8..76ed34adc08d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7232,6 +7232,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);
+
                if (intel_crtc_needs_color_update(new_crtc_state))
                        intel_color_commit_noarm(new_crtc_state->dsb_commit,
                                                 new_crtc_state);
@@ -7262,6 +7266,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 (new_crtc_state->dsb_color_vblank)
diff --git a/drivers/gpu/drm/i915/display/intel_flipq.c 
b/drivers/gpu/drm/i915/display/intel_flipq.c
index 8677929b7ece..c4b4ecd44eb2 100644
--- a/drivers/gpu/drm/i915/display/intel_flipq.c
+++ b/drivers/gpu/drm/i915/display/intel_flipq.c
@@ -304,3 +304,13 @@ void intel_flipq_add(struct intel_crtc *crtc,
 
        intel_flipq_sw_dmc_wake(crtc);
 }
+
+void intel_flipq_wait_dmc_halt(struct intel_dsb *dsb)
+{
+       intel_dsb_wait_usec(dsb, 2);
+}
+
+void intel_flipq_unhalt_dmc(struct intel_dsb *dsb, struct intel_crtc *crtc)
+{
+       intel_dsb_reg_write(dsb, PIPEDMC_CTL(crtc->pipe), 0);
+}
-- 
2.49.0

Reply via email to