> -----Original Message----- > From: Intel-gfx <intel-gfx-boun...@lists.freedesktop.org> On Behalf Of Ville > Syrjala > Sent: Monday, June 9, 2025 7:41 PM > To: intel-gfx@lists.freedesktop.org > Cc: intel...@lists.freedesktop.org > Subject: [PATCH v4 17/21] drm/i915/flipq: Implement Wa_18034343758 > > From: Ville Syrjälä <ville.syrj...@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
Changes Look Good to me. Reviewed-by: Uma Shankar <uma.shan...@intel.com> > Signed-off-by: Ville Syrjälä <ville.syrj...@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