From: Jouni Högander Date: Mon, 14 Apr 2025 10:05:05 +0000 (+0300) Subject: drm/i915/dmc: Add interface to control start of PKG C-state exit X-Git-Tag: v6.16-rc1~144^2~12^2~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2978eb1841cd635f17e568ad74ffa32f68fcd54d;p=thirdparty%2Flinux.git drm/i915/dmc: Add interface to control start of PKG C-state exit Add interface to control if package C exit starts at the start of the undelayed vblank. This is needed to implement workaround for underrun on idle PSR HW issue (Wa_16025596647). Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://lore.kernel.org/r/20250414100508.1208774-11-jouni.hogander@intel.com --- diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 8360385ed140b..b58189d24e7e4 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -533,6 +533,37 @@ void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe, PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS : 0); } +/** + * intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank() - start of PKG + * C-state exit + * @display: display instance + * @pipe: pipe which register use to block + * @enable: enable/disable + * + * This interface is target for Wa_16025596647 usage. I.e. start the package C + * exit at the start of the undelayed vblank + */ +void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display, + enum pipe pipe, bool enable) +{ + u32 val; + + if (enable) + val = DMC_EVT_CTL_ENABLE | DMC_EVT_CTL_RECURRING | + REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK, + DMC_EVT_CTL_TYPE_EDGE_0_1) | + REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK, + DMC_EVT_CTL_EVENT_ID_VBLANK_A); + else + val = REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK, + DMC_EVT_CTL_EVENT_ID_FALSE) | + REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK, + DMC_EVT_CTL_TYPE_EDGE_0_1); + + intel_de_write(display, MTL_PIPEDMC_EVT_CTL_4(pipe), + val); +} + static bool is_dmc_evt_ctl_reg(struct intel_display *display, enum intel_dmc_id dmc_id, i915_reg_t reg) { diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 236312fb791c3..bd1c459b00757 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -20,6 +20,8 @@ void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe); void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe); void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe, bool block); +void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display, + enum pipe pipe, bool enable); void intel_dmc_fini(struct intel_display *display); void intel_dmc_suspend(struct intel_display *display); void intel_dmc_resume(struct intel_display *display);