summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJouni Högander <jouni.hogander@intel.com>2025-04-14 13:05:05 +0300
committerJouni Högander <jouni.hogander@intel.com>2025-04-23 12:16:31 +0300
commit2978eb1841cd635f17e568ad74ffa32f68fcd54d (patch)
tree929c6bf954f6c767c84654b34d75a616ed53db02
parent0c427ac78a1d9ef4cff5ec6df94aaa6337086a24 (diff)
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 <jouni.hogander@intel.com> Reviewed-by: Mika Kahola <mika.kahola@intel.com> Link: https://lore.kernel.org/r/20250414100508.1208774-11-jouni.hogander@intel.com
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c31
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h2
2 files changed, 33 insertions, 0 deletions
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);