From cd0121502ce61a2efec23fb61b90ffec300be281 Mon Sep 17 00:00:00 2001 From: Dibin Moolakadan Subrahmanian Date: Wed, 1 Jul 2026 15:36:50 +0530 Subject: [PATCH] drm/i915/psr: Block DC3CO entry during active frame On Xe3P, when PSR2 is enabled on a panel that does not support Early Transport, DC3CO can be entered in the middle of an active frame. This prevents the pipe from completing the frame and leaves it in a bad state that does not recover well, causing visible corruption on screen. Set CHICKEN_DCPR_4 bit 24 in the PSR2 enable path when Early Transport is not in use, to notify DMC to prevent DC3CO entry. v2: - Remove display from commit header (Suraj Kandpal). - Add HSD number to intel_display_wa framework (Suraj Kandpal). - Change register prefix from XE3LPD_ to XE3P_ (Suraj Kandpal). BSpec: 71483, 75253 Signed-off-by: Dibin Moolakadan Subrahmanian Reviewed-by: Suraj Kandpal Signed-off-by: Suraj Kandpal Link: https://patch.msgid.link/20260701100650.1689665-2-dibin.moolakadan.subrahmanian@intel.com --- .../gpu/drm/i915/display/intel_display_regs.h | 3 +++ drivers/gpu/drm/i915/display/intel_display_wa.c | 2 ++ drivers/gpu/drm/i915/display/intel_display_wa.h | 1 + drivers/gpu/drm/i915/display/intel_psr.c | 16 ++++++++++++++++ 4 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h index 39e50423132f..0f5018482497 100644 --- a/drivers/gpu/drm/i915/display/intel_display_regs.h +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h @@ -1747,6 +1747,9 @@ #define XELPD_CHICKEN_DCPR_3 _MMIO(0x46438) #define DMD_RSP_TIMEOUT_DISABLE REG_BIT(19) +#define XE3P_CHICKEN_DCPR_4 _MMIO(0x454a0) +#define DCPR4_BLOCK_DC3CO_ACTIVE_FRAME REG_BIT(24) + #define SKL_DFSM _MMIO(0x51000) #define SKL_DFSM_DISPLAY_PM_DISABLE (1 << 27) #define SKL_DFSM_DISPLAY_HDCP_DISABLE (1 << 25) diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c index 2094eda09c91..b4c49816f7eb 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.c +++ b/drivers/gpu/drm/i915/display/intel_display_wa.c @@ -112,6 +112,8 @@ bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, DISPLAY_VERx100(display) == 1401; case INTEL_DISPLAY_WA_14025769978: return DISPLAY_VER(display) == 35; + case INTEL_DISPLAY_WA_14026643300: + return DISPLAY_VER(display) == 35; case INTEL_DISPLAY_WA_15013987218: return DISPLAY_VER(display) == 20; case INTEL_DISPLAY_WA_15018326506: diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h index 9cdd148ea4fa..92b3980bea84 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.h +++ b/drivers/gpu/drm/i915/display/intel_display_wa.h @@ -43,6 +43,7 @@ enum intel_display_wa { INTEL_DISPLAY_WA_14016740474, INTEL_DISPLAY_WA_14020863754, INTEL_DISPLAY_WA_14025769978, + INTEL_DISPLAY_WA_14026643300, INTEL_DISPLAY_WA_15013987218, INTEL_DISPLAY_WA_15018326506, INTEL_DISPLAY_WA_16011181250, diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 92af21d823a3..40e3d7095996 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2100,6 +2100,18 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, else if (display->platform.alderlake_p) intel_de_rmw(display, CLKGATE_DIS_MISC, 0, CLKGATE_DIS_MISC_DMASC_GATING_DIS); + + /* + * Wa_14026643300 + * On Xe3P, restrict DC3CO entry during active frame when PSR2 is + * enabled without panel Early Transport; required to avoid pipe bad state. + * DMC honours CHICKEN_DCPR_4 bit 24 to block DC3CO entry during active frame. + */ + if (intel_display_wa(display, INTEL_DISPLAY_WA_14026643300) && + !intel_dp->psr.panel_replay_enabled && + !intel_dp->psr.su_region_et_enabled) + intel_de_rmw(display, XE3P_CHICKEN_DCPR_4, + 0, DCPR4_BLOCK_DC3CO_ACTIVE_FRAME); } /* Wa_16025596647 */ @@ -2341,6 +2353,10 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) else if (display->platform.alderlake_p) intel_de_rmw(display, CLKGATE_DIS_MISC, CLKGATE_DIS_MISC_DMASC_GATING_DIS, 0); + + if (intel_display_wa(display, INTEL_DISPLAY_WA_14026643300)) + intel_de_rmw(display, XE3P_CHICKEN_DCPR_4, + DCPR4_BLOCK_DC3CO_ACTIVE_FRAME, 0); } if (intel_dp_is_edp(intel_dp))