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