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; 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
