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
