> Subject: Re: [PATCH] drm/i915/display: Use PIPEDMC_FRMTMSTMP on
> display ver >= 30
>
> On Fri, May 15, 2026 at 09:40:56PM +0530, Suraj Kandpal wrote:
> > Starting with display version 30, the per-pipe frame timestamp is read
> > from the PIPEDMC register block (PIPEDMC_FRMTMSTMP) instead of the
> > legacy PIPE_FRMTMSTMP MMIO. Extend PIPE_FRMTMSTMP() to take the
> > display and select the appropriate register based on DISPLAY_VER(),
> > and update all callers intel_vblank accordingly.
> >
> > Bspec: 79482
> > Signed-off-by: Suraj Kandpal <[email protected]>
> > ---
> > v1 -> v2:
> > - Define registers in correct location (Jani)
> > - Use the intel_display_wa() helper to select the correct register
> > (Gustavo)
> > - Fix early vblank timeout issue when DMC is not loaded
> >
> > .../gpu/drm/i915/display/intel_display_wa.c | 2 ++
> > .../gpu/drm/i915/display/intel_display_wa.h | 1 +
> > drivers/gpu/drm/i915/display/intel_dmc_regs.h | 6 ++++++
> > drivers/gpu/drm/i915/display/intel_vblank.c | 18 ++++++++++++++----
> > 4 files changed, 23 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c
> > b/drivers/gpu/drm/i915/display/intel_display_wa.c
> > index 7d3d63a59882..44c2a503c911 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_wa.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_wa.c
> > @@ -110,6 +110,8 @@ bool __intel_display_wa(struct intel_display
> *display, enum intel_display_wa wa,
> > return DISPLAY_VERx100(display) == 3000 ||
> > DISPLAY_VERx100(display) == 2000 ||
> > DISPLAY_VERx100(display) == 1401;
> > + case INTEL_DISPLAY_WA_14022946399:
> > + return DISPLAY_VER(display) >= 30;
>
> According to bspec PIPEDMC_FRMTMSTMP shouldn't even exist on PTL.
> Did you actually check that the register works?
Yes you are correct seems like this does not exist on PTL, weird that the Xe.CI
does not throw any error In relation to this.
>
> And I believe the hw register corruption issue being addressed by w/a
> 14022946399 (also applies to LNL) should anyway be fixed on the platforms
> that have PIPEDMC_FRMTMSTMP so this w/a stuff here makes no sense.
Hmm the confusing thing here is this same WA has two ways to go about it. From
NVL onwards we need to ready the PIPEDMC_FRMTMSPTMP
But before that it was that we read the FRMTMSTMP register once per frame.
So for display ver >= 35 we maybe should still switch to PIPEDMC_FRMTMSTMP
Regards,
Suraj Kandpal
>
> > case INTEL_DISPLAY_WA_14025769978:
> > return DISPLAY_VER(display) == 35;
> > case INTEL_DISPLAY_WA_15013987218:
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h
> > b/drivers/gpu/drm/i915/display/intel_display_wa.h
> > index 15fec843f15e..884463a894c8 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_wa.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_wa.h
> > @@ -42,6 +42,7 @@ enum intel_display_wa {
> > INTEL_DISPLAY_WA_14014143976,
> > INTEL_DISPLAY_WA_14016740474,
> > INTEL_DISPLAY_WA_14020863754,
> > + INTEL_DISPLAY_WA_14022946399,
> > INTEL_DISPLAY_WA_14025769978,
> > INTEL_DISPLAY_WA_15013987218,
> > INTEL_DISPLAY_WA_15018326506,
> > diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> > b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> > index 38e342b45af0..985642a79a52 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> > +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> > @@ -644,4 +644,10 @@ enum pipedmc_event_id {
> > #define _PIPEDMC_DCB_BALANCE_RESET_B 0x986a8
> > #define PIPEDMC_DCB_BALANCE_RESET(pipe)
> _MMIO_PIPE(pipe, _PIPEDMC_DCB_BALANCE_RESET_A,\
> >
> _PIPEDMC_DCB_BALANCE_RESET_B)
> > +
> > +#define _PIPEDMC_FRMTMSTMP_A 0x5f0ac
> > +#define _PIPEDMC_FRMTMSTMP_B 0x5f4ac
> > +#define PIPEDMC_FRMTMSTMP(pipe) \
> > + _MMIO_PIPE(pipe, _PIPEDMC_FRMTMSTMP_A,
> _PIPEDMC_FRMTMSTMP_B)
> > +
> > #endif /* __INTEL_DMC_REGS_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c
> > b/drivers/gpu/drm/i915/display/intel_vblank.c
> > index 28d81199792e..145c342f445f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_vblank.c
> > +++ b/drivers/gpu/drm/i915/display/intel_vblank.c
> > @@ -15,6 +15,8 @@
> > #include "intel_display_regs.h"
> > #include "intel_display_types.h"
> > #include "intel_display_utils.h"
> > +#include "intel_display_wa.h"
> > +#include "intel_dmc_regs.h"
> > #include "intel_vblank.h"
> > #include "intel_vrr.h"
> >
> > @@ -156,8 +158,12 @@ static u32
> intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)
> > * pipe frame time stamp. The time stamp value
> > * is sampled at every start of vertical blank.
> > */
> > - scan_prev_time = intel_de_read_fw(display,
> > - PIPE_FRMTMSTMP(crtc-
> >pipe));
> > + if (intel_display_wa(display,
> INTEL_DISPLAY_WA_14022946399))
> > + scan_prev_time = intel_de_read_fw(display,
> > +
> PIPEDMC_FRMTMSTMP(crtc->pipe));
> > + else
> > + scan_prev_time = intel_de_read_fw(display,
> > +
> PIPE_FRMTMSTMP(crtc->pipe));
> >
> > /*
> > * The TIMESTAMP_CTR register has the current @@ -165,8
> +171,12 @@
> > static u32 intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc
> *crtc)
> > */
> > scan_curr_time = intel_de_read_fw(display,
> IVB_TIMESTAMP_CTR);
> >
> > - scan_post_time = intel_de_read_fw(display,
> > - PIPE_FRMTMSTMP(crtc-
> >pipe));
> > + if (intel_display_wa(display,
> INTEL_DISPLAY_WA_14022946399))
> > + scan_post_time = intel_de_read_fw(display,
> > +
> PIPEDMC_FRMTMSTMP(crtc->pipe));
> > + else
> > + scan_post_time = intel_de_read_fw(display,
> > +
> PIPE_FRMTMSTMP(crtc->pipe));
> > } while (scan_post_time != scan_prev_time);
> >
> > return div_u64(mul_u32_u32(scan_curr_time - scan_prev_time,
> > --
> > 2.34.1
>
> --
> Ville Syrjälä
> Intel