* [PATCH v2 00/11] Underrun on idle PSR workaround
@ 2025-03-17 8:18 Jouni Högander
2025-03-17 8:18 ` [PATCH v2 01/11] drm/i915/display: Add new interface for getting dc_state Jouni Högander
` (13 more replies)
0 siblings, 14 replies; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:18 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
This patchset is implementing workaround for underrun on idle PSR HW
bug (Wa_16025596647).
It is adding notification mechanisms towards PSR for pipe
enable/disable, vblank enable/disable and enabling disabling
DC5/DC6. These notifications are used to apply/remove the workaround.
Current mechanism to block DC states while vblank is enabled on Panel
Replay capable system is extended to work for this new workaround as
well.
v2:
- remove patch mistakenly added to the set
- add missing patch
Jouni Högander (11):
drm/i915/display: Add new interface for getting dc_state
drm/i915/psr: Store enabled non-psr pipes into intel_crtc_state
drm/i915/dmc: Add PIPEDMC_EVT_CTL register definition
drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions
drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR
drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable
drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable
drm/i915/psr: Add interface to notify PSR of vblank enable/disable
drm/i915/psr: Apply underrun on PSR idle workaround
drm/i915/display: Rename intel_psr_needs_block_dc_vblank
drm/i915/display: Rename vblank DC workaround functions and variables
drivers/gpu/drm/i915/display/intel_crtc.c | 6 +-
drivers/gpu/drm/i915/display/intel_display.c | 4 +
.../gpu/drm/i915/display/intel_display_core.h | 6 +-
.../drm/i915/display/intel_display_driver.c | 3 +
.../gpu/drm/i915/display/intel_display_irq.c | 27 +-
.../drm/i915/display/intel_display_power.c | 29 ++
.../drm/i915/display/intel_display_power.h | 1 +
.../i915/display/intel_display_power_well.c | 4 +
.../drm/i915/display/intel_display_types.h | 5 +-
drivers/gpu/drm/i915/display/intel_dmc_regs.h | 14 +
drivers/gpu/drm/i915/display/intel_psr.c | 273 +++++++++++++++++-
drivers/gpu/drm/i915/display/intel_psr.h | 8 +-
12 files changed, 350 insertions(+), 30 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 01/11] drm/i915/display: Add new interface for getting dc_state
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
@ 2025-03-17 8:18 ` Jouni Högander
2025-03-17 8:18 ` [PATCH v2 02/11] drm/i915/psr: Store enabled non-psr pipes into intel_crtc_state Jouni Högander
` (12 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:18 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
To implement workaround for underrun on idle PSR HW issue (Wa_16025596647)
we need to have current configured DC state available. Add new interface
for this purpose.
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
.../drm/i915/display/intel_display_power.c | 29 +++++++++++++++++++
.../drm/i915/display/intel_display_power.h | 1 +
2 files changed, 30 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index f7171e6932dc3..6dfe85a5528fc 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -322,6 +322,35 @@ void intel_display_power_set_target_dc_state(struct intel_display *display,
mutex_unlock(&power_domains->lock);
}
+/**
+ * intel_display_power_get_current_dc_state - Set target dc state.
+ * @display: display device
+ *
+ * This function set the "DC off" power well target_dc_state,
+ * based upon this target_dc_stste, "DC off" power well will
+ * enable desired DC state.
+ */
+u32 intel_display_power_get_current_dc_state(struct intel_display *display)
+{
+ struct i915_power_well *power_well;
+ struct i915_power_domains *power_domains = &display->power.domains;
+ u32 current_dc_state = DC_STATE_DISABLE;
+
+ mutex_lock(&power_domains->lock);
+ power_well = lookup_power_well(display, SKL_DISP_DC_OFF);
+
+ if (drm_WARN_ON(display->drm, !power_well))
+ goto unlock;
+
+ current_dc_state = intel_power_well_is_enabled(display, power_well) ?
+ DC_STATE_DISABLE : power_domains->target_dc_state;
+
+unlock:
+ mutex_unlock(&power_domains->lock);
+
+ return current_dc_state;
+}
+
static void __async_put_domains_mask(struct i915_power_domains *power_domains,
struct intel_power_domain_mask *mask)
{
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index 1b53d67f9b60d..f8813b0e16dfb 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -183,6 +183,7 @@ void intel_display_power_suspend(struct intel_display *display);
void intel_display_power_resume(struct intel_display *display);
void intel_display_power_set_target_dc_state(struct intel_display *display,
u32 state);
+u32 intel_display_power_get_current_dc_state(struct intel_display *display);
bool intel_display_power_is_enabled(struct intel_display *display,
enum intel_display_power_domain domain);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 02/11] drm/i915/psr: Store enabled non-psr pipes into intel_crtc_state
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
2025-03-17 8:18 ` [PATCH v2 01/11] drm/i915/display: Add new interface for getting dc_state Jouni Högander
@ 2025-03-17 8:18 ` Jouni Högander
2025-03-17 8:18 ` [PATCH v2 03/11] drm/i915/dmc: Add PIPEDMC_EVT_CTL register definition Jouni Högander
` (11 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:18 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
To implement workaround for underrun on idle PSR HW issue (Wa_16025596647)
we need to know enabled. Figure out which non-PSR pipes we will have active
and store it into intel_crtc_state->active_non_psr_pipes. This is currently
assuming only one eDP on a time. I.e. possible secondary eDP with PSR
capable panel is not considered.
Bspec: 74151
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
.../drm/i915/display/intel_display_types.h | 3 +++
drivers/gpu/drm/i915/display/intel_psr.c | 23 +++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 99a6fd2900b9c..3d203a2003f10 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1114,6 +1114,7 @@ struct intel_crtc_state {
bool wm_level_disabled;
u32 dc3co_exitline;
u16 su_y_granularity;
+ u8 active_non_psr_pipes;
/*
* Frequency the dpll for the port should run at. Differs from the
@@ -1650,6 +1651,8 @@ struct intel_psr {
u8 entry_setup_frames;
bool link_ok;
+
+ u8 active_non_psr_pipes;
};
struct intel_dp {
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 4e938bad808cc..1415e1e7aaf2c 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1658,6 +1658,9 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
{
struct intel_display *display = to_intel_display(intel_dp);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+ struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
+ struct intel_crtc *crtc;
+ u8 active_pipes = 0;
if (!psr_global_enabled(intel_dp)) {
drm_dbg_kms(display->drm, "PSR disabled by flag\n");
@@ -1711,6 +1714,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
drm_dbg_kms(display->drm,
"PSR disabled to workaround PSR FSM hang issue\n");
}
+
+ /* Rest is for Wa_16025596647 */
+ if (DISPLAY_VER(display) != 20 &&
+ !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
+ return;
+
+ /* Not needed by Panel Replay */
+ if (crtc_state->has_panel_replay)
+ return;
+
+ /* We ignore possible secondary PSR/Panel Replay capable eDP */
+ for_each_intel_crtc(display->drm, crtc)
+ active_pipes |= crtc->active ? BIT(crtc->pipe) : 0;
+
+ active_pipes = intel_calc_active_pipes(state, active_pipes);
+
+ crtc_state->active_non_psr_pipes = active_pipes &
+ ~BIT(to_intel_crtc(crtc_state->uapi.crtc)->pipe);
}
void intel_psr_get_config(struct intel_encoder *encoder,
@@ -1995,6 +2016,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
intel_dp->psr.req_psr2_sdp_prior_scanline =
crtc_state->req_psr2_sdp_prior_scanline;
+ intel_dp->psr.active_non_psr_pipes = crtc_state->active_non_psr_pipes;
if (!psr_interrupt_error_check(intel_dp))
return;
@@ -2170,6 +2192,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
intel_dp->psr.psr2_sel_fetch_enabled = false;
intel_dp->psr.su_region_et_enabled = false;
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
+ intel_dp->psr.active_non_psr_pipes = 0;
}
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 03/11] drm/i915/dmc: Add PIPEDMC_EVT_CTL register definition
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
2025-03-17 8:18 ` [PATCH v2 01/11] drm/i915/display: Add new interface for getting dc_state Jouni Högander
2025-03-17 8:18 ` [PATCH v2 02/11] drm/i915/psr: Store enabled non-psr pipes into intel_crtc_state Jouni Högander
@ 2025-03-17 8:18 ` Jouni Högander
2025-03-17 8:18 ` [PATCH v2 04/11] drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions Jouni Högander
` (10 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:18 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
To implement workaround for underrun on idle PSR HW issue (Wa_16025596647)
we need PIPEDMC_EVT_CTL_4 register. Add PIPEDMC_EVT_CTL_4 register
definitions.
Bspec: 67576
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_dmc_regs.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
index 1bf446f96a10c..2f1e3cb1a2477 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
@@ -21,6 +21,12 @@
#define MTL_PIPEDMC_CONTROL _MMIO(0x45250)
#define PIPEDMC_ENABLE_MTL(pipe) REG_BIT(((pipe) - PIPE_A) * 4)
+#define _MTL_PIPEDMC_EVT_CTL_4_A 0x5f044
+#define _MTL_PIPEDMC_EVT_CTL_4_B 0x5f444
+#define MTL_PIPEDMC_EVT_CTL_4(pipe) _MMIO_PIPE(pipe, \
+ _MTL_PIPEDMC_EVT_CTL_4_A, \
+ _MTL_PIPEDMC_EVT_CTL_4_B)
+
#define _ADLP_PIPEDMC_REG_MMIO_BASE_A 0x5f000
#define _TGL_PIPEDMC_REG_MMIO_BASE_A 0x92000
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 04/11] drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (2 preceding siblings ...)
2025-03-17 8:18 ` [PATCH v2 03/11] drm/i915/dmc: Add PIPEDMC_EVT_CTL register definition Jouni Högander
@ 2025-03-17 8:18 ` Jouni Högander
2025-04-07 11:50 ` Kahola, Mika
2025-03-17 8:18 ` [PATCH v2 05/11] drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR Jouni Högander
` (9 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:18 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
We need PIPEDMC_BLOCK_PKGC_SW definitions to implement workaround for
underrun on idle PSR HW issue (Wa_16025596647). Add PIPEDMC_BLOCK_PKGC_SW
register definitions.
Bspec: 71265
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_dmc_regs.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
index 2f1e3cb1a2477..e16ea3f16ed88 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
@@ -27,6 +27,14 @@
_MTL_PIPEDMC_EVT_CTL_4_A, \
_MTL_PIPEDMC_EVT_CTL_4_B)
+#define PIPEDMC_BLOCK_PKGC_SW_A 0x5f1d0
+#define PIPEDMC_BLOCK_PKGC_SW_B 0x5F5d0
+#define PIPEDMC_BLOCK_PKGC_SW(pipe) _MMIO_PIPE(pipe, \
+ PIPEDMC_BLOCK_PKGC_SW_A, \
+ PIPEDMC_BLOCK_PKGC_SW_B)
+#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS BIT(31)
+#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_UNTIL_NEXT_FRAMESTART BIT(15)
+
#define _ADLP_PIPEDMC_REG_MMIO_BASE_A 0x5f000
#define _TGL_PIPEDMC_REG_MMIO_BASE_A 0x92000
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 05/11] drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (3 preceding siblings ...)
2025-03-17 8:18 ` [PATCH v2 04/11] drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions Jouni Högander
@ 2025-03-17 8:18 ` Jouni Högander
2025-03-21 12:39 ` Jani Nikula
2025-03-17 8:19 ` [PATCH v2 06/11] drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable Jouni Högander
` (8 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:18 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR as described in workaround
for underrun on idle PSR HW issue (Wa_16025596647).
Bspec: 74151
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_psr.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 1415e1e7aaf2c..a3946eef44f0d 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -37,6 +37,7 @@
#include "intel_de.h"
#include "intel_display_irq.h"
#include "intel_display_types.h"
+#include "intel_dmc_regs.h"
#include "intel_dp.h"
#include "intel_dp_aux.h"
#include "intel_frontbuffer.h"
@@ -1961,6 +1962,13 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
intel_de_rmw(display, CLKGATE_DIS_MISC, 0,
CLKGATE_DIS_MISC_DMASC_GATING_DIS);
}
+
+ /* Wa_16025596647 */
+ if ((DISPLAY_VER(display) == 20 ||
+ IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
+ !intel_dp->psr.panel_replay_enabled)
+ intel_de_rmw(display, PIPEDMC_BLOCK_PKGC_SW(intel_dp->psr.pipe), 0,
+ PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS);
}
static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
@@ -2186,6 +2194,13 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
DP_RECEIVER_ALPM_CONFIG, 0);
}
+ /* Wa_16025596647 */
+ if ((DISPLAY_VER(display) == 20 ||
+ IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
+ !intel_dp->psr.panel_replay_enabled)
+ intel_de_rmw(display, PIPEDMC_BLOCK_PKGC_SW(intel_dp->psr.pipe),
+ PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS, 0);
+
intel_dp->psr.enabled = false;
intel_dp->psr.panel_replay_enabled = false;
intel_dp->psr.sel_update_enabled = false;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 06/11] drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (4 preceding siblings ...)
2025-03-17 8:18 ` [PATCH v2 05/11] drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR Jouni Högander
@ 2025-03-17 8:19 ` Jouni Högander
2025-04-08 10:44 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 07/11] drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable Jouni Högander
` (7 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:19 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
We need to apply/remove workaround for underrun on idle PSR HW issue
(Wa_16025596647) when new pipe is enabled or pipe is getting disabled. This
patch implements mechanism to notify PSR about pipe enable/disable and
applies/removes the workaround using this notification.
Bspec: 74151
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_psr.c | 106 +++++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_psr.h | 2 +
2 files changed, 108 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index a3946eef44f0d..4b62d5832cbfa 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -26,6 +26,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_debugfs.h>
+#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -3664,6 +3665,111 @@ void intel_psr_unlock(const struct intel_crtc_state *crtc_state)
}
}
+/* Wa_16025596647 */
+static void psr1_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp,
+ bool dc5_dc6_blocked)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ u32 val;
+
+ if (dc5_dc6_blocked)
+ 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(intel_dp->psr.pipe),
+ val);
+}
+
+/* Wa_16025596647 */
+static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ u32 current_dc_state = intel_display_power_get_current_dc_state(display);
+ struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe];
+
+ return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
+ current_dc_state != DC_STATE_EN_UPTO_DC6) ||
+ intel_dp->psr.active_non_psr_pipes ||
+ READ_ONCE(vblank->enabled);
+}
+
+/* Wa_16025596647 */
+static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp)
+{
+ bool dc5_dc6_blocked;
+
+ if (!intel_dp->psr.active)
+ return;
+
+ dc5_dc6_blocked = is_dc5_dc6_blocked(intel_dp);
+
+ if (intel_dp->psr.sel_update_enabled)
+ psr2_program_idle_frames(intel_dp, dc5_dc6_blocked ? 0 :
+ psr_compute_idle_frames(intel_dp));
+ else
+ psr1_apply_underrun_on_idle_wa_locked(intel_dp, dc5_dc6_blocked);
+}
+
+/**
+ * intel_psr_notify_pipe_change - Notify PSR about enable/disable of a pipe
+ * @state: intel atomic state
+ * @crtc: intel crtc
+ * @enable: enable/disable
+ *
+ * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply
+ * remove the workaround when pipe is getting enabled/disabled
+ */
+void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
+ struct intel_crtc *crtc, bool enable)
+{
+ struct intel_display *display = to_intel_display(state);
+ struct intel_encoder *encoder;
+
+ if (DISPLAY_VER(display) != 20 &&
+ !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
+ return;
+
+ for_each_intel_encoder_with_psr(display->drm, encoder) {
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ u8 active_non_psr_pipes;
+
+ mutex_lock(&intel_dp->psr.lock);
+
+ if (!intel_dp->psr.enabled || intel_dp->psr.panel_replay_enabled)
+ goto unlock;
+
+ active_non_psr_pipes = intel_dp->psr.active_non_psr_pipes;
+
+ if (enable)
+ active_non_psr_pipes |= BIT(crtc->pipe);
+ else
+ active_non_psr_pipes &= ~BIT(crtc->pipe);
+
+ if (active_non_psr_pipes == intel_dp->psr.active_non_psr_pipes)
+ goto unlock;
+
+ if ((enable && intel_dp->psr.active_non_psr_pipes) ||
+ (!enable && !intel_dp->psr.active_non_psr_pipes)) {
+ intel_dp->psr.active_non_psr_pipes = active_non_psr_pipes;
+ goto unlock;
+ }
+
+ intel_dp->psr.active_non_psr_pipes = active_non_psr_pipes;
+
+ intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
+unlock:
+ mutex_unlock(&intel_dp->psr.lock);
+ }
+}
+
static void
psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
{
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index a43a374cff550..273e70a50915c 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -60,6 +60,8 @@ void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb,
void intel_psr_pause(struct intel_dp *intel_dp);
void intel_psr_resume(struct intel_dp *intel_dp);
bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
+void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
+ struct intel_crtc *crtc, bool enable);
bool intel_psr_link_ok(struct intel_dp *intel_dp);
void intel_psr_lock(const struct intel_crtc_state *crtc_state);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 07/11] drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (5 preceding siblings ...)
2025-03-17 8:19 ` [PATCH v2 06/11] drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable Jouni Högander
@ 2025-03-17 8:19 ` Jouni Högander
2025-04-08 11:07 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 08/11] drm/i915/psr: Add interface to notify PSR of vblank enable/disable Jouni Högander
` (6 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:19 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
We need to apply/remove workaround for underrun on idle PSR HW issue
(Wa_16025596647) when DC5/6 is enabled/disabled. This patch implements
mechanism to notify PSR about DC5/6 enable/disable and applies/removes the
workaround using this notification.
Bspec: 74115
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
.../gpu/drm/i915/display/intel_display_core.h | 2 +
drivers/gpu/drm/i915/display/intel_psr.c | 50 +++++++++++++++++++
drivers/gpu/drm/i915/display/intel_psr.h | 2 +
3 files changed, 54 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
index 3673275f9061a..7ca1e7d710133 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -575,6 +575,8 @@ struct intel_display {
struct intel_vbt_data vbt;
struct intel_dmc_wl wl;
struct intel_wm wm;
+
+ struct work_struct psr_dc5_dc6_wa_work;
};
#endif /* __INTEL_DISPLAY_CORE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 4b62d5832cbfa..baf6a7110a555 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -3718,6 +3718,56 @@ static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp
psr1_apply_underrun_on_idle_wa_locked(intel_dp, dc5_dc6_blocked);
}
+static void psr_dc5_dc6_wa_work(struct work_struct *work)
+{
+ struct intel_display *display = container_of(work, typeof(*display),
+ psr_dc5_dc6_wa_work);
+ struct intel_encoder *encoder;
+
+ for_each_intel_encoder_with_psr(display->drm, encoder) {
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ mutex_lock(&intel_dp->psr.lock);
+
+ if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled)
+ intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
+
+ mutex_unlock(&intel_dp->psr.lock);
+ }
+}
+
+/**
+ * intel_psr_notify_dc5_dc6 - Notify PSR about enable/disable dc5/dc6
+ * @display: intel atomic state
+ *
+ * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to schedule
+ * psr_dc5_dc6_wa_work used for applying/removing the workaround.
+ */
+void intel_psr_notify_dc5_dc6(struct intel_display *display)
+{
+ if (DISPLAY_VER(display) != 20 &&
+ !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
+ return;
+
+ schedule_work(&display->psr_dc5_dc6_wa_work);
+}
+
+/**
+ * intel_psr_dc5_dc6_wa_init - Init work for underrun on idle PSR HW bug wa
+ * @display: intel atomic state
+ *
+ * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to init
+ * psr_dc5_dc6_wa_work used for applying the workaround.
+ */
+void intel_psr_dc5_dc6_wa_init(struct intel_display *display)
+{
+ if (DISPLAY_VER(display) != 20 &&
+ !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
+ return;
+
+ INIT_WORK(&display->psr_dc5_dc6_wa_work, psr_dc5_dc6_wa_work);
+}
+
/**
* intel_psr_notify_pipe_change - Notify PSR about enable/disable of a pipe
* @state: intel atomic state
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index 273e70a50915c..bfe368239bc27 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -62,6 +62,8 @@ void intel_psr_resume(struct intel_dp *intel_dp);
bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
struct intel_crtc *crtc, bool enable);
+void intel_psr_notify_dc5_dc6(struct intel_display *display);
+void intel_psr_dc5_dc6_wa_init(struct intel_display *display);
bool intel_psr_link_ok(struct intel_dp *intel_dp);
void intel_psr_lock(const struct intel_crtc_state *crtc_state);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 08/11] drm/i915/psr: Add interface to notify PSR of vblank enable/disable
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (6 preceding siblings ...)
2025-03-17 8:19 ` [PATCH v2 07/11] drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable Jouni Högander
@ 2025-03-17 8:19 ` Jouni Högander
2025-04-08 12:10 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 09/11] drm/i915/psr: Apply underrun on PSR idle workaround Jouni Högander
` (5 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:19 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
To implement Wa_16025596647 we need to get notification of vblank interrupt
enable/disable. Add new interface to PSR code for this notification.
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_psr.c | 40 ++++++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_psr.h | 2 ++
2 files changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index baf6a7110a555..afb9faed7784b 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -3820,6 +3820,46 @@ void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
}
}
+/**
+ * intel_psr_notify_vblank_enable_disable - Notify PSR about enable/disable of vblank
+ * @display: intel display struct
+ * @enable: enable/disable
+ *
+ * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply
+ * remove the workaround when vblank is getting enabled/disabled
+ */
+void intel_psr_notify_vblank_enable_disable(struct intel_display *display,
+ bool enable)
+{
+ struct intel_encoder *encoder;
+
+ for_each_intel_encoder_with_psr(display->drm, encoder) {
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ mutex_lock(&intel_dp->psr.lock);
+ if (intel_dp->psr.panel_replay_enabled) {
+ mutex_unlock(&intel_dp->psr.lock);
+ break;
+ }
+
+ if (intel_dp->psr.enabled)
+ intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
+
+ mutex_unlock(&intel_dp->psr.lock);
+ return;
+ }
+
+ /*
+ * NOTE: intel_display_power_set_target_dc_state is used
+ * only by PSR * code for DC3CO handling. DC3CO target
+ * state is currently disabled in * PSR code. If DC3CO
+ * is taken into use we need take that into account here
+ * as well.
+ */
+ intel_display_power_set_target_dc_state(display, enable ? DC_STATE_DISABLE :
+ DC_STATE_EN_UPTO_DC6);
+}
+
static void
psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
{
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index bfe368239bc27..a914b7ee3756a 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -64,6 +64,8 @@ void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
struct intel_crtc *crtc, bool enable);
void intel_psr_notify_dc5_dc6(struct intel_display *display);
void intel_psr_dc5_dc6_wa_init(struct intel_display *display);
+void intel_psr_notify_vblank_enable_disable(struct intel_display *display,
+ bool enable);
bool intel_psr_link_ok(struct intel_dp *intel_dp);
void intel_psr_lock(const struct intel_crtc_state *crtc_state);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 09/11] drm/i915/psr: Apply underrun on PSR idle workaround
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (7 preceding siblings ...)
2025-03-17 8:19 ` [PATCH v2 08/11] drm/i915/psr: Add interface to notify PSR of vblank enable/disable Jouni Högander
@ 2025-03-17 8:19 ` Jouni Högander
2025-04-08 12:27 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 10/11] drm/i915/display: Rename intel_psr_needs_block_dc_vblank Jouni Högander
` (4 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:19 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
This patch is applying workaround for underrun on idle PSR HW issue
(Wa_16025596647) when PSR is getting enabled. It uses vblank enable/disable
status, DC5/6 enabled disabled and enabled pipes count information made
available.
This patch is also adding calls to dc5/dc6, vblank enable/disable and pipe
enable/disable notification functions as needed.
intel_psr_needs_block_dc_vblank is modified to get vblank enable/disable
notification on PSR capable system.
Bspec: 74151
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_display.c | 4 +
.../drm/i915/display/intel_display_driver.c | 3 +
.../gpu/drm/i915/display/intel_display_irq.c | 9 +-
.../i915/display/intel_display_power_well.c | 4 +
drivers/gpu/drm/i915/display/intel_psr.c | 103 +++++++++++-------
5 files changed, 76 insertions(+), 47 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 3afb85fe8536d..834d023d0c626 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6648,6 +6648,8 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
intel_crtc_update_active_timings(pipe_crtc_state, false);
}
+ intel_psr_notify_pipe_change(state, crtc, true);
+
display->funcs.display->crtc_enable(state, crtc);
/* vblanks work again, re-enable pipe CRC. */
@@ -6767,6 +6769,8 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
intel_crtc_joined_pipe_mask(old_crtc_state))
intel_crtc_disable_pipe_crc(pipe_crtc);
+ intel_psr_notify_pipe_change(state, crtc, false);
+
display->funcs.display->crtc_disable(state, crtc);
for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc,
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c
index 31740a677dd80..b4c989bbac93a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -54,6 +54,7 @@
#include "intel_plane_initial.h"
#include "intel_pmdemand.h"
#include "intel_pps.h"
+#include "intel_psr.h"
#include "intel_quirks.h"
#include "intel_vga.h"
#include "intel_wm.h"
@@ -226,6 +227,8 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
if (ret)
goto cleanup_bios;
+ intel_psr_dc5_dc6_wa_init(display);
+
/* FIXME: completely on the wrong abstraction layer */
ret = intel_power_domains_init(display);
if (ret < 0)
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index aa23bb8178053..62fbdcbb4a123 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -1728,14 +1728,7 @@ static void intel_display_vblank_dc_work(struct work_struct *work)
container_of(work, typeof(*display), irq.vblank_dc_work);
int vblank_wa_num_pipes = READ_ONCE(display->irq.vblank_wa_num_pipes);
- /*
- * NOTE: intel_display_power_set_target_dc_state is used only by PSR
- * code for DC3CO handling. DC3CO target state is currently disabled in
- * PSR code. If DC3CO is taken into use we need take that into account
- * here as well.
- */
- intel_display_power_set_target_dc_state(display, vblank_wa_num_pipes ? DC_STATE_DISABLE :
- DC_STATE_EN_UPTO_DC6);
+ intel_psr_notify_vblank_enable_disable(display, vblank_wa_num_pipes);
}
int bdw_enable_vblank(struct drm_crtc *_crtc)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
index 8ec87ffd87d26..510f97341893b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -24,6 +24,7 @@
#include "intel_hotplug.h"
#include "intel_pcode.h"
#include "intel_pps.h"
+#include "intel_psr.h"
#include "intel_tc.h"
#include "intel_vga.h"
#include "skl_watermark.h"
@@ -762,6 +763,9 @@ void gen9_set_dc_state(struct intel_display *display, u32 state)
state & ~power_domains->allowed_dc_mask))
state &= power_domains->allowed_dc_mask;
+ if (!power_domains->initializing)
+ intel_psr_notify_dc5_dc6(display);
+
val = intel_de_read(display, DC_STATE_EN);
mask = gen9_dc_mask(display);
drm_dbg_kms(display->drm, "Setting DC state from %02x to %02x\n",
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index afb9faed7784b..d2a28a83e4f20 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -908,6 +908,41 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp)
return idle_frames;
}
+/* Wa_16025596647 */
+static void psr1_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp,
+ bool dc5_dc6_blocked)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ u32 val;
+
+ if (dc5_dc6_blocked)
+ 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(intel_dp->psr.pipe),
+ val);
+}
+
+static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ u32 current_dc_state = intel_display_power_get_current_dc_state(display);
+ struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe];
+
+ return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
+ current_dc_state != DC_STATE_EN_UPTO_DC6) ||
+ intel_dp->psr.active_non_psr_pipes ||
+ READ_ONCE(vblank->enabled);
+}
+
static void hsw_activate_psr1(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
@@ -937,6 +972,12 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
intel_de_rmw(display, psr_ctl_reg(display, cpu_transcoder),
~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
+
+ /* Wa_16025596647 */
+ if ((DISPLAY_VER(display) == 20 ||
+ IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
+ is_dc5_dc6_blocked(intel_dp))
+ psr1_apply_underrun_on_idle_wa_locked(intel_dp, true);
}
static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
@@ -1019,8 +1060,16 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
u32 val = EDP_PSR2_ENABLE;
u32 psr_val = 0;
+ u8 idle_frames;
- val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
+ /* Wa_16025596647 */
+ if ((DISPLAY_VER(display) == 20 ||
+ IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
+ is_dc5_dc6_blocked(intel_dp))
+ idle_frames = 0;
+ else
+ idle_frames = psr_compute_idle_frames(intel_dp);
+ val |= EDP_PSR2_IDLE_FRAMES(idle_frames);
if (DISPLAY_VER(display) < 14 && !IS_ALDERLAKE_P(dev_priv))
val |= EDP_SU_TRACK_ENABLE;
@@ -2101,6 +2150,10 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
drm_WARN_ON(display->drm, !(val & EDP_PSR2_ENABLE));
} else {
+ if (DISPLAY_VER(display) == 20 ||
+ IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
+ psr1_apply_underrun_on_idle_wa_locked(intel_dp, false);
+
val = intel_de_rmw(display,
psr_ctl_reg(display, cpu_transcoder),
EDP_PSR_ENABLE, 0);
@@ -2312,6 +2365,7 @@ void intel_psr_resume(struct intel_dp *intel_dp)
bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_display *display = to_intel_display(crtc_state);
struct intel_encoder *encoder;
for_each_encoder_on_crtc(crtc->base.dev, &crtc->base, encoder) {
@@ -2322,8 +2376,15 @@ bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
intel_dp = enc_to_intel_dp(encoder);
- if (intel_dp_is_edp(intel_dp) &&
- CAN_PANEL_REPLAY(intel_dp))
+ if (!intel_dp_is_edp(intel_dp))
+ continue;
+
+ if (CAN_PANEL_REPLAY(intel_dp))
+ return true;
+
+ if ((DISPLAY_VER(display) == 20 ||
+ IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
+ CAN_PSR(intel_dp))
return true;
}
@@ -3665,42 +3726,6 @@ void intel_psr_unlock(const struct intel_crtc_state *crtc_state)
}
}
-/* Wa_16025596647 */
-static void psr1_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp,
- bool dc5_dc6_blocked)
-{
- struct intel_display *display = to_intel_display(intel_dp);
- u32 val;
-
- if (dc5_dc6_blocked)
- 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(intel_dp->psr.pipe),
- val);
-}
-
-/* Wa_16025596647 */
-static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp)
-{
- struct intel_display *display = to_intel_display(intel_dp);
- u32 current_dc_state = intel_display_power_get_current_dc_state(display);
- struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe];
-
- return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
- current_dc_state != DC_STATE_EN_UPTO_DC6) ||
- intel_dp->psr.active_non_psr_pipes ||
- READ_ONCE(vblank->enabled);
-}
-
/* Wa_16025596647 */
static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 10/11] drm/i915/display: Rename intel_psr_needs_block_dc_vblank
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (8 preceding siblings ...)
2025-03-17 8:19 ` [PATCH v2 09/11] drm/i915/psr: Apply underrun on PSR idle workaround Jouni Högander
@ 2025-03-17 8:19 ` Jouni Högander
2025-04-08 12:28 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 11/11] drm/i915/display: Rename vblank DC workaround functions and variables Jouni Högander
` (3 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:19 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
Scope of intel_psr_needs_block_dc_vblank has changed now. Rename it as
intel_psr_needs_vblank_notification. Also rename
intel_crtc::block_dc_for_vblank as intel_crtc:vblank_psr_notify
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_crtc.c | 4 ++--
drivers/gpu/drm/i915/display/intel_display_irq.c | 4 ++--
drivers/gpu/drm/i915/display/intel_display_types.h | 2 +-
drivers/gpu/drm/i915/display/intel_psr.c | 8 +++++---
drivers/gpu/drm/i915/display/intel_psr.h | 2 +-
5 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 5b2603ef2ff75..bdf30ab963967 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -124,7 +124,7 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- crtc->block_dc_for_vblank = intel_psr_needs_block_dc_vblank(crtc_state);
+ crtc->vblank_psr_notify = intel_psr_needs_vblank_notification(crtc_state);
assert_vblank_disabled(&crtc->base);
drm_crtc_set_max_vblank_count(&crtc->base,
@@ -154,7 +154,7 @@ void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
drm_crtc_vblank_off(&crtc->base);
assert_vblank_disabled(&crtc->base);
- crtc->block_dc_for_vblank = false;
+ crtc->vblank_psr_notify = false;
flush_work(&display->irq.vblank_dc_work);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index 62fbdcbb4a123..833f8227da803 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -1742,7 +1742,7 @@ int bdw_enable_vblank(struct drm_crtc *_crtc)
if (gen11_dsi_configure_te(crtc, true))
return 0;
- if (crtc->block_dc_for_vblank && display->irq.vblank_wa_num_pipes++ == 0)
+ if (crtc->vblank_psr_notify && display->irq.vblank_wa_num_pipes++ == 0)
schedule_work(&display->irq.vblank_dc_work);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
@@ -1773,7 +1773,7 @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
- if (crtc->block_dc_for_vblank && --display->irq.vblank_wa_num_pipes == 0)
+ if (crtc->vblank_psr_notify && --display->irq.vblank_wa_num_pipes == 0)
schedule_work(&display->irq.vblank_dc_work);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 3d203a2003f10..4f3fdfacbc1b1 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1440,7 +1440,7 @@ struct intel_crtc {
struct intel_pipe_crc pipe_crc;
#endif
- bool block_dc_for_vblank;
+ bool vblank_psr_notify;
};
struct intel_plane_error {
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index d2a28a83e4f20..228996f1f26d2 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2354,15 +2354,17 @@ void intel_psr_resume(struct intel_dp *intel_dp)
}
/**
- * intel_psr_needs_block_dc_vblank - Check if block dc entry is needed
+ * intel_psr_needs_vblank_notification - Check if PSR need vblank enable/disable
+ * notification.
* @crtc_state: CRTC status
*
* We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
* prevent it in case of Panel Replay. Panel Replay switches main link off on
* DC entry. This means vblank interrupts are not fired and is a problem if
- * user-space is polling for vblank events.
+ * user-space is polling for vblank events. Also Wa_16025596647 needs
+ * information when vblank is enabled/disabled.
*/
-bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
+bool intel_psr_needs_vblank_notification(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_display *display = to_intel_display(crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index a914b7ee3756a..c61384bb7382a 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -59,7 +59,7 @@ void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state);
void intel_psr_pause(struct intel_dp *intel_dp);
void intel_psr_resume(struct intel_dp *intel_dp);
-bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
+bool intel_psr_needs_vblank_notification(const struct intel_crtc_state *crtc_state);
void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
struct intel_crtc *crtc, bool enable);
void intel_psr_notify_dc5_dc6(struct intel_display *display);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 11/11] drm/i915/display: Rename vblank DC workaround functions and variables
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (9 preceding siblings ...)
2025-03-17 8:19 ` [PATCH v2 10/11] drm/i915/display: Rename intel_psr_needs_block_dc_vblank Jouni Högander
@ 2025-03-17 8:19 ` Jouni Högander
2025-04-08 12:28 ` Kahola, Mika
2025-03-17 8:47 ` ✗ Fi.CI.CHECKPATCH: warning for Underrun on idle PSR workaround (rev3) Patchwork
` (2 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Jouni Högander @ 2025-03-17 8:19 UTC (permalink / raw)
To: intel-gfx, intel-xe; +Cc: Jouni Högander
We have extended using vblank DC workaround mechanism for
Wa_16025596647. Rename related functions and variables:
vblank_wa_num_pipes -> vblank_enable_count
vblank_dc_work -> vblank_notify_work
intel_display_vblank_dc_work -> intel_display_vblank_notify_work
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
drivers/gpu/drm/i915/display/intel_crtc.c | 2 +-
.../gpu/drm/i915/display/intel_display_core.h | 4 ++--
.../gpu/drm/i915/display/intel_display_irq.c | 20 +++++++++----------
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index bdf30ab963967..537859630363b 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -156,7 +156,7 @@ void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
crtc->vblank_psr_notify = false;
- flush_work(&display->irq.vblank_dc_work);
+ flush_work(&display->irq.vblank_notify_work);
}
struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc)
diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
index 7ca1e7d710133..b24586c3753a9 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -466,9 +466,9 @@ struct intel_display {
/* For i915gm/i945gm vblank irq workaround */
u8 vblank_enabled;
- int vblank_wa_num_pipes;
+ int vblank_enable_count;
- struct work_struct vblank_dc_work;
+ struct work_struct vblank_notify_work;
u32 de_irq_mask[I915_MAX_PIPES];
u32 pipestat_irq_mask[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index 833f8227da803..22942edf5ff02 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -1722,13 +1722,13 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
return true;
}
-static void intel_display_vblank_dc_work(struct work_struct *work)
+static void intel_display_vblank_notify_work(struct work_struct *work)
{
struct intel_display *display =
- container_of(work, typeof(*display), irq.vblank_dc_work);
- int vblank_wa_num_pipes = READ_ONCE(display->irq.vblank_wa_num_pipes);
+ container_of(work, typeof(*display), irq.vblank_notify_work);
+ int vblank_enable_count = READ_ONCE(display->irq.vblank_enable_count);
- intel_psr_notify_vblank_enable_disable(display, vblank_wa_num_pipes);
+ intel_psr_notify_vblank_enable_disable(display, vblank_enable_count);
}
int bdw_enable_vblank(struct drm_crtc *_crtc)
@@ -1742,8 +1742,8 @@ int bdw_enable_vblank(struct drm_crtc *_crtc)
if (gen11_dsi_configure_te(crtc, true))
return 0;
- if (crtc->vblank_psr_notify && display->irq.vblank_wa_num_pipes++ == 0)
- schedule_work(&display->irq.vblank_dc_work);
+ if (crtc->vblank_psr_notify && display->irq.vblank_enable_count++ == 0)
+ schedule_work(&display->irq.vblank_notify_work);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
@@ -1773,8 +1773,8 @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
- if (crtc->vblank_psr_notify && --display->irq.vblank_wa_num_pipes == 0)
- schedule_work(&display->irq.vblank_dc_work);
+ if (crtc->vblank_psr_notify && --display->irq.vblank_enable_count == 0)
+ schedule_work(&display->irq.vblank_notify_work);
}
static u32 vlv_dpinvgtt_pipe_fault_mask(enum pipe pipe)
@@ -2345,6 +2345,6 @@ void intel_display_irq_init(struct drm_i915_private *i915)
intel_hotplug_irq_init(i915);
- INIT_WORK(&i915->display.irq.vblank_dc_work,
- intel_display_vblank_dc_work);
+ INIT_WORK(&i915->display.irq.vblank_notify_work,
+ intel_display_vblank_notify_work);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* ✗ Fi.CI.CHECKPATCH: warning for Underrun on idle PSR workaround (rev3)
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (10 preceding siblings ...)
2025-03-17 8:19 ` [PATCH v2 11/11] drm/i915/display: Rename vblank DC workaround functions and variables Jouni Högander
@ 2025-03-17 8:47 ` Patchwork
2025-03-17 8:47 ` ✗ Fi.CI.SPARSE: " Patchwork
2025-03-17 9:07 ` ✓ i915.CI.BAT: success " Patchwork
13 siblings, 0 replies; 23+ messages in thread
From: Patchwork @ 2025-03-17 8:47 UTC (permalink / raw)
To: Jouni Högander; +Cc: intel-gfx
== Series Details ==
Series: Underrun on idle PSR workaround (rev3)
URL : https://patchwork.freedesktop.org/series/145986/
State : warning
== Summary ==
Error: dim checkpatch failed
d17141c733b0 drm/i915/display: Add new interface for getting dc_state
3a103157f0a1 drm/i915/psr: Store enabled non-psr pipes into intel_crtc_state
f051aa5330e7 drm/i915/dmc: Add PIPEDMC_EVT_CTL register definition
fb98bc00ea32 drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions
-:28: WARNING:LONG_LINE: line length of 101 exceeds 100 columns
#28: FILE: drivers/gpu/drm/i915/display/intel_dmc_regs.h:33:
+ PIPEDMC_BLOCK_PKGC_SW_A, \
total: 0 errors, 1 warnings, 0 checks, 14 lines checked
352110d3ed60 drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR
6697cedb1123 drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable
a1ad136d5114 drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable
bc7f48181953 drm/i915/psr: Add interface to notify PSR of vblank enable/disable
6915e6f48cef drm/i915/psr: Apply underrun on PSR idle workaround
02d4c17b4a87 drm/i915/display: Rename intel_psr_needs_block_dc_vblank
78628a1a860d drm/i915/display: Rename vblank DC workaround functions and variables
^ permalink raw reply [flat|nested] 23+ messages in thread
* ✗ Fi.CI.SPARSE: warning for Underrun on idle PSR workaround (rev3)
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (11 preceding siblings ...)
2025-03-17 8:47 ` ✗ Fi.CI.CHECKPATCH: warning for Underrun on idle PSR workaround (rev3) Patchwork
@ 2025-03-17 8:47 ` Patchwork
2025-03-17 9:07 ` ✓ i915.CI.BAT: success " Patchwork
13 siblings, 0 replies; 23+ messages in thread
From: Patchwork @ 2025-03-17 8:47 UTC (permalink / raw)
To: Jouni Högander; +Cc: intel-gfx
== Series Details ==
Series: Underrun on idle PSR workaround (rev3)
URL : https://patchwork.freedesktop.org/series/145986/
State : warning
== Summary ==
Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
^ permalink raw reply [flat|nested] 23+ messages in thread
* ✓ i915.CI.BAT: success for Underrun on idle PSR workaround (rev3)
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
` (12 preceding siblings ...)
2025-03-17 8:47 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2025-03-17 9:07 ` Patchwork
13 siblings, 0 replies; 23+ messages in thread
From: Patchwork @ 2025-03-17 9:07 UTC (permalink / raw)
To: Jouni Högander; +Cc: intel-gfx
[-- Attachment #1: Type: text/plain, Size: 2408 bytes --]
== Series Details ==
Series: Underrun on idle PSR workaround (rev3)
URL : https://patchwork.freedesktop.org/series/145986/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_16293 -> Patchwork_145986v3
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_145986v3/index.html
Participating hosts (43 -> 38)
------------------------------
Missing (5): fi-rkl-11600 bat-arlh-3 fi-snb-2520m fi-elk-e7500 bat-arlh-2
Known issues
------------
Here are the changes found in Patchwork_145986v3 that come from known issues:
### IGT changes ###
#### Possible fixes ####
* igt@i915_selftest@live:
- bat-adlp-9: [INCOMPLETE][1] ([i915#9413]) -> [PASS][2] +1 other test pass
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_16293/bat-adlp-9/igt@i915_selftest@live.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_145986v3/bat-adlp-9/igt@i915_selftest@live.html
* igt@i915_selftest@live@workarounds:
- bat-arls-5: [DMESG-FAIL][3] ([i915#12061]) -> [PASS][4] +1 other test pass
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_16293/bat-arls-5/igt@i915_selftest@live@workarounds.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_145986v3/bat-arls-5/igt@i915_selftest@live@workarounds.html
- bat-arls-6: [DMESG-FAIL][5] ([i915#12061]) -> [PASS][6] +1 other test pass
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_16293/bat-arls-6/igt@i915_selftest@live@workarounds.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_145986v3/bat-arls-6/igt@i915_selftest@live@workarounds.html
[i915#12061]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12061
[i915#9413]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9413
Build changes
-------------
* Linux: CI_DRM_16293 -> Patchwork_145986v3
CI-20190529: 20190529
CI_DRM_16293: a958e31a81b3267201c85b6f171419586afa792c @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_8275: a851348546d61620c263d3292148f67620efa7d0 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
Patchwork_145986v3: a958e31a81b3267201c85b6f171419586afa792c @ git://anongit.freedesktop.org/gfx-ci/linux
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_145986v3/index.html
[-- Attachment #2: Type: text/html, Size: 3113 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 05/11] drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR
2025-03-17 8:18 ` [PATCH v2 05/11] drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR Jouni Högander
@ 2025-03-21 12:39 ` Jani Nikula
0 siblings, 0 replies; 23+ messages in thread
From: Jani Nikula @ 2025-03-21 12:39 UTC (permalink / raw)
To: Jouni Högander, intel-gfx, intel-xe; +Cc: Jouni Högander
On Mon, 17 Mar 2025, Jouni Högander <jouni.hogander@intel.com> wrote:
> Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR as described in workaround
> for underrun on idle PSR HW issue (Wa_16025596647).
>
> Bspec: 74151
>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_psr.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index 1415e1e7aaf2c..a3946eef44f0d 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -37,6 +37,7 @@
> #include "intel_de.h"
> #include "intel_display_irq.h"
> #include "intel_display_types.h"
> +#include "intel_dmc_regs.h"
Mildly annoying to poke at dmc registers from psr code.
BR,
Jani.
> #include "intel_dp.h"
> #include "intel_dp_aux.h"
> #include "intel_frontbuffer.h"
> @@ -1961,6 +1962,13 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
> intel_de_rmw(display, CLKGATE_DIS_MISC, 0,
> CLKGATE_DIS_MISC_DMASC_GATING_DIS);
> }
> +
> + /* Wa_16025596647 */
> + if ((DISPLAY_VER(display) == 20 ||
> + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
> + !intel_dp->psr.panel_replay_enabled)
> + intel_de_rmw(display, PIPEDMC_BLOCK_PKGC_SW(intel_dp->psr.pipe), 0,
> + PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS);
> }
>
> static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
> @@ -2186,6 +2194,13 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
> DP_RECEIVER_ALPM_CONFIG, 0);
> }
>
> + /* Wa_16025596647 */
> + if ((DISPLAY_VER(display) == 20 ||
> + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
> + !intel_dp->psr.panel_replay_enabled)
> + intel_de_rmw(display, PIPEDMC_BLOCK_PKGC_SW(intel_dp->psr.pipe),
> + PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS, 0);
> +
> intel_dp->psr.enabled = false;
> intel_dp->psr.panel_replay_enabled = false;
> intel_dp->psr.sel_update_enabled = false;
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH v2 04/11] drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions
2025-03-17 8:18 ` [PATCH v2 04/11] drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions Jouni Högander
@ 2025-04-07 11:50 ` Kahola, Mika
0 siblings, 0 replies; 23+ messages in thread
From: Kahola, Mika @ 2025-04-07 11:50 UTC (permalink / raw)
To: Hogander, Jouni, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Cc: Hogander, Jouni
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Jouni
> Högander
> Sent: Monday, 17 March 2025 10.19
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 04/11] drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW
> definitions
>
> We need PIPEDMC_BLOCK_PKGC_SW definitions to implement workaround for
> underrun on idle PSR HW issue (Wa_16025596647). Add
> PIPEDMC_BLOCK_PKGC_SW register definitions.
>
> Bspec: 71265
>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_dmc_regs.h | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> index 2f1e3cb1a2477..e16ea3f16ed88 100644
> --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> @@ -27,6 +27,14 @@
>
> _MTL_PIPEDMC_EVT_CTL_4_A, \
>
> _MTL_PIPEDMC_EVT_CTL_4_B)
>
> +#define PIPEDMC_BLOCK_PKGC_SW_A 0x5f1d0
> +#define PIPEDMC_BLOCK_PKGC_SW_B 0x5F5d0
> +#define PIPEDMC_BLOCK_PKGC_SW(pipe)
> _MMIO_PIPE(pipe, \
> +
> PIPEDMC_BLOCK_PKGC_SW_A, \
> +
> PIPEDMC_BLOCK_PKGC_SW_B)
> +#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS
> BIT(31)
> +#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_UNTIL_NEXT_FRAMESTART
> BIT(15)
> +
> #define _ADLP_PIPEDMC_REG_MMIO_BASE_A 0x5f000
> #define _TGL_PIPEDMC_REG_MMIO_BASE_A 0x92000
>
> --
> 2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH v2 06/11] drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable
2025-03-17 8:19 ` [PATCH v2 06/11] drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable Jouni Högander
@ 2025-04-08 10:44 ` Kahola, Mika
0 siblings, 0 replies; 23+ messages in thread
From: Kahola, Mika @ 2025-04-08 10:44 UTC (permalink / raw)
To: Hogander, Jouni, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Cc: Hogander, Jouni
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Jouni
> Högander
> Sent: Monday, 17 March 2025 10.19
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 06/11] drm/i915/psr: Add mechanism to notify PSR of pipe
> enable/disable
>
> We need to apply/remove workaround for underrun on idle PSR HW issue
> (Wa_16025596647) when new pipe is enabled or pipe is getting disabled. This
> patch implements mechanism to notify PSR about pipe enable/disable and
> applies/removes the workaround using this notification.
>
> Bspec: 74151
>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_psr.c | 106 +++++++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_psr.h | 2 +
> 2 files changed, 108 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index a3946eef44f0d..4b62d5832cbfa 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -26,6 +26,7 @@
> #include <drm/drm_atomic_helper.h>
> #include <drm/drm_damage_helper.h>
> #include <drm/drm_debugfs.h>
> +#include <drm/drm_vblank.h>
>
> #include "i915_drv.h"
> #include "i915_reg.h"
> @@ -3664,6 +3665,111 @@ void intel_psr_unlock(const struct intel_crtc_state
> *crtc_state)
> }
> }
>
> +/* Wa_16025596647 */
> +static void psr1_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp,
> + bool dc5_dc6_blocked)
> +{
> + struct intel_display *display = to_intel_display(intel_dp);
> + u32 val;
> +
> + if (dc5_dc6_blocked)
> + 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(intel_dp->psr.pipe),
> + val);
> +}
> +
> +/* Wa_16025596647 */
> +static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp) {
> + struct intel_display *display = to_intel_display(intel_dp);
> + u32 current_dc_state =
> intel_display_power_get_current_dc_state(display);
> + struct drm_vblank_crtc *vblank =
> +&display->drm->vblank[intel_dp->psr.pipe];
> +
> + return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
> + current_dc_state != DC_STATE_EN_UPTO_DC6) ||
> + intel_dp->psr.active_non_psr_pipes ||
> + READ_ONCE(vblank->enabled);
> +}
> +
> +/* Wa_16025596647 */
> +static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp
> +*intel_dp) {
> + bool dc5_dc6_blocked;
> +
> + if (!intel_dp->psr.active)
> + return;
> +
> + dc5_dc6_blocked = is_dc5_dc6_blocked(intel_dp);
> +
> + if (intel_dp->psr.sel_update_enabled)
> + psr2_program_idle_frames(intel_dp, dc5_dc6_blocked ? 0 :
> + psr_compute_idle_frames(intel_dp));
> + else
> + psr1_apply_underrun_on_idle_wa_locked(intel_dp,
> dc5_dc6_blocked); }
> +
> +/**
> + * intel_psr_notify_pipe_change - Notify PSR about enable/disable of a
> +pipe
> + * @state: intel atomic state
> + * @crtc: intel crtc
> + * @enable: enable/disable
> + *
> + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to
> +apply
> + * remove the workaround when pipe is getting enabled/disabled */ void
> +intel_psr_notify_pipe_change(struct intel_atomic_state *state,
> + struct intel_crtc *crtc, bool enable) {
> + struct intel_display *display = to_intel_display(state);
> + struct intel_encoder *encoder;
> +
> + if (DISPLAY_VER(display) != 20 &&
> + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
> + return;
> +
> + for_each_intel_encoder_with_psr(display->drm, encoder) {
> + struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> + u8 active_non_psr_pipes;
> +
> + mutex_lock(&intel_dp->psr.lock);
> +
> + if (!intel_dp->psr.enabled || intel_dp-
> >psr.panel_replay_enabled)
> + goto unlock;
> +
> + active_non_psr_pipes = intel_dp->psr.active_non_psr_pipes;
> +
> + if (enable)
> + active_non_psr_pipes |= BIT(crtc->pipe);
> + else
> + active_non_psr_pipes &= ~BIT(crtc->pipe);
> +
> + if (active_non_psr_pipes == intel_dp->psr.active_non_psr_pipes)
> + goto unlock;
> +
> + if ((enable && intel_dp->psr.active_non_psr_pipes) ||
> + (!enable && !intel_dp->psr.active_non_psr_pipes)) {
> + intel_dp->psr.active_non_psr_pipes =
> active_non_psr_pipes;
> + goto unlock;
> + }
> +
> + intel_dp->psr.active_non_psr_pipes = active_non_psr_pipes;
> +
> + intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
> +unlock:
> + mutex_unlock(&intel_dp->psr.lock);
> + }
> +}
> +
> static void
> psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) { diff --git
> a/drivers/gpu/drm/i915/display/intel_psr.h
> b/drivers/gpu/drm/i915/display/intel_psr.h
> index a43a374cff550..273e70a50915c 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -60,6 +60,8 @@ void intel_psr2_program_trans_man_trk_ctl(struct
> intel_dsb *dsb, void intel_psr_pause(struct intel_dp *intel_dp); void
> intel_psr_resume(struct intel_dp *intel_dp); bool
> intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
> +void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
> + struct intel_crtc *crtc, bool enable);
> bool intel_psr_link_ok(struct intel_dp *intel_dp);
>
> void intel_psr_lock(const struct intel_crtc_state *crtc_state);
> --
> 2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH v2 07/11] drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable
2025-03-17 8:19 ` [PATCH v2 07/11] drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable Jouni Högander
@ 2025-04-08 11:07 ` Kahola, Mika
0 siblings, 0 replies; 23+ messages in thread
From: Kahola, Mika @ 2025-04-08 11:07 UTC (permalink / raw)
To: Hogander, Jouni, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Cc: Hogander, Jouni
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Jouni
> Högander
> Sent: Monday, 17 March 2025 10.19
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 07/11] drm/i915/psr: Add mechanism to notify PSR of DC5/6
> enable disable
>
> We need to apply/remove workaround for underrun on idle PSR HW issue
> (Wa_16025596647) when DC5/6 is enabled/disabled. This patch implements
> mechanism to notify PSR about DC5/6 enable/disable and applies/removes the
> workaround using this notification.
>
> Bspec: 74115
>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> .../gpu/drm/i915/display/intel_display_core.h | 2 +
> drivers/gpu/drm/i915/display/intel_psr.c | 50 +++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_psr.h | 2 +
> 3 files changed, 54 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h
> b/drivers/gpu/drm/i915/display/intel_display_core.h
> index 3673275f9061a..7ca1e7d710133 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> @@ -575,6 +575,8 @@ struct intel_display {
> struct intel_vbt_data vbt;
> struct intel_dmc_wl wl;
> struct intel_wm wm;
> +
> + struct work_struct psr_dc5_dc6_wa_work;
> };
>
> #endif /* __INTEL_DISPLAY_CORE_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 4b62d5832cbfa..baf6a7110a555 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -3718,6 +3718,56 @@ static void
> intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp
> psr1_apply_underrun_on_idle_wa_locked(intel_dp,
> dc5_dc6_blocked); }
>
> +static void psr_dc5_dc6_wa_work(struct work_struct *work) {
> + struct intel_display *display = container_of(work, typeof(*display),
> + psr_dc5_dc6_wa_work);
> + struct intel_encoder *encoder;
> +
> + for_each_intel_encoder_with_psr(display->drm, encoder) {
> + struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> + mutex_lock(&intel_dp->psr.lock);
> +
> + if (intel_dp->psr.enabled && !intel_dp-
> >psr.panel_replay_enabled)
> +
> intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
> +
> + mutex_unlock(&intel_dp->psr.lock);
> + }
> +}
> +
> +/**
> + * intel_psr_notify_dc5_dc6 - Notify PSR about enable/disable dc5/dc6
> + * @display: intel atomic state
> + *
> + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to
> +schedule
> + * psr_dc5_dc6_wa_work used for applying/removing the workaround.
> + */
> +void intel_psr_notify_dc5_dc6(struct intel_display *display) {
> + if (DISPLAY_VER(display) != 20 &&
> + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
> + return;
> +
> + schedule_work(&display->psr_dc5_dc6_wa_work);
> +}
> +
> +/**
> + * intel_psr_dc5_dc6_wa_init - Init work for underrun on idle PSR HW
> +bug wa
> + * @display: intel atomic state
> + *
> + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to
> +init
> + * psr_dc5_dc6_wa_work used for applying the workaround.
> + */
> +void intel_psr_dc5_dc6_wa_init(struct intel_display *display) {
> + if (DISPLAY_VER(display) != 20 &&
> + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
> + return;
> +
> + INIT_WORK(&display->psr_dc5_dc6_wa_work, psr_dc5_dc6_wa_work);
> }
> +
> /**
> * intel_psr_notify_pipe_change - Notify PSR about enable/disable of a pipe
> * @state: intel atomic state
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.h
> b/drivers/gpu/drm/i915/display/intel_psr.h
> index 273e70a50915c..bfe368239bc27 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -62,6 +62,8 @@ void intel_psr_resume(struct intel_dp *intel_dp); bool
> intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state); void
> intel_psr_notify_pipe_change(struct intel_atomic_state *state,
> struct intel_crtc *crtc, bool enable);
> +void intel_psr_notify_dc5_dc6(struct intel_display *display); void
> +intel_psr_dc5_dc6_wa_init(struct intel_display *display);
> bool intel_psr_link_ok(struct intel_dp *intel_dp);
>
> void intel_psr_lock(const struct intel_crtc_state *crtc_state);
> --
> 2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH v2 08/11] drm/i915/psr: Add interface to notify PSR of vblank enable/disable
2025-03-17 8:19 ` [PATCH v2 08/11] drm/i915/psr: Add interface to notify PSR of vblank enable/disable Jouni Högander
@ 2025-04-08 12:10 ` Kahola, Mika
0 siblings, 0 replies; 23+ messages in thread
From: Kahola, Mika @ 2025-04-08 12:10 UTC (permalink / raw)
To: Hogander, Jouni, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Cc: Hogander, Jouni
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Jouni
> Högander
> Sent: Monday, 17 March 2025 10.19
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 08/11] drm/i915/psr: Add interface to notify PSR of vblank
> enable/disable
>
> To implement Wa_16025596647 we need to get notification of vblank interrupt
> enable/disable. Add new interface to PSR code for this notification.
>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_psr.c | 40 ++++++++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_psr.h | 2 ++
> 2 files changed, 42 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index baf6a7110a555..afb9faed7784b 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -3820,6 +3820,46 @@ void intel_psr_notify_pipe_change(struct
> intel_atomic_state *state,
> }
> }
>
> +/**
> + * intel_psr_notify_vblank_enable_disable - Notify PSR about
> +enable/disable of vblank
> + * @display: intel display struct
> + * @enable: enable/disable
> + *
> + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to
> +apply
> + * remove the workaround when vblank is getting enabled/disabled */
> +void intel_psr_notify_vblank_enable_disable(struct intel_display *display,
> + bool enable)
> +{
> + struct intel_encoder *encoder;
> +
> + for_each_intel_encoder_with_psr(display->drm, encoder) {
> + struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> + mutex_lock(&intel_dp->psr.lock);
> + if (intel_dp->psr.panel_replay_enabled) {
> + mutex_unlock(&intel_dp->psr.lock);
> + break;
> + }
> +
> + if (intel_dp->psr.enabled)
> +
> intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
> +
> + mutex_unlock(&intel_dp->psr.lock);
> + return;
> + }
> +
> + /*
> + * NOTE: intel_display_power_set_target_dc_state is used
> + * only by PSR * code for DC3CO handling. DC3CO target
> + * state is currently disabled in * PSR code. If DC3CO
> + * is taken into use we need take that into account here
> + * as well.
> + */
> + intel_display_power_set_target_dc_state(display, enable ?
> DC_STATE_DISABLE :
> + DC_STATE_EN_UPTO_DC6);
> +}
> +
> static void
> psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) { diff --git
> a/drivers/gpu/drm/i915/display/intel_psr.h
> b/drivers/gpu/drm/i915/display/intel_psr.h
> index bfe368239bc27..a914b7ee3756a 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -64,6 +64,8 @@ void intel_psr_notify_pipe_change(struct
> intel_atomic_state *state,
> struct intel_crtc *crtc, bool enable); void
> intel_psr_notify_dc5_dc6(struct intel_display *display); void
> intel_psr_dc5_dc6_wa_init(struct intel_display *display);
> +void intel_psr_notify_vblank_enable_disable(struct intel_display *display,
> + bool enable);
> bool intel_psr_link_ok(struct intel_dp *intel_dp);
>
> void intel_psr_lock(const struct intel_crtc_state *crtc_state);
> --
> 2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH v2 09/11] drm/i915/psr: Apply underrun on PSR idle workaround
2025-03-17 8:19 ` [PATCH v2 09/11] drm/i915/psr: Apply underrun on PSR idle workaround Jouni Högander
@ 2025-04-08 12:27 ` Kahola, Mika
0 siblings, 0 replies; 23+ messages in thread
From: Kahola, Mika @ 2025-04-08 12:27 UTC (permalink / raw)
To: Hogander, Jouni, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Cc: Hogander, Jouni
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Jouni
> Högander
> Sent: Monday, 17 March 2025 10.19
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 09/11] drm/i915/psr: Apply underrun on PSR idle workaround
>
> This patch is applying workaround for underrun on idle PSR HW issue
> (Wa_16025596647) when PSR is getting enabled. It uses vblank enable/disable
> status, DC5/6 enabled disabled and enabled pipes count information made
> available.
>
> This patch is also adding calls to dc5/dc6, vblank enable/disable and pipe
> enable/disable notification functions as needed.
> intel_psr_needs_block_dc_vblank is modified to get vblank enable/disable
> notification on PSR capable system.
>
> Bspec: 74151
>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_display.c | 4 +
> .../drm/i915/display/intel_display_driver.c | 3 +
> .../gpu/drm/i915/display/intel_display_irq.c | 9 +-
> .../i915/display/intel_display_power_well.c | 4 +
> drivers/gpu/drm/i915/display/intel_psr.c | 103 +++++++++++-------
> 5 files changed, 76 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 3afb85fe8536d..834d023d0c626 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6648,6 +6648,8 @@ static void intel_enable_crtc(struct intel_atomic_state
> *state,
> intel_crtc_update_active_timings(pipe_crtc_state, false);
> }
>
> + intel_psr_notify_pipe_change(state, crtc, true);
> +
> display->funcs.display->crtc_enable(state, crtc);
>
> /* vblanks work again, re-enable pipe CRC. */ @@ -6767,6 +6769,8 @@
> static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>
> intel_crtc_joined_pipe_mask(old_crtc_state))
> intel_crtc_disable_pipe_crc(pipe_crtc);
>
> + intel_psr_notify_pipe_change(state, crtc, false);
> +
> display->funcs.display->crtc_disable(state, crtc);
>
> for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, diff --git
> a/drivers/gpu/drm/i915/display/intel_display_driver.c
> b/drivers/gpu/drm/i915/display/intel_display_driver.c
> index 31740a677dd80..b4c989bbac93a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_driver.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
> @@ -54,6 +54,7 @@
> #include "intel_plane_initial.h"
> #include "intel_pmdemand.h"
> #include "intel_pps.h"
> +#include "intel_psr.h"
> #include "intel_quirks.h"
> #include "intel_vga.h"
> #include "intel_wm.h"
> @@ -226,6 +227,8 @@ int intel_display_driver_probe_noirq(struct intel_display
> *display)
> if (ret)
> goto cleanup_bios;
>
> + intel_psr_dc5_dc6_wa_init(display);
> +
> /* FIXME: completely on the wrong abstraction layer */
> ret = intel_power_domains_init(display);
> if (ret < 0)
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c
> b/drivers/gpu/drm/i915/display/intel_display_irq.c
> index aa23bb8178053..62fbdcbb4a123 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> @@ -1728,14 +1728,7 @@ static void intel_display_vblank_dc_work(struct
> work_struct *work)
> container_of(work, typeof(*display), irq.vblank_dc_work);
> int vblank_wa_num_pipes = READ_ONCE(display-
> >irq.vblank_wa_num_pipes);
>
> - /*
> - * NOTE: intel_display_power_set_target_dc_state is used only by PSR
> - * code for DC3CO handling. DC3CO target state is currently disabled in
> - * PSR code. If DC3CO is taken into use we need take that into account
> - * here as well.
> - */
> - intel_display_power_set_target_dc_state(display, vblank_wa_num_pipes
> ? DC_STATE_DISABLE :
> - DC_STATE_EN_UPTO_DC6);
> + intel_psr_notify_vblank_enable_disable(display, vblank_wa_num_pipes);
> }
>
> int bdw_enable_vblank(struct drm_crtc *_crtc) diff --git
> a/drivers/gpu/drm/i915/display/intel_display_power_well.c
> b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> index 8ec87ffd87d26..510f97341893b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> @@ -24,6 +24,7 @@
> #include "intel_hotplug.h"
> #include "intel_pcode.h"
> #include "intel_pps.h"
> +#include "intel_psr.h"
> #include "intel_tc.h"
> #include "intel_vga.h"
> #include "skl_watermark.h"
> @@ -762,6 +763,9 @@ void gen9_set_dc_state(struct intel_display *display, u32
> state)
> state & ~power_domains->allowed_dc_mask))
> state &= power_domains->allowed_dc_mask;
>
> + if (!power_domains->initializing)
> + intel_psr_notify_dc5_dc6(display);
> +
> val = intel_de_read(display, DC_STATE_EN);
> mask = gen9_dc_mask(display);
> drm_dbg_kms(display->drm, "Setting DC state from %02x to %02x\n", diff
> --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index afb9faed7784b..d2a28a83e4f20 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -908,6 +908,41 @@ static u8 psr_compute_idle_frames(struct intel_dp
> *intel_dp)
> return idle_frames;
> }
>
> +/* Wa_16025596647 */
> +static void psr1_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp,
> + bool dc5_dc6_blocked)
> +{
> + struct intel_display *display = to_intel_display(intel_dp);
> + u32 val;
> +
> + if (dc5_dc6_blocked)
> + 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(intel_dp->psr.pipe),
> + val);
> +}
> +
> +static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp) {
> + struct intel_display *display = to_intel_display(intel_dp);
> + u32 current_dc_state =
> intel_display_power_get_current_dc_state(display);
> + struct drm_vblank_crtc *vblank =
> +&display->drm->vblank[intel_dp->psr.pipe];
> +
> + return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
> + current_dc_state != DC_STATE_EN_UPTO_DC6) ||
> + intel_dp->psr.active_non_psr_pipes ||
> + READ_ONCE(vblank->enabled);
> +}
> +
> static void hsw_activate_psr1(struct intel_dp *intel_dp) {
> struct intel_display *display = to_intel_display(intel_dp); @@ -937,6
> +972,12 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
>
> intel_de_rmw(display, psr_ctl_reg(display, cpu_transcoder),
> ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
> +
> + /* Wa_16025596647 */
> + if ((DISPLAY_VER(display) == 20 ||
> + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
> + is_dc5_dc6_blocked(intel_dp))
> + psr1_apply_underrun_on_idle_wa_locked(intel_dp, true);
> }
>
> static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) @@ -1019,8
> +1060,16 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
> enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
> u32 val = EDP_PSR2_ENABLE;
> u32 psr_val = 0;
> + u8 idle_frames;
>
> - val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
> + /* Wa_16025596647 */
> + if ((DISPLAY_VER(display) == 20 ||
> + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
> + is_dc5_dc6_blocked(intel_dp))
> + idle_frames = 0;
> + else
> + idle_frames = psr_compute_idle_frames(intel_dp);
> + val |= EDP_PSR2_IDLE_FRAMES(idle_frames);
>
> if (DISPLAY_VER(display) < 14 && !IS_ALDERLAKE_P(dev_priv))
> val |= EDP_SU_TRACK_ENABLE;
> @@ -2101,6 +2150,10 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
>
> drm_WARN_ON(display->drm, !(val & EDP_PSR2_ENABLE));
> } else {
> + if (DISPLAY_VER(display) == 20 ||
> + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
> + psr1_apply_underrun_on_idle_wa_locked(intel_dp,
> false);
> +
> val = intel_de_rmw(display,
> psr_ctl_reg(display, cpu_transcoder),
> EDP_PSR_ENABLE, 0);
> @@ -2312,6 +2365,7 @@ void intel_psr_resume(struct intel_dp *intel_dp) bool
> intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state) {
> struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> + struct intel_display *display = to_intel_display(crtc_state);
> struct intel_encoder *encoder;
>
> for_each_encoder_on_crtc(crtc->base.dev, &crtc->base, encoder) { @@
> -2322,8 +2376,15 @@ bool intel_psr_needs_block_dc_vblank(const struct
> intel_crtc_state *crtc_state)
>
> intel_dp = enc_to_intel_dp(encoder);
>
> - if (intel_dp_is_edp(intel_dp) &&
> - CAN_PANEL_REPLAY(intel_dp))
> + if (!intel_dp_is_edp(intel_dp))
> + continue;
> +
> + if (CAN_PANEL_REPLAY(intel_dp))
> + return true;
> +
> + if ((DISPLAY_VER(display) == 20 ||
> + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
> &&
> + CAN_PSR(intel_dp))
> return true;
> }
>
> @@ -3665,42 +3726,6 @@ void intel_psr_unlock(const struct intel_crtc_state
> *crtc_state)
> }
> }
>
> -/* Wa_16025596647 */
> -static void psr1_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp,
> - bool dc5_dc6_blocked)
> -{
> - struct intel_display *display = to_intel_display(intel_dp);
> - u32 val;
> -
> - if (dc5_dc6_blocked)
> - 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(intel_dp->psr.pipe),
> - val);
> -}
> -
> -/* Wa_16025596647 */
> -static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp) -{
> - struct intel_display *display = to_intel_display(intel_dp);
> - u32 current_dc_state =
> intel_display_power_get_current_dc_state(display);
> - struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp-
> >psr.pipe];
> -
> - return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
> - current_dc_state != DC_STATE_EN_UPTO_DC6) ||
> - intel_dp->psr.active_non_psr_pipes ||
> - READ_ONCE(vblank->enabled);
> -}
> -
> /* Wa_16025596647 */
> static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp
> *intel_dp) {
> --
> 2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH v2 10/11] drm/i915/display: Rename intel_psr_needs_block_dc_vblank
2025-03-17 8:19 ` [PATCH v2 10/11] drm/i915/display: Rename intel_psr_needs_block_dc_vblank Jouni Högander
@ 2025-04-08 12:28 ` Kahola, Mika
0 siblings, 0 replies; 23+ messages in thread
From: Kahola, Mika @ 2025-04-08 12:28 UTC (permalink / raw)
To: Hogander, Jouni, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Cc: Hogander, Jouni
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Jouni
> Högander
> Sent: Monday, 17 March 2025 10.19
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 10/11] drm/i915/display: Rename
> intel_psr_needs_block_dc_vblank
>
> Scope of intel_psr_needs_block_dc_vblank has changed now. Rename it as
> intel_psr_needs_vblank_notification. Also rename
> intel_crtc::block_dc_for_vblank as intel_crtc:vblank_psr_notify
>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_crtc.c | 4 ++--
> drivers/gpu/drm/i915/display/intel_display_irq.c | 4 ++--
> drivers/gpu/drm/i915/display/intel_display_types.h | 2 +-
> drivers/gpu/drm/i915/display/intel_psr.c | 8 +++++---
> drivers/gpu/drm/i915/display/intel_psr.h | 2 +-
> 5 files changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c
> b/drivers/gpu/drm/i915/display/intel_crtc.c
> index 5b2603ef2ff75..bdf30ab963967 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -124,7 +124,7 @@ void intel_crtc_vblank_on(const struct intel_crtc_state
> *crtc_state) {
> struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>
> - crtc->block_dc_for_vblank =
> intel_psr_needs_block_dc_vblank(crtc_state);
> + crtc->vblank_psr_notify =
> +intel_psr_needs_vblank_notification(crtc_state);
>
> assert_vblank_disabled(&crtc->base);
> drm_crtc_set_max_vblank_count(&crtc->base,
> @@ -154,7 +154,7 @@ void intel_crtc_vblank_off(const struct intel_crtc_state
> *crtc_state)
> drm_crtc_vblank_off(&crtc->base);
> assert_vblank_disabled(&crtc->base);
>
> - crtc->block_dc_for_vblank = false;
> + crtc->vblank_psr_notify = false;
>
> flush_work(&display->irq.vblank_dc_work);
> }
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c
> b/drivers/gpu/drm/i915/display/intel_display_irq.c
> index 62fbdcbb4a123..833f8227da803 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> @@ -1742,7 +1742,7 @@ int bdw_enable_vblank(struct drm_crtc *_crtc)
> if (gen11_dsi_configure_te(crtc, true))
> return 0;
>
> - if (crtc->block_dc_for_vblank && display->irq.vblank_wa_num_pipes++
> == 0)
> + if (crtc->vblank_psr_notify && display->irq.vblank_wa_num_pipes++ ==
> +0)
> schedule_work(&display->irq.vblank_dc_work);
>
> spin_lock_irqsave(&dev_priv->irq_lock, irqflags); @@ -1773,7 +1773,7
> @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
> bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
> spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
>
> - if (crtc->block_dc_for_vblank && --display->irq.vblank_wa_num_pipes
> == 0)
> + if (crtc->vblank_psr_notify && --display->irq.vblank_wa_num_pipes ==
> +0)
> schedule_work(&display->irq.vblank_dc_work);
> }
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 3d203a2003f10..4f3fdfacbc1b1 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1440,7 +1440,7 @@ struct intel_crtc {
> struct intel_pipe_crc pipe_crc;
> #endif
>
> - bool block_dc_for_vblank;
> + bool vblank_psr_notify;
> };
>
> struct intel_plane_error {
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index d2a28a83e4f20..228996f1f26d2 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -2354,15 +2354,17 @@ void intel_psr_resume(struct intel_dp *intel_dp) }
>
> /**
> - * intel_psr_needs_block_dc_vblank - Check if block dc entry is needed
> + * intel_psr_needs_vblank_notification - Check if PSR need vblank
> + enable/disable
> + * notification.
> * @crtc_state: CRTC status
> *
> * We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
> * prevent it in case of Panel Replay. Panel Replay switches main link off on
> * DC entry. This means vblank interrupts are not fired and is a problem if
> - * user-space is polling for vblank events.
> + * user-space is polling for vblank events. Also Wa_16025596647 needs
> + * information when vblank is enabled/disabled.
> */
> -bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
> +bool intel_psr_needs_vblank_notification(const struct intel_crtc_state
> +*crtc_state)
> {
> struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> struct intel_display *display = to_intel_display(crtc_state); diff --git
> a/drivers/gpu/drm/i915/display/intel_psr.h
> b/drivers/gpu/drm/i915/display/intel_psr.h
> index a914b7ee3756a..c61384bb7382a 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -59,7 +59,7 @@ void intel_psr2_program_trans_man_trk_ctl(struct
> intel_dsb *dsb,
> const struct intel_crtc_state
> *crtc_state); void intel_psr_pause(struct intel_dp *intel_dp); void
> intel_psr_resume(struct intel_dp *intel_dp); -bool
> intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
> +bool intel_psr_needs_vblank_notification(const struct intel_crtc_state
> +*crtc_state);
> void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
> struct intel_crtc *crtc, bool enable); void
> intel_psr_notify_dc5_dc6(struct intel_display *display);
> --
> 2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH v2 11/11] drm/i915/display: Rename vblank DC workaround functions and variables
2025-03-17 8:19 ` [PATCH v2 11/11] drm/i915/display: Rename vblank DC workaround functions and variables Jouni Högander
@ 2025-04-08 12:28 ` Kahola, Mika
0 siblings, 0 replies; 23+ messages in thread
From: Kahola, Mika @ 2025-04-08 12:28 UTC (permalink / raw)
To: Hogander, Jouni, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Cc: Hogander, Jouni
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Jouni
> Högander
> Sent: Monday, 17 March 2025 10.19
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 11/11] drm/i915/display: Rename vblank DC workaround
> functions and variables
>
> We have extended using vblank DC workaround mechanism for
> Wa_16025596647. Rename related functions and variables:
>
> vblank_wa_num_pipes -> vblank_enable_count vblank_dc_work ->
> vblank_notify_work intel_display_vblank_dc_work ->
> intel_display_vblank_notify_work
>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_crtc.c | 2 +-
> .../gpu/drm/i915/display/intel_display_core.h | 4 ++--
> .../gpu/drm/i915/display/intel_display_irq.c | 20 +++++++++----------
> 3 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c
> b/drivers/gpu/drm/i915/display/intel_crtc.c
> index bdf30ab963967..537859630363b 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -156,7 +156,7 @@ void intel_crtc_vblank_off(const struct intel_crtc_state
> *crtc_state)
>
> crtc->vblank_psr_notify = false;
>
> - flush_work(&display->irq.vblank_dc_work);
> + flush_work(&display->irq.vblank_notify_work);
> }
>
> struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc) diff --git
> a/drivers/gpu/drm/i915/display/intel_display_core.h
> b/drivers/gpu/drm/i915/display/intel_display_core.h
> index 7ca1e7d710133..b24586c3753a9 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> @@ -466,9 +466,9 @@ struct intel_display {
> /* For i915gm/i945gm vblank irq workaround */
> u8 vblank_enabled;
>
> - int vblank_wa_num_pipes;
> + int vblank_enable_count;
>
> - struct work_struct vblank_dc_work;
> + struct work_struct vblank_notify_work;
>
> u32 de_irq_mask[I915_MAX_PIPES];
> u32 pipestat_irq_mask[I915_MAX_PIPES];
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c
> b/drivers/gpu/drm/i915/display/intel_display_irq.c
> index 833f8227da803..22942edf5ff02 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> @@ -1722,13 +1722,13 @@ static bool gen11_dsi_configure_te(struct intel_crtc
> *intel_crtc,
> return true;
> }
>
> -static void intel_display_vblank_dc_work(struct work_struct *work)
> +static void intel_display_vblank_notify_work(struct work_struct *work)
> {
> struct intel_display *display =
> - container_of(work, typeof(*display), irq.vblank_dc_work);
> - int vblank_wa_num_pipes = READ_ONCE(display-
> >irq.vblank_wa_num_pipes);
> + container_of(work, typeof(*display), irq.vblank_notify_work);
> + int vblank_enable_count = READ_ONCE(display-
> >irq.vblank_enable_count);
>
> - intel_psr_notify_vblank_enable_disable(display, vblank_wa_num_pipes);
> + intel_psr_notify_vblank_enable_disable(display, vblank_enable_count);
> }
>
> int bdw_enable_vblank(struct drm_crtc *_crtc) @@ -1742,8 +1742,8 @@ int
> bdw_enable_vblank(struct drm_crtc *_crtc)
> if (gen11_dsi_configure_te(crtc, true))
> return 0;
>
> - if (crtc->vblank_psr_notify && display->irq.vblank_wa_num_pipes++ ==
> 0)
> - schedule_work(&display->irq.vblank_dc_work);
> + if (crtc->vblank_psr_notify && display->irq.vblank_enable_count++ == 0)
> + schedule_work(&display->irq.vblank_notify_work);
>
> spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
> bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); @@ -1773,8
> +1773,8 @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
> bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
> spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
>
> - if (crtc->vblank_psr_notify && --display->irq.vblank_wa_num_pipes == 0)
> - schedule_work(&display->irq.vblank_dc_work);
> + if (crtc->vblank_psr_notify && --display->irq.vblank_enable_count == 0)
> + schedule_work(&display->irq.vblank_notify_work);
> }
>
> static u32 vlv_dpinvgtt_pipe_fault_mask(enum pipe pipe) @@ -2345,6 +2345,6
> @@ void intel_display_irq_init(struct drm_i915_private *i915)
>
> intel_hotplug_irq_init(i915);
>
> - INIT_WORK(&i915->display.irq.vblank_dc_work,
> - intel_display_vblank_dc_work);
> + INIT_WORK(&i915->display.irq.vblank_notify_work,
> + intel_display_vblank_notify_work);
> }
> --
> 2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2025-04-08 12:29 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-17 8:18 [PATCH v2 00/11] Underrun on idle PSR workaround Jouni Högander
2025-03-17 8:18 ` [PATCH v2 01/11] drm/i915/display: Add new interface for getting dc_state Jouni Högander
2025-03-17 8:18 ` [PATCH v2 02/11] drm/i915/psr: Store enabled non-psr pipes into intel_crtc_state Jouni Högander
2025-03-17 8:18 ` [PATCH v2 03/11] drm/i915/dmc: Add PIPEDMC_EVT_CTL register definition Jouni Högander
2025-03-17 8:18 ` [PATCH v2 04/11] drm/i915/dmc: Add PIPEDMC_BLOCK_PKGC_SW definitions Jouni Högander
2025-04-07 11:50 ` Kahola, Mika
2025-03-17 8:18 ` [PATCH v2 05/11] drm/i915/psr: Write PIPEDMC_BLOCK_PKGC_SW when enabling PSR Jouni Högander
2025-03-21 12:39 ` Jani Nikula
2025-03-17 8:19 ` [PATCH v2 06/11] drm/i915/psr: Add mechanism to notify PSR of pipe enable/disable Jouni Högander
2025-04-08 10:44 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 07/11] drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable Jouni Högander
2025-04-08 11:07 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 08/11] drm/i915/psr: Add interface to notify PSR of vblank enable/disable Jouni Högander
2025-04-08 12:10 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 09/11] drm/i915/psr: Apply underrun on PSR idle workaround Jouni Högander
2025-04-08 12:27 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 10/11] drm/i915/display: Rename intel_psr_needs_block_dc_vblank Jouni Högander
2025-04-08 12:28 ` Kahola, Mika
2025-03-17 8:19 ` [PATCH v2 11/11] drm/i915/display: Rename vblank DC workaround functions and variables Jouni Högander
2025-04-08 12:28 ` Kahola, Mika
2025-03-17 8:47 ` ✗ Fi.CI.CHECKPATCH: warning for Underrun on idle PSR workaround (rev3) Patchwork
2025-03-17 8:47 ` ✗ Fi.CI.SPARSE: " Patchwork
2025-03-17 9:07 ` ✓ i915.CI.BAT: success " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox