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
This commit is contained in:
Jouni Högander
2025-04-14 13:05:05 +03:00
parent 0c427ac78a
commit 2978eb1841
2 changed files with 33 additions and 0 deletions

View File

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

View File

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