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

Reply via email to