Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [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