public inbox for intel-xe@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH 00/19] drm/i915/display: Add DC3CO support
@ 2026-03-26 17:15 Dibin Moolakadan Subrahmanian
  2026-03-26 17:15 ` [PATCH 01/19] drm/i915/display: Remove TGL " Dibin Moolakadan Subrahmanian
                   ` (18 more replies)
  0 siblings, 19 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

This series adds initial DC3CO support for display version 35+ and adds
debugfs visibility into DC3CO count/residency.

The series also includes required PSR/ALPM updates for DC3CO enablement.

This series is based on the CMTG enablement series currently under
review:
https://patchwork.freedesktop.org/series/157664/

DC3CO is not enabled by this series since power_domains->allowed_dc_mask
is not updated to include DC3CO.

TODO: 
- CMTG restore on DC6 exit
- CMTG HWGB programming for DC3CO latencies
- Enable DC3CO in power_domains->allowed_dc_mask

Dibin Moolakadan Subrahmanian (19):
  drm/i915/display: Remove TGL DC3CO support
  drm/i915/display: Replace DC_STATE_EN_DC3CO with
    DC_STATE_EN_UPTO_DC3CO
  drm/i915/display: Use FIELD_PREP() for DC state enable bits
  drm/i915/display: Add DC3CO DC_STATE enable/disable support
  drm/i915/display: Validate target DC state against allowed_dc_mask
  drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum
  drm/i915/display: Add helper to check DC3CO support
  drm/i915/display: Add DC3CO eligibility computation
  drm/i915/display: Remove unused PSR dc3co_exitline field
  drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state
  drm/i915/display: Store DC3CO eligibility in PSR state
  drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO
  drm/i915/display: Define DC3CO idle protocol bit in PR_ALPM_CTL
  drm/i915/display: Enable DC3CO idle protocol in ALPM
  drm/i915/display: PSR Add delayed work to exit DC3CO
  drm/i915/display: Add helper to enable DC counter
  drm/i915/display: Remove DC3CO DMC debugfs
  drm/i915/display: Add DC3CO count and residency in dmc debugfs
  drm/i915/display: PSR set idle frames while exit from DC3CO

 drivers/gpu/drm/i915/display/intel_alpm.c     |   9 +
 drivers/gpu/drm/i915/display/intel_display.c  |  98 +++++++-
 drivers/gpu/drm/i915/display/intel_display.h  |   2 +-
 .../drm/i915/display/intel_display_device.h   |   2 +-
 .../drm/i915/display/intel_display_power.c    |  20 +-
 .../drm/i915/display/intel_display_power.h    |  16 ++
 .../i915/display/intel_display_power_well.c   |  36 ++-
 .../i915/display/intel_display_power_well.h   |   1 +
 .../gpu/drm/i915/display/intel_display_regs.h |  14 +-
 .../drm/i915/display/intel_display_types.h    |  14 +-
 drivers/gpu/drm/i915/display/intel_dmc.c      |  15 +-
 drivers/gpu/drm/i915/display/intel_dmc_regs.h |   2 +
 drivers/gpu/drm/i915/display/intel_dmc_wl.c   |   2 +-
 drivers/gpu/drm/i915/display/intel_psr.c      | 224 +++++-------------
 drivers/gpu/drm/i915/display/intel_psr_regs.h |   1 +
 15 files changed, 245 insertions(+), 211 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 01/19] drm/i915/display: Remove TGL DC3CO support
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 20:40   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with DC_STATE_EN_UPTO_DC3CO Dibin Moolakadan Subrahmanian
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Remove all Tiger Lake DC3CO-related functions, as the feature is not
enabled and not used. The existing structure members are intentionally
left in place and will be cleaned up in subsequent patches.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 .../i915/display/intel_display_power_well.c   |  25 ---
 .../drm/i915/display/intel_display_types.h    |   1 -
 drivers/gpu/drm/i915/display/intel_psr.c      | 163 ------------------
 3 files changed, 189 deletions(-)

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 f855f0f88694..6d5f07f7f590 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -867,23 +867,6 @@ void gen9_set_dc_state(struct intel_display *display, u32 state)
 	power_domains->dc_state = val & mask;
 }
 
-static void tgl_enable_dc3co(struct intel_display *display)
-{
-	drm_dbg_kms(display->drm, "Enabling DC3CO\n");
-	gen9_set_dc_state(display, DC_STATE_EN_DC3CO);
-}
-
-static void tgl_disable_dc3co(struct intel_display *display)
-{
-	drm_dbg_kms(display->drm, "Disabling DC3CO\n");
-	intel_de_rmw(display, DC_STATE_EN, DC_STATE_DC3CO_STATUS, 0);
-	gen9_set_dc_state(display, DC_STATE_DISABLE);
-	/*
-	 * Delay of 200us DC3CO Exit time B.Spec 49196
-	 */
-	usleep_range(200, 210);
-}
-
 static void assert_can_enable_dc5(struct intel_display *display)
 {
 	enum i915_power_well_id high_pg;
@@ -1062,11 +1045,6 @@ void gen9_disable_dc_states(struct intel_display *display)
 	struct intel_cdclk_config cdclk_config = {};
 	u32 old_state = power_domains->dc_state;
 
-	if (power_domains->target_dc_state == DC_STATE_EN_DC3CO) {
-		tgl_disable_dc3co(display);
-		return;
-	}
-
 	if (HAS_DISPLAY(display)) {
 		intel_dmc_wl_get_noreg(display);
 		gen9_set_dc_state(display, DC_STATE_DISABLE);
@@ -1115,9 +1093,6 @@ static void gen9_dc_off_power_well_disable(struct intel_display *display,
 		return;
 
 	switch (power_domains->target_dc_state) {
-	case DC_STATE_EN_DC3CO:
-		tgl_enable_dc3co(display);
-		break;
 	case DC_STATE_EN_UPTO_DC6:
 		skl_enable_dc6(display);
 		break;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index b4c3d8537a99..6830f911d94d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1784,7 +1784,6 @@ struct intel_psr {
 	bool panel_replay_enabled;
 	u32 dc3co_exitline;
 	u32 dc3co_exit_delay;
-	struct delayed_work dc3co_work;
 	u8 entry_setup_frames;
 
 	u8 io_wake_lines;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 5041a5a138d1..29900576e117 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -85,22 +85,6 @@
  * issues the self-refresh re-enable code is done from a work queue, which
  * must be correctly synchronized/cancelled when shutting down the pipe."
  *
- * DC3CO (DC3 clock off)
- *
- * On top of PSR2, GEN12 adds a intermediate power savings state that turns
- * clock off automatically during PSR2 idle state.
- * The smaller overhead of DC3co entry/exit vs. the overhead of PSR2 deep sleep
- * entry/exit allows the HW to enter a low-power state even when page flipping
- * periodically (for instance a 30fps video playback scenario).
- *
- * Every time a flips occurs PSR2 will get out of deep sleep state(if it was),
- * so DC3CO is enabled and tgl_dc3co_disable_work is schedule to run after 6
- * frames, if no other flip occurs and the function above is executed, DC3CO is
- * disabled and PSR2 is configured to enter deep sleep, resetting again in case
- * of another flip.
- * Front buffer modifications do not trigger DC3CO activation on purpose as it
- * would bring a lot of complexity and most of the moderns systems will only
- * use page flips.
  */
 
 /*
@@ -1178,108 +1162,6 @@ static void psr2_program_idle_frames(struct intel_dp *intel_dp,
 		     EDP_PSR2_IDLE_FRAMES(idle_frames));
 }
 
-static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
-{
-	struct intel_display *display = to_intel_display(intel_dp);
-
-	psr2_program_idle_frames(intel_dp, 0);
-	intel_display_power_set_target_dc_state(display, DC_STATE_EN_DC3CO);
-}
-
-static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp)
-{
-	struct intel_display *display = to_intel_display(intel_dp);
-
-	intel_display_power_set_target_dc_state(display, DC_STATE_EN_UPTO_DC6);
-	psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp));
-}
-
-static void tgl_dc3co_disable_work(struct work_struct *work)
-{
-	struct intel_dp *intel_dp =
-		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
-
-	mutex_lock(&intel_dp->psr.lock);
-	/* If delayed work is pending, it is not idle */
-	if (delayed_work_pending(&intel_dp->psr.dc3co_work))
-		goto unlock;
-
-	tgl_psr2_disable_dc3co(intel_dp);
-unlock:
-	mutex_unlock(&intel_dp->psr.lock);
-}
-
-static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp)
-{
-	if (!intel_dp->psr.dc3co_exitline)
-		return;
-
-	cancel_delayed_work(&intel_dp->psr.dc3co_work);
-	/* Before PSR2 exit disallow dc3co*/
-	tgl_psr2_disable_dc3co(intel_dp);
-}
-
-static bool
-dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp,
-			      struct intel_crtc_state *crtc_state)
-{
-	struct intel_display *display = to_intel_display(intel_dp);
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
-	enum port port = dig_port->base.port;
-
-	if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14)
-		return pipe <= PIPE_B && port <= PORT_B;
-	else
-		return pipe == PIPE_A && port == PORT_A;
-}
-
-static void
-tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
-				  struct intel_crtc_state *crtc_state)
-{
-	struct intel_display *display = to_intel_display(intel_dp);
-	const u32 crtc_vdisplay = crtc_state->uapi.adjusted_mode.crtc_vdisplay;
-	struct i915_power_domains *power_domains = &display->power.domains;
-	u32 exit_scanlines;
-
-	/*
-	 * FIXME: Due to the changed sequence of activating/deactivating DC3CO,
-	 * disable DC3CO until the changed dc3co activating/deactivating sequence
-	 * is applied. B.Specs:49196
-	 */
-	return;
-
-	/*
-	 * DMC's DC3CO exit mechanism has an issue with Selective Fecth
-	 * TODO: when the issue is addressed, this restriction should be removed.
-	 */
-	if (crtc_state->enable_psr2_sel_fetch)
-		return;
-
-	if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC3CO))
-		return;
-
-	if (!dc3co_is_pipe_port_compatible(intel_dp, crtc_state))
-		return;
-
-	/* Wa_16011303918:adl-p */
-	if (intel_display_wa(display, INTEL_DISPLAY_WA_16011303918))
-		return;
-
-	/*
-	 * DC3CO Exit time 200us B.Spec 49196
-	 * PSR2 transcoder Early Exit scanlines = ROUNDUP(200 / line time) + 1
-	 */
-	exit_scanlines =
-		intel_usecs_to_scanlines(&crtc_state->uapi.adjusted_mode, 200) + 1;
-
-	if (drm_WARN_ON(display->drm, exit_scanlines > crtc_vdisplay))
-		return;
-
-	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
-}
-
 static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
 					      struct intel_crtc_state *crtc_state)
 {
@@ -1622,8 +1504,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
-	tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
-
 	return true;
 }
 
@@ -2071,16 +1951,6 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
 
 	psr_irq_control(intel_dp);
 
-	/*
-	 * TODO: if future platforms supports DC3CO in more than one
-	 * transcoder, EXITLINE will need to be unset when disabling PSR
-	 */
-	if (intel_dp->psr.dc3co_exitline)
-		intel_de_rmw(display,
-			     TRANS_EXITLINE(display, cpu_transcoder),
-			     EXITLINE_MASK,
-			     intel_dp->psr.dc3co_exitline << EXITLINE_SHIFT | EXITLINE_ENABLE);
-
 	if (HAS_PSR_HW_TRACKING(display) && HAS_PSR2_SEL_FETCH(display))
 		intel_de_rmw(display, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
 			     intel_dp->psr.psr2_sel_fetch_enabled ?
@@ -2258,7 +2128,6 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
 		intel_de_rmw(display, TRANS_DP2_CTL(intel_dp->psr.transcoder),
 			     TRANS_DP2_PANEL_REPLAY_ENABLE, 0);
 	} else if (intel_dp->psr.sel_update_enabled) {
-		tgl_disallow_dc3co_on_psr2_exit(intel_dp);
 
 		val = intel_de_rmw(display,
 				   EDP_PSR2_CTL(display, cpu_transcoder),
@@ -2401,7 +2270,6 @@ void intel_psr_disable(struct intel_dp *intel_dp,
 
 	mutex_unlock(&intel_dp->psr.lock);
 	cancel_work_sync(&intel_dp->psr.work);
-	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
 }
 
 /**
@@ -2432,7 +2300,6 @@ void intel_psr_pause(struct intel_dp *intel_dp)
 	mutex_unlock(&psr->lock);
 
 	cancel_work_sync(&psr->work);
-	cancel_delayed_work_sync(&psr->dc3co_work);
 }
 
 /**
@@ -3568,34 +3435,6 @@ void intel_psr_invalidate(struct intel_display *display,
 		mutex_unlock(&intel_dp->psr.lock);
 	}
 }
-/*
- * When we will be completely rely on PSR2 S/W tracking in future,
- * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP
- * event also therefore tgl_dc3co_flush_locked() require to be changed
- * accordingly in future.
- */
-static void
-tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
-		       enum fb_op_origin origin)
-{
-	struct intel_display *display = to_intel_display(intel_dp);
-
-	if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.sel_update_enabled ||
-	    !intel_dp->psr.active)
-		return;
-
-	/*
-	 * At every frontbuffer flush flip event modified delay of delayed work,
-	 * when delayed work schedules that means display has been idle.
-	 */
-	if (!(frontbuffer_bits &
-	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
-		return;
-
-	tgl_psr2_enable_dc3co(intel_dp);
-	mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work,
-			 intel_dp->psr.dc3co_exit_delay);
-}
 
 static void _psr_flush_handle(struct intel_dp *intel_dp)
 {
@@ -3682,7 +3521,6 @@ void intel_psr_flush(struct intel_display *display,
 		if (origin == ORIGIN_FLIP ||
 		    (origin == ORIGIN_CURSOR_UPDATE &&
 		     !intel_dp->psr.psr2_sel_fetch_enabled)) {
-			tgl_dc3co_flush_locked(intel_dp, frontbuffer_bits, origin);
 			goto unlock;
 		}
 
@@ -3741,7 +3579,6 @@ void intel_psr_init(struct intel_dp *intel_dp)
 		intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link;
 
 	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
-	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work);
 	mutex_init(&intel_dp->psr.lock);
 }
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with DC_STATE_EN_UPTO_DC3CO
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
  2026-03-26 17:15 ` [PATCH 01/19] drm/i915/display: Remove TGL " Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 20:51   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 03/19] drm/i915/display: Use FIELD_PREP() for DC state enable bits Dibin Moolakadan Subrahmanian
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

On platforms prior to xe3, DC3CO was controlled via a standalone enable
bit. Starting with xe3 DC3CO is encoded as part of the existing
DC_STATE_EN_UPTO_DC* field.

No functional change, as DC3CO is not enabled on platforms prior to xe3.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_power.c      | 6 +++---
 drivers/gpu/drm/i915/display/intel_display_power_well.c | 4 ++--
 drivers/gpu/drm/i915/display/intel_display_regs.h       | 2 +-
 drivers/gpu/drm/i915/display/intel_dmc_wl.c             | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index ec96b141c74c..0afae5c2f62b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -267,7 +267,7 @@ sanitize_target_dc_state(struct intel_display *display,
 	static const u32 states[] = {
 		DC_STATE_EN_UPTO_DC6,
 		DC_STATE_EN_UPTO_DC5,
-		DC_STATE_EN_DC3CO,
+		DC_STATE_EN_UPTO_DC3CO,
 		DC_STATE_DISABLE,
 	};
 	int i;
@@ -999,10 +999,10 @@ static u32 get_allowed_dc_mask(struct intel_display *display, int enable_dc)
 
 	switch (requested_dc) {
 	case 4:
-		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6;
+		mask |= DC_STATE_EN_UPTO_DC3CO | DC_STATE_EN_UPTO_DC6;
 		break;
 	case 3:
-		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC5;
+		mask |= DC_STATE_EN_UPTO_DC3CO | DC_STATE_EN_UPTO_DC5;
 		break;
 	case 2:
 		mask |= DC_STATE_EN_UPTO_DC6;
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 6d5f07f7f590..9a948f5e2164 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -773,7 +773,7 @@ static u32 gen9_dc_mask(struct intel_display *display)
 	mask = DC_STATE_EN_UPTO_DC5;
 
 	if (DISPLAY_VER(display) >= 12)
-		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6
+		mask |= DC_STATE_EN_UPTO_DC3CO | DC_STATE_EN_UPTO_DC6
 					  | DC_STATE_EN_DC9;
 	else if (DISPLAY_VER(display) == 11)
 		mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9;
@@ -1023,7 +1023,7 @@ static void bxt_verify_dpio_phy_power_wells(struct intel_display *display)
 static bool gen9_dc_off_power_well_enabled(struct intel_display *display,
 					   struct i915_power_well *power_well)
 {
-	return ((intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_DC3CO) == 0 &&
+	return ((intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC3CO) == 0 &&
 		(intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
index 5838338f495a..d0196d4ad234 100644
--- a/drivers/gpu/drm/i915/display/intel_display_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
@@ -3044,13 +3044,13 @@ enum skl_power_gate {
 /* GEN9 DC */
 #define DC_STATE_EN			_MMIO(0x45504)
 #define  DC_STATE_DISABLE		0
-#define  DC_STATE_EN_DC3CO		REG_BIT(30)
 #define  DC_STATE_DC3CO_STATUS		REG_BIT(29)
 #define  HOLD_PHY_CLKREQ_PG1_LATCH	REG_BIT(21)
 #define  HOLD_PHY_PG1_LATCH		REG_BIT(20)
 #define  DC_STATE_EN_UPTO_DC5		(1 << 0)
 #define  DC_STATE_EN_DC9		(1 << 3)
 #define  DC_STATE_EN_UPTO_DC6		(2 << 0)
+#define  DC_STATE_EN_UPTO_DC3CO		(3 << 0)
 #define  DC_STATE_EN_UPTO_DC5_DC6_MASK   0x3
 
 #define  DC_STATE_DEBUG                  _MMIO(0x45520)
diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
index 73a3101514f3..9f403b7820ab 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
@@ -260,7 +260,7 @@ static bool intel_dmc_wl_check_range(struct intel_display *display,
 	 * the DMC and requires a DC exit for proper access.
 	 */
 	switch (dc_state) {
-	case DC_STATE_EN_DC3CO:
+	case DC_STATE_EN_UPTO_DC3CO:
 		ranges = xe3lpd_dc3co_dmc_ranges;
 		break;
 	case DC_STATE_EN_UPTO_DC5:
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 03/19] drm/i915/display: Use FIELD_PREP() for DC state enable bits
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
  2026-03-26 17:15 ` [PATCH 01/19] drm/i915/display: Remove TGL " Dibin Moolakadan Subrahmanian
  2026-03-26 17:15 ` [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with DC_STATE_EN_UPTO_DC3CO Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 20:54   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 04/19] drm/i915/display: Add DC3CO DC_STATE enable/disable support Dibin Moolakadan Subrahmanian
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Replace open-coded shifts with REG_GENMASK() and REG_FIELD_PREP()
for the DC state enable field.

Suggested-by: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_regs.h | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
index d0196d4ad234..2bace331437c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
@@ -3047,11 +3047,12 @@ enum skl_power_gate {
 #define  DC_STATE_DC3CO_STATUS		REG_BIT(29)
 #define  HOLD_PHY_CLKREQ_PG1_LATCH	REG_BIT(21)
 #define  HOLD_PHY_PG1_LATCH		REG_BIT(20)
-#define  DC_STATE_EN_UPTO_DC5		(1 << 0)
 #define  DC_STATE_EN_DC9		(1 << 3)
-#define  DC_STATE_EN_UPTO_DC6		(2 << 0)
-#define  DC_STATE_EN_UPTO_DC3CO		(3 << 0)
-#define  DC_STATE_EN_UPTO_DC5_DC6_MASK   0x3
+#define  DC_STATE_EN_UPTO_DC5_DC6_MASK   REG_GENMASK(1, 0)
+#define  DC_STATE_EN_DISABLE		REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 0)
+#define  DC_STATE_EN_UPTO_DC5		REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 1)
+#define  DC_STATE_EN_UPTO_DC6		REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 2)
+#define  DC_STATE_EN_UPTO_DC3CO	REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 3)
 
 #define  DC_STATE_DEBUG                  _MMIO(0x45520)
 #define  DC_STATE_DEBUG_MASK_CORES	(1 << 0)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 04/19] drm/i915/display: Add DC3CO DC_STATE enable/disable support
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (2 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 03/19] drm/i915/display: Use FIELD_PREP() for DC state enable bits Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:03   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 05/19] drm/i915/display: Validate target DC state against allowed_dc_mask Dibin Moolakadan Subrahmanian
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Add DC3CO handling to the dc_off power well sequencing and disable the
DMC wakelock when exiting DC3CO.

BSpec:75253
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 .../drm/i915/display/intel_display_power_well.c  | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

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 9a948f5e2164..cb3dcd1460b2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -867,6 +867,13 @@ void gen9_set_dc_state(struct intel_display *display, u32 state)
 	power_domains->dc_state = val & mask;
 }
 
+static void xe3lpd_enable_dc3co(struct intel_display *display)
+{
+	drm_dbg_kms(display->drm, "Enabling DC3CO\n");
+	intel_dmc_wl_enable(display, DC_STATE_EN_UPTO_DC3CO);
+	gen9_set_dc_state(display, DC_STATE_EN_UPTO_DC3CO);
+}
+
 static void assert_can_enable_dc5(struct intel_display *display)
 {
 	enum i915_power_well_id high_pg;
@@ -1055,9 +1062,13 @@ void gen9_disable_dc_states(struct intel_display *display)
 	}
 
 	if (old_state == DC_STATE_EN_UPTO_DC5 ||
-	    old_state == DC_STATE_EN_UPTO_DC6)
+	    old_state == DC_STATE_EN_UPTO_DC6 ||
+	    old_state == DC_STATE_EN_UPTO_DC3CO)
 		intel_dmc_wl_disable(display);
 
+	if (old_state == DC_STATE_EN_UPTO_DC3CO)
+		return;
+
 	intel_cdclk_get_cdclk(display, &cdclk_config);
 	/* Can't read out voltage_level so can't use intel_cdclk_changed() */
 	drm_WARN_ON(display->drm,
@@ -1093,6 +1104,9 @@ static void gen9_dc_off_power_well_disable(struct intel_display *display,
 		return;
 
 	switch (power_domains->target_dc_state) {
+	case DC_STATE_EN_UPTO_DC3CO:
+		xe3lpd_enable_dc3co(display);
+		break;
 	case DC_STATE_EN_UPTO_DC6:
 		skl_enable_dc6(display);
 		break;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 05/19] drm/i915/display: Validate target DC state against allowed_dc_mask
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (3 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 04/19] drm/i915/display: Add DC3CO DC_STATE enable/disable support Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:04   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum Dibin Moolakadan Subrahmanian
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Validate the requested target DC state against allowed_dc_mask to
avoid programming unsupported DC states.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_power.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 0afae5c2f62b..12967db27c8d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -302,6 +302,13 @@ void intel_display_power_set_target_dc_state(struct intel_display *display,
 	struct i915_power_domains *power_domains = &display->power.domains;
 
 	mutex_lock(&power_domains->lock);
+
+	if ((state & power_domains->allowed_dc_mask) != state) {
+		drm_dbg_kms(display->drm,
+			    "Rejecting DC state 0x%x (allowed mask 0x%x)\n",
+			     state, power_domains->allowed_dc_mask);
+		goto unlock;
+	}
 	power_well = lookup_power_well(display, SKL_DISP_DC_OFF);
 
 	if (drm_WARN_ON(display->drm, !power_well))
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (4 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 05/19] drm/i915/display: Validate target DC state against allowed_dc_mask Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:16   ` Shankar, Uma
  2026-04-14  7:11   ` Jani Nikula
  2026-03-26 17:15 ` [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support Dibin Moolakadan Subrahmanian
                   ` (12 subsequent siblings)
  18 siblings, 2 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Fix HAS_DC3CO() based on display version and introduce an enum to
track DC3CO enabling triggers.

BSpec: 75253
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 .../gpu/drm/i915/display/intel_display_device.h   |  2 +-
 .../gpu/drm/i915/display/intel_display_power.h    | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index 35e06fcf794d..002fe0ce951a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -189,7 +189,7 @@ struct intel_display_platforms {
 #define HAS_LRR(__display)		(DISPLAY_VER(__display) >= 12)
 #define HAS_LSPCON(__display)		(IS_DISPLAY_VER(__display, 9, 10))
 #define HAS_LT_PHY(__display)		((__display)->platform.novalake)
-#define HAS_DC3CO(__display)		((__display)->platform.novalake)
+#define HAS_DC3CO(__display)		(DISPLAY_VER(__display) >= 35)
 #define HAS_MBUS_JOINING(__display)	((__display)->platform.alderlake_p || DISPLAY_VER(__display) >= 14)
 #define HAS_MSO(__display)		(DISPLAY_VER(__display) >= 12)
 #define HAS_OVERLAY(__display)		(DISPLAY_INFO(__display)->has_overlay)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index d616d5d09cbe..3fb45154864e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -131,6 +131,21 @@ struct intel_power_domain_mask {
 	DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);
 };
 
+/*
+ * DC3CO enabling triggers (bitmask).
+ * DC3CO may be enabled when at least one of these triggers is active.
+ * Additional constraints may still apply.
+ */
+enum intel_dc3co_trigger {
+	DC3CO_TRIGGER_NONE	     = 0,
+	DC3CO_TRIGGER_PSR2	     = BIT(0),
+	DC3CO_TRIGGER_LOBF	     = BIT(1),
+	DC3CO_TRIGGER_PANEL_REPLAY   = BIT(2),
+	DC3CO_TRIGGER_ALL  = DC3CO_TRIGGER_PSR2 |
+			     DC3CO_TRIGGER_LOBF |
+			     DC3CO_TRIGGER_PANEL_REPLAY,
+};
+
 struct i915_power_domains {
 	/*
 	 * Power wells needed for initialization at driver init and suspend
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (5 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:18   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation Dibin Moolakadan Subrahmanian
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Add a helper to query DC3CO support from allowed_dc_mask.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_power.c | 7 +++++++
 drivers/gpu/drm/i915/display/intel_display_power.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 12967db27c8d..a3b0c8ad8bb5 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -365,6 +365,13 @@ u32 intel_display_power_get_current_dc_state(struct intel_display *display)
 	return current_dc_state;
 }
 
+bool intel_display_power_dc3co_supported(struct intel_display *display)
+{
+	struct i915_power_domains *power_domains = &display->power.domains;
+
+	return (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC3CO) == DC_STATE_EN_UPTO_DC3CO;
+}
+
 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 3fb45154864e..f57ce99a6039 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -201,6 +201,7 @@ 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_dc3co_supported(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] 49+ messages in thread

* [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (6 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:42   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 09/19] drm/i915/display: Remove unused PSR dc3co_exitline field Dibin Moolakadan Subrahmanian
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Compute DC3CO eligibility during atomic_check based on
pipe/port constraints and runtime triggers, and propagate
the result via intel_atomic_state.

When DC3CO is allowed, request DC_STATE_EN_UPTO_DC3CO and
reduce the DC entry delay. Otherwise, retain the existing
delay and set default DC_STATE_EN_UPTO_DC6 .

BSpec: 75253
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 98 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_display.h  |  2 +-
 .../drm/i915/display/intel_display_types.h    |  7 ++
 3 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index f20d5ebe06ed..df0eaf6ae76b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5943,6 +5943,81 @@ static bool intel_pipes_need_modeset(struct intel_atomic_state *state,
 	return false;
 }
 
+bool intel_dc3co_allowed(struct intel_atomic_state *state)
+{
+	return state && state->dc3co.allowed;
+}
+
+static bool intel_dc3co_port_pipe_compatible(struct intel_dp *intel_dp,
+					     const struct intel_crtc_state *crtc_state)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+	enum port port = dig_port->base.port;
+	int num_pipes = intel_crtc_num_joined_pipes(crtc_state);
+
+	return num_pipes == 1 && pipe <= PIPE_B && port <= PORT_B;
+}
+
+static void intel_dc3co_compute_state(struct intel_atomic_state *state)
+{
+	struct intel_display *display = to_intel_display(state);
+	struct intel_crtc *crtc;
+	struct intel_crtc_state *crtc_state;
+	struct intel_encoder *encoder;
+	struct intel_dp *intel_dp;
+	int active_pipes = 0;
+	u32 trigger = 0;
+
+	/* disable unless all conditions are met */
+	state->dc3co.trigger = DC3CO_TRIGGER_NONE;
+	state->dc3co.allowed = false;
+
+	if (!HAS_DC3CO(display))
+		return;
+
+	if (state->modeset)
+		return;
+
+	for_each_intel_crtc(display->drm, crtc) {
+		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
+		if (!crtc_state)
+			crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
+
+		if (!crtc_state || !crtc_state->hw.active)
+			continue;
+
+		active_pipes++;
+
+		if (active_pipes > 1)
+			return;
+
+		for_each_intel_encoder_mask(display->drm, encoder,
+					    crtc_state->uapi.encoder_mask) {
+			if (encoder->type != INTEL_OUTPUT_EDP)
+				return;
+
+			intel_dp = enc_to_intel_dp(encoder);
+
+			if (!intel_dc3co_port_pipe_compatible(intel_dp, crtc_state))
+				return;
+		}
+
+		if (crtc_state->has_lobf)
+			trigger |= DC3CO_TRIGGER_LOBF;
+		if (crtc_state->has_panel_replay)
+			trigger |= DC3CO_TRIGGER_PANEL_REPLAY;
+		if (crtc_state->has_sel_update)
+			trigger |= DC3CO_TRIGGER_PSR2;
+	}
+	if (trigger) {
+		state->dc3co.trigger = trigger;
+		state->dc3co.allowed = true;
+	}
+	drm_dbg_kms(display->drm, "DC3CO allowed=%d trigger=0x%x\n",
+		    state->dc3co.allowed, state->dc3co.trigger);
+}
+
 static int intel_atomic_check_joiner(struct intel_atomic_state *state,
 				     struct intel_crtc *primary_crtc)
 {
@@ -6623,6 +6698,7 @@ int intel_atomic_check(struct drm_device *dev,
 	if (ret)
 		goto fail;
 
+	intel_dc3co_compute_state(state);
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
 		intel_color_assert_luts(new_crtc_state);
@@ -7505,6 +7581,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {};
 	struct ref_tracker *wakeref = NULL;
 	int i;
+	int power_async_delay;
 
 	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
 		intel_atomic_dsb_prepare(state, crtc);
@@ -7711,11 +7788,22 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		 */
 		intel_uncore_arm_unclaimed_mmio_detection(uncore);
 	}
-	/*
-	 * Delay re-enabling DC states by 17 ms to avoid the off->on->off
-	 * toggling overhead at and above 60 FPS.
-	 */
-	intel_display_power_put_async_delay(display, POWER_DOMAIN_DC_OFF, wakeref, 17);
+
+	if (intel_dc3co_allowed(state) &&
+	    intel_display_power_dc3co_supported(display)) {
+		intel_display_power_set_target_dc_state(display, DC_STATE_EN_UPTO_DC3CO);
+		power_async_delay = 1;
+	} else {
+		/*
+		 * Delay re-enabling DC states by 17 ms to avoid the off->on->off
+		 * toggling overhead at and above 60 FPS.
+		 */
+		intel_display_power_set_target_dc_state(display, DC_STATE_EN_UPTO_DC6);
+		power_async_delay = 17;
+	}
+	intel_display_power_put_async_delay(display,
+					    POWER_DOMAIN_DC_OFF, wakeref, power_async_delay);
+
 	intel_display_rpm_put(display, state->wakeref);
 
 	/*
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 552a59d19e0f..6eb84f9d8791 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -535,5 +535,5 @@ bool assert_port_valid(struct intel_display *display, enum port port);
 
 bool intel_scanout_needs_vtd_wa(struct intel_display *display);
 int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state);
-
+bool intel_dc3co_allowed(struct intel_atomic_state *state);
 #endif
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 6830f911d94d..6c7f5bbbc821 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -632,6 +632,11 @@ struct dpll {
 	int	p;
 };
 
+struct intel_dc3co_state {
+	bool allowed; /* DC3CO eligibility result */
+	u32 trigger; /* Bitmask of active DC3CO triggers */
+};
+
 struct intel_atomic_state {
 	struct drm_atomic_state base;
 
@@ -658,6 +663,8 @@ struct intel_atomic_state {
 	bool rps_interactive;
 
 	struct work_struct cleanup_work;
+
+	struct intel_dc3co_state dc3co;
 };
 
 struct intel_plane_state {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 09/19] drm/i915/display: Remove unused PSR dc3co_exitline field
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (7 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-03-26 17:15 ` [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state Dibin Moolakadan Subrahmanian
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Remove dc3co_exitline from struct intel_psr as it is unused.
Keep dc3co_exit_delay for use in subsequent patches.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_types.h | 1 -
 drivers/gpu/drm/i915/display/intel_psr.c           | 1 -
 2 files changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 6c7f5bbbc821..60366087038f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1789,7 +1789,6 @@ struct intel_psr {
 	bool source_panel_replay_support;
 	bool sink_panel_replay_support;
 	bool panel_replay_enabled;
-	u32 dc3co_exitline;
 	u32 dc3co_exit_delay;
 	u8 entry_setup_frames;
 
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 29900576e117..40adbd1c8ddc 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2050,7 +2050,6 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
 	/* DC5/DC6 requires at least 6 idle frames */
 	val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
 	intel_dp->psr.dc3co_exit_delay = val;
-	intel_dp->psr.dc3co_exitline = crtc_state->dc3co_exitline;
 	intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
 	intel_dp->psr.su_region_et_enabled = crtc_state->enable_psr2_su_region_et;
 	intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (8 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 09/19] drm/i915/display: Remove unused PSR dc3co_exitline field Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:44   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 11/19] drm/i915/display: Store DC3CO eligibility in PSR state Dibin Moolakadan Subrahmanian
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Remove dc3co_exitline from struct intel_crtc_state, as it is not
used anywhere in the driver.

Also remove the corresponding register read in intel_psr_get_config().

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_types.h | 1 -
 drivers/gpu/drm/i915/display/intel_psr.c           | 1 -
 2 files changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 60366087038f..0a327c4df98d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1192,7 +1192,6 @@ struct intel_crtc_state {
 	bool pkg_c_latency_used;
 	/* Only used for state verification. */
 	enum intel_panel_replay_dsc_support panel_replay_dsc_support;
-	u32 dc3co_exitline;
 	u16 su_y_granularity;
 	u8 active_non_psr_pipes;
 	const char *no_psr_reason;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 40adbd1c8ddc..987d49536548 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1822,7 +1822,6 @@ void intel_psr_get_config(struct intel_encoder *encoder,
 	if (DISPLAY_VER(display) >= 12) {
 		val = intel_de_read(display,
 				    TRANS_EXITLINE(display, cpu_transcoder));
-		pipe_config->dc3co_exitline = REG_FIELD_GET(EXITLINE_MASK, val);
 	}
 unlock:
 	mutex_unlock(&intel_dp->psr.lock);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 11/19] drm/i915/display: Store DC3CO eligibility in PSR state
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (9 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:54   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO Dibin Moolakadan Subrahmanian
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Store DC3CO eligibility in intel_dp->psr during
intel_psr_post_plane_update() so PSR configuration
can take DC3CO into account.

This will be used to control PSR2 parameters such as idle frames

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++
 drivers/gpu/drm/i915/display/intel_psr.c           | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 0a327c4df98d..d0d2cda3d669 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1783,6 +1783,8 @@ struct intel_psr {
 	ktime_t last_exit;
 	bool sink_not_reliable;
 	bool irq_aux_error;
+	/* DC3CO eligibility used to control PSR configuration */
+	bool dc3co_eligible;
 	u16 su_w_granularity;
 	u16 su_y_granularity;
 	bool source_panel_replay_support;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 987d49536548..bab254700a62 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2239,6 +2239,8 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
 	intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
 	intel_dp->psr.active_non_psr_pipes = 0;
 	intel_dp->psr.pkg_c_latency_used = 0;
+	intel_dp->psr.dc3co_eligible = false;
+
 }
 
 /**
@@ -3061,6 +3063,9 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state,
 		 */
 		intel_dp->psr.busy_frontbuffer_bits = 0;
 
+		intel_dp->psr.dc3co_eligible = intel_dc3co_allowed(state) &&
+			intel_display_power_dc3co_supported(display);
+
 		mutex_unlock(&psr->lock);
 	}
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (10 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 11/19] drm/i915/display: Store DC3CO eligibility in PSR state Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:56   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 13/19] drm/i915/display: Define DC3CO idle protocol bit in PR_ALPM_CTL Dibin Moolakadan Subrahmanian
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Force idle_frames to 0 when DC3CO is eligible.

BSpec: 75253
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index bab254700a62..16a9f4111ac8 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1040,10 +1040,13 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 	u32 psr_val = 0;
 	u8 idle_frames;
 
+	/* DC3CO requires idle_frames = 0 */
+	if (intel_dp->psr.dc3co_eligible)
+		idle_frames = 0;
 	/* Wa_16025596647 */
-	if ((DISPLAY_VER(display) == 20 ||
-	     IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
-	    is_dc5_dc6_blocked(intel_dp) && intel_dp->psr.pkg_c_latency_used)
+	else if ((DISPLAY_VER(display) == 20 ||
+		  IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
+		 is_dc5_dc6_blocked(intel_dp) && intel_dp->psr.pkg_c_latency_used)
 		idle_frames = 0;
 	else
 		idle_frames = psr_compute_idle_frames(intel_dp);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 13/19] drm/i915/display: Define DC3CO idle protocol bit in PR_ALPM_CTL
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (11 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-03-26 17:15 ` [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM Dibin Moolakadan Subrahmanian
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Add PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL bit definition.

BSpec: 75253
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr_regs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h
index 8afbf5a38335..16a9e3af198d 100644
--- a/drivers/gpu/drm/i915/display/intel_psr_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h
@@ -268,6 +268,7 @@
 
 #define _PR_ALPM_CTL_A	0x60948
 #define PR_ALPM_CTL(dev_priv, tran)	_MMIO_TRANS2(dev_priv, tran, _PR_ALPM_CTL_A)
+#define  PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL			BIT(7)
 #define  PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU	BIT(6)
 #define  PR_ALPM_CTL_RFB_UPDATE_CONTROL				BIT(5)
 #define  PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE	BIT(4)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (12 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 13/19] drm/i915/display: Define DC3CO idle protocol bit in PR_ALPM_CTL Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 21:58   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO Dibin Moolakadan Subrahmanian
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Set PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL when DC3CO is
allowed.

BSpec: 75253
Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_alpm.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
index a7350ce8e716..9f92513a23c0 100644
--- a/drivers/gpu/drm/i915/display/intel_alpm.c
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -365,6 +365,9 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
 	struct intel_display *display = to_intel_display(intel_dp);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 alpm_ctl;
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(crtc_state->uapi.state);
+
 
 	if (DISPLAY_VER(display) < 20 || (!intel_psr_needs_alpm(intel_dp, crtc_state) &&
 					  !crtc_state->has_lobf))
@@ -389,6 +392,12 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
 			if (crtc_state->disable_as_sdp_when_pr_active)
 				pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
 
+			if (intel_dc3co_allowed(state) &&
+			    intel_display_power_dc3co_supported(display))
+				pr_alpm_ctl |= PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
+			else
+				pr_alpm_ctl &= ~PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
+
 			intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder),
 				       pr_alpm_ctl);
 		}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (13 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 22:11   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 16/19] drm/i915/display: Add helper to enable DC counter Dibin Moolakadan Subrahmanian
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

For DC3CO, idle_frames is programmed to 0, so PSR does not
enter deep sleep. Add delayed work to schedule DC3CO exit
after an idle duration derived from frame time (minimum
equivalent of 6 frames).

The work is re-armed from the PSR flush path on relevant
frontbuffer activity, and once the display remains idle,
DC3CO is disabled and DC6 is enabled to allow deeper power
savings.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  2 +
 drivers/gpu/drm/i915/display/intel_psr.c      | 48 +++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index d0d2cda3d669..0c8958338f76 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1785,6 +1785,8 @@ struct intel_psr {
 	bool irq_aux_error;
 	/* DC3CO eligibility used to control PSR configuration */
 	bool dc3co_eligible;
+	/* DC3CO disable work*/
+	struct delayed_work dc3co_work;
 	u16 su_w_granularity;
 	u16 su_y_granularity;
 	bool source_panel_replay_support;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 16a9f4111ac8..f3476118b8d0 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1701,6 +1701,50 @@ static bool intel_psr_needs_wa_18037818876(struct intel_dp *intel_dp,
 		!crtc_state->has_sel_update);
 }
 
+static void psr2_dc3co_disable_locked(struct intel_dp *intel_dp)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+
+	if (intel_dp->psr.dc3co_eligible) {
+		intel_dp->psr.dc3co_eligible = false;
+		intel_display_power_set_target_dc_state(display, DC_STATE_EN_UPTO_DC6);
+	}
+}
+
+static void psr2_dc3co_disable_work(struct work_struct *work)
+{
+	struct intel_dp *intel_dp =
+		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
+
+	mutex_lock(&intel_dp->psr.lock);
+	psr2_dc3co_disable_locked(intel_dp);
+	mutex_unlock(&intel_dp->psr.lock);
+}
+
+static void
+psr2_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
+			enum fb_op_origin origin)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+
+	if (!intel_dp->psr.dc3co_eligible)
+		return;
+
+	if (!intel_dp->psr.sel_update_enabled ||
+	    !intel_dp->psr.active)
+		return;
+	/*
+	 * At every frontbuffer flush flip event modified delay of delayed work,
+	 * when delayed work schedules that means display has been idle.
+	 */
+	if (!(frontbuffer_bits &
+	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
+		return;
+
+	mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work,
+			 intel_dp->psr.dc3co_exit_delay);
+}
+
 static
 void intel_psr_set_non_psr_pipes(struct intel_dp *intel_dp,
 				 struct intel_crtc_state *crtc_state)
@@ -2273,6 +2317,7 @@ void intel_psr_disable(struct intel_dp *intel_dp,
 
 	mutex_unlock(&intel_dp->psr.lock);
 	cancel_work_sync(&intel_dp->psr.work);
+	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
 }
 
 /**
@@ -2303,6 +2348,7 @@ void intel_psr_pause(struct intel_dp *intel_dp)
 	mutex_unlock(&psr->lock);
 
 	cancel_work_sync(&psr->work);
+	cancel_delayed_work_sync(&psr->dc3co_work);
 }
 
 /**
@@ -3527,6 +3573,7 @@ void intel_psr_flush(struct intel_display *display,
 		if (origin == ORIGIN_FLIP ||
 		    (origin == ORIGIN_CURSOR_UPDATE &&
 		     !intel_dp->psr.psr2_sel_fetch_enabled)) {
+			psr2_dc3co_flush_locked(intel_dp, frontbuffer_bits, origin);
 			goto unlock;
 		}
 
@@ -3585,6 +3632,7 @@ void intel_psr_init(struct intel_dp *intel_dp)
 		intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link;
 
 	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
+	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, psr2_dc3co_disable_work);
 	mutex_init(&intel_dp->psr.lock);
 }
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 16/19] drm/i915/display: Add helper to enable DC counter
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (14 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 22:14   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 17/19] drm/i915/display: Remove DC3CO DMC debugfs Dibin Moolakadan Subrahmanian
                   ` (2 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Add xe3lpd_enable_dc_count() to enable the DC_COUNT_EN register.
Also define DC_STATE_DC3CO_RESIDENCY to read DC3CO residency.
Needed to retrieve DC residency for DC3CO.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_power_well.c | 5 +++++
 drivers/gpu/drm/i915/display/intel_display_power_well.h | 1 +
 drivers/gpu/drm/i915/display/intel_display_regs.h       | 5 +++++
 drivers/gpu/drm/i915/display/intel_dmc.c                | 3 +++
 4 files changed, 14 insertions(+)

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 cb3dcd1460b2..15521442e6d4 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -867,6 +867,11 @@ void gen9_set_dc_state(struct intel_display *display, u32 state)
 	power_domains->dc_state = val & mask;
 }
 
+void xe3lpd_enable_dc_count(struct intel_display *display)
+{
+	intel_de_write(display, DC_COUNT_EN, DC_COUNT_EN_COUNTER_ENABLE);
+}
+
 static void xe3lpd_enable_dc3co(struct intel_display *display)
 {
 	drm_dbg_kms(display->drm, "Enabling DC3CO\n");
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.h b/drivers/gpu/drm/i915/display/intel_display_power_well.h
index 8f5524da2d06..0ce64b894436 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.h
@@ -159,6 +159,7 @@ void gen9_set_dc_state(struct intel_display *display, u32 state);
 void gen9_disable_dc_states(struct intel_display *display);
 void bxt_enable_dc9(struct intel_display *display);
 void bxt_disable_dc9(struct intel_display *display);
+void xe3lpd_enable_dc_count(struct intel_display *display);
 
 extern const struct i915_power_well_ops i9xx_always_on_power_well_ops;
 extern const struct i915_power_well_ops chv_pipe_power_well_ops;
diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
index 2bace331437c..8b59e1ff2590 100644
--- a/drivers/gpu/drm/i915/display/intel_display_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
@@ -3058,6 +3058,11 @@ enum skl_power_gate {
 #define  DC_STATE_DEBUG_MASK_CORES	(1 << 0)
 #define  DC_STATE_DEBUG_MASK_MEMORY_UP	(1 << 1)
 
+#define DC_COUNT_EN			_MMIO(0x457B4)
+#define DC_COUNT_EN_COUNTER_ENABLE	REG_BIT(31)
+
+#define DC_STATE_DC3CO_RESIDENCY	_MMIO(0x457B8)
+
 #define D_COMP_BDW			_MMIO(0x138144)
 
 /* Pipe WM_LINETIME - watermark line time */
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 90ba932d940a..74d18806d01f 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -937,6 +937,9 @@ void intel_dmc_load_program(struct intel_display *display)
 
 	gen9_set_dc_state_debugmask(display);
 
+	if (DISPLAY_VER(display) >= 35)
+		xe3lpd_enable_dc_count(display);
+
 	pipedmc_clock_gating_wa(display, false);
 }
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 17/19] drm/i915/display: Remove DC3CO DMC debugfs
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (15 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 16/19] drm/i915/display: Add helper to enable DC counter Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 22:17   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 18/19] drm/i915/display: Add DC3CO count and residency in dmc debugfs Dibin Moolakadan Subrahmanian
  2026-03-26 17:15 ` [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from DC3CO Dibin Moolakadan Subrahmanian
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

DC3CO is not enabled on TGL and DG1. Remove the debugfs entry for
DC3CO counts. A new debugfs entry for Xe3LP will be added in a
subsequent patch.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dmc.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 74d18806d01f..f0ebdab089ca 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -1645,19 +1645,13 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
 		   DMC_VERSION_MINOR(dmc->version));
 
 	if (DISPLAY_VER(display) >= 12) {
-		i915_reg_t dc3co_reg;
-
 		if (display->platform.dgfx || DISPLAY_VER(display) >= 14) {
-			dc3co_reg = DG1_DMC_DEBUG3;
 			dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
 		} else {
-			dc3co_reg = TGL_DMC_DEBUG3;
 			dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
 			dc6_reg = TGL_DMC_DEBUG_DC6_COUNT;
 		}
 
-		seq_printf(m, "DC3CO count: %d\n",
-			   intel_de_read(display, dc3co_reg));
 	} else {
 		dc5_reg = display->platform.broxton ? BXT_DMC_DC3_DC5_COUNT :
 			SKL_DMC_DC3_DC5_COUNT;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 18/19] drm/i915/display: Add DC3CO count and residency in dmc debugfs
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (16 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 17/19] drm/i915/display: Remove DC3CO DMC debugfs Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 22:19   ` Shankar, Uma
  2026-03-26 17:15 ` [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from DC3CO Dibin Moolakadan Subrahmanian
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

Expose DC3CO count and residency for xe3lp platforms via debugfs.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dmc.c      | 8 +++++++-
 drivers/gpu/drm/i915/display/intel_dmc_regs.h | 2 ++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index f0ebdab089ca..6f24ee620f2e 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -1645,7 +1645,13 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
 		   DMC_VERSION_MINOR(dmc->version));
 
 	if (DISPLAY_VER(display) >= 12) {
-		if (display->platform.dgfx || DISPLAY_VER(display) >= 14) {
+		if (DISPLAY_VER(display) >= 35) {
+			seq_printf(m, "DC3CO count: %d\n",
+				   intel_de_read(display, XE3P_DMC_DC3CO_COUNT));
+
+			seq_printf(m, "DC3CO residency: %d\n",
+				   intel_de_read(display, DC_STATE_DC3CO_RESIDENCY));
+		} else if (display->platform.dgfx || DISPLAY_VER(display) >= 14) {
 			dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
 		} else {
 			dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
index 38e342b45af0..1998549b6318 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
@@ -531,6 +531,8 @@ enum pipedmc_event_id {
 #define TGL_DMC_DEBUG3		_MMIO(0x101090)
 #define DG1_DMC_DEBUG3		_MMIO(0x13415c)
 
+#define XE3P_DMC_DC3CO_COUNT	_MMIO(0x8f05C)
+
 #define DMC_WAKELOCK_CFG	_MMIO(0x8F1B0)
 #define  DMC_WAKELOCK_CFG_ENABLE REG_BIT(31)
 #define DMC_WAKELOCK1_CTL	_MMIO(0x8F140)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from DC3CO
  2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
                   ` (17 preceding siblings ...)
  2026-03-26 17:15 ` [PATCH 18/19] drm/i915/display: Add DC3CO count and residency in dmc debugfs Dibin Moolakadan Subrahmanian
@ 2026-03-26 17:15 ` Dibin Moolakadan Subrahmanian
  2026-04-13 22:21   ` Shankar, Uma
  18 siblings, 1 reply; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-03-26 17:15 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

After 6 idle frames, DC3CO is exited and DC6 is enabled.
Reprogram idle frames so that the deeper states can be entered.

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index f3476118b8d0..dcf33359dc9c 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1708,6 +1708,7 @@ static void psr2_dc3co_disable_locked(struct intel_dp *intel_dp)
 	if (intel_dp->psr.dc3co_eligible) {
 		intel_dp->psr.dc3co_eligible = false;
 		intel_display_power_set_target_dc_state(display, DC_STATE_EN_UPTO_DC6);
+		psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp));
 	}
 }
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* RE: [PATCH 01/19] drm/i915/display: Remove TGL DC3CO support
  2026-03-26 17:15 ` [PATCH 01/19] drm/i915/display: Remove TGL " Dibin Moolakadan Subrahmanian
@ 2026-04-13 20:40   ` Shankar, Uma
  2026-04-20 12:01     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 20:40 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 01/19] drm/i915/display: Remove TGL DC3CO support
> 
> Remove all Tiger Lake DC3CO-related functions, as the feature is not enabled and
> not used. The existing structure members are intentionally left in place and will be
> cleaned up in subsequent patches.
> 
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  .../i915/display/intel_display_power_well.c   |  25 ---
>  .../drm/i915/display/intel_display_types.h    |   1 -
>  drivers/gpu/drm/i915/display/intel_psr.c      | 163 ------------------
>  3 files changed, 189 deletions(-)
> 
> 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 f855f0f88694..6d5f07f7f590 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> @@ -867,23 +867,6 @@ void gen9_set_dc_state(struct intel_display *display,
> u32 state)
>  	power_domains->dc_state = val & mask;
>  }
> 
> -static void tgl_enable_dc3co(struct intel_display *display) -{
> -	drm_dbg_kms(display->drm, "Enabling DC3CO\n");
> -	gen9_set_dc_state(display, DC_STATE_EN_DC3CO);
> -}
> -
> -static void tgl_disable_dc3co(struct intel_display *display) -{
> -	drm_dbg_kms(display->drm, "Disabling DC3CO\n");
> -	intel_de_rmw(display, DC_STATE_EN, DC_STATE_DC3CO_STATUS, 0);
> -	gen9_set_dc_state(display, DC_STATE_DISABLE);
> -	/*
> -	 * Delay of 200us DC3CO Exit time B.Spec 49196
> -	 */
> -	usleep_range(200, 210);
> -}
> -
>  static void assert_can_enable_dc5(struct intel_display *display)  {
>  	enum i915_power_well_id high_pg;
> @@ -1062,11 +1045,6 @@ void gen9_disable_dc_states(struct intel_display
> *display)
>  	struct intel_cdclk_config cdclk_config = {};
>  	u32 old_state = power_domains->dc_state;
> 
> -	if (power_domains->target_dc_state == DC_STATE_EN_DC3CO) {
> -		tgl_disable_dc3co(display);
> -		return;
> -	}
> -
>  	if (HAS_DISPLAY(display)) {
>  		intel_dmc_wl_get_noreg(display);
>  		gen9_set_dc_state(display, DC_STATE_DISABLE); @@ -1115,9
> +1093,6 @@ static void gen9_dc_off_power_well_disable(struct intel_display
> *display,
>  		return;
> 
>  	switch (power_domains->target_dc_state) {
> -	case DC_STATE_EN_DC3CO:
> -		tgl_enable_dc3co(display);
> -		break;
>  	case DC_STATE_EN_UPTO_DC6:
>  		skl_enable_dc6(display);
>  		break;
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index b4c3d8537a99..6830f911d94d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1784,7 +1784,6 @@ struct intel_psr {
>  	bool panel_replay_enabled;
>  	u32 dc3co_exitline;
>  	u32 dc3co_exit_delay;
> -	struct delayed_work dc3co_work;
>  	u8 entry_setup_frames;
> 
>  	u8 io_wake_lines;
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 5041a5a138d1..29900576e117 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -85,22 +85,6 @@
>   * issues the self-refresh re-enable code is done from a work queue, which
>   * must be correctly synchronized/cancelled when shutting down the pipe."
>   *
> - * DC3CO (DC3 clock off)
> - *
> - * On top of PSR2, GEN12 adds a intermediate power savings state that turns
> - * clock off automatically during PSR2 idle state.
> - * The smaller overhead of DC3co entry/exit vs. the overhead of PSR2 deep
> sleep
> - * entry/exit allows the HW to enter a low-power state even when page flipping
> - * periodically (for instance a 30fps video playback scenario).
> - *
> - * Every time a flips occurs PSR2 will get out of deep sleep state(if it was),
> - * so DC3CO is enabled and tgl_dc3co_disable_work is schedule to run after 6
> - * frames, if no other flip occurs and the function above is executed, DC3CO is
> - * disabled and PSR2 is configured to enter deep sleep, resetting again in case
> - * of another flip.
> - * Front buffer modifications do not trigger DC3CO activation on purpose as it
> - * would bring a lot of complexity and most of the moderns systems will only
> - * use page flips.
>   */
> 
>  /*
> @@ -1178,108 +1162,6 @@ static void psr2_program_idle_frames(struct intel_dp
> *intel_dp,
>  		     EDP_PSR2_IDLE_FRAMES(idle_frames));
>  }
> 
> -static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp) -{
> -	struct intel_display *display = to_intel_display(intel_dp);
> -
> -	psr2_program_idle_frames(intel_dp, 0);
> -	intel_display_power_set_target_dc_state(display,
> DC_STATE_EN_DC3CO);
> -}
> -
> -static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp) -{
> -	struct intel_display *display = to_intel_display(intel_dp);
> -
> -	intel_display_power_set_target_dc_state(display,
> DC_STATE_EN_UPTO_DC6);
> -	psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp));
> -}
> -
> -static void tgl_dc3co_disable_work(struct work_struct *work) -{
> -	struct intel_dp *intel_dp =
> -		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
> -
> -	mutex_lock(&intel_dp->psr.lock);
> -	/* If delayed work is pending, it is not idle */
> -	if (delayed_work_pending(&intel_dp->psr.dc3co_work))
> -		goto unlock;
> -
> -	tgl_psr2_disable_dc3co(intel_dp);
> -unlock:
> -	mutex_unlock(&intel_dp->psr.lock);
> -}
> -
> -static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp) -{
> -	if (!intel_dp->psr.dc3co_exitline)
> -		return;
> -
> -	cancel_delayed_work(&intel_dp->psr.dc3co_work);
> -	/* Before PSR2 exit disallow dc3co*/
> -	tgl_psr2_disable_dc3co(intel_dp);
> -}
> -
> -static bool
> -dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp,
> -			      struct intel_crtc_state *crtc_state)
> -{
> -	struct intel_display *display = to_intel_display(intel_dp);
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> -	enum port port = dig_port->base.port;
> -
> -	if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14)
> -		return pipe <= PIPE_B && port <= PORT_B;
> -	else
> -		return pipe == PIPE_A && port == PORT_A;
> -}
> -
> -static void
> -tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
> -				  struct intel_crtc_state *crtc_state)
> -{
> -	struct intel_display *display = to_intel_display(intel_dp);
> -	const u32 crtc_vdisplay = crtc_state->uapi.adjusted_mode.crtc_vdisplay;
> -	struct i915_power_domains *power_domains = &display->power.domains;
> -	u32 exit_scanlines;
> -
> -	/*
> -	 * FIXME: Due to the changed sequence of activating/deactivating
> DC3CO,
> -	 * disable DC3CO until the changed dc3co activating/deactivating
> sequence
> -	 * is applied. B.Specs:49196
> -	 */
> -	return;
> -
> -	/*
> -	 * DMC's DC3CO exit mechanism has an issue with Selective Fecth
> -	 * TODO: when the issue is addressed, this restriction should be removed.
> -	 */
> -	if (crtc_state->enable_psr2_sel_fetch)
> -		return;
> -
> -	if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC3CO))
> -		return;
> -
> -	if (!dc3co_is_pipe_port_compatible(intel_dp, crtc_state))
> -		return;
> -
> -	/* Wa_16011303918:adl-p */
> -	if (intel_display_wa(display, INTEL_DISPLAY_WA_16011303918))
> -		return;
> -
> -	/*
> -	 * DC3CO Exit time 200us B.Spec 49196
> -	 * PSR2 transcoder Early Exit scanlines = ROUNDUP(200 / line time) + 1
> -	 */
> -	exit_scanlines =
> -		intel_usecs_to_scanlines(&crtc_state->uapi.adjusted_mode, 200)
> + 1;
> -
> -	if (drm_WARN_ON(display->drm, exit_scanlines > crtc_vdisplay))
> -		return;
> -
> -	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
> -}
> -
>  static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
>  					      struct intel_crtc_state *crtc_state)  {
> @@ -1622,8 +1504,6 @@ static bool intel_psr2_config_valid(struct intel_dp
> *intel_dp,
>  		return false;
>  	}
> 
> -	tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
> -
>  	return true;
>  }
> 
> @@ -2071,16 +1951,6 @@ static void intel_psr_enable_source(struct intel_dp
> *intel_dp,
> 
>  	psr_irq_control(intel_dp);
> 
> -	/*
> -	 * TODO: if future platforms supports DC3CO in more than one
> -	 * transcoder, EXITLINE will need to be unset when disabling PSR
> -	 */
> -	if (intel_dp->psr.dc3co_exitline)
> -		intel_de_rmw(display,
> -			     TRANS_EXITLINE(display, cpu_transcoder),
> -			     EXITLINE_MASK,
> -			     intel_dp->psr.dc3co_exitline << EXITLINE_SHIFT |
> EXITLINE_ENABLE);
> -
>  	if (HAS_PSR_HW_TRACKING(display) &&
> HAS_PSR2_SEL_FETCH(display))
>  		intel_de_rmw(display, CHICKEN_PAR1_1,
> IGNORE_PSR2_HW_TRACKING,
>  			     intel_dp->psr.psr2_sel_fetch_enabled ?
> @@ -2258,7 +2128,6 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
>  		intel_de_rmw(display, TRANS_DP2_CTL(intel_dp-
> >psr.transcoder),
>  			     TRANS_DP2_PANEL_REPLAY_ENABLE, 0);
>  	} else if (intel_dp->psr.sel_update_enabled) {
> -		tgl_disallow_dc3co_on_psr2_exit(intel_dp);
> 

Nit: This leaves a blank line

With above fixed, this is
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

>  		val = intel_de_rmw(display,
>  				   EDP_PSR2_CTL(display, cpu_transcoder), @@
> -2401,7 +2270,6 @@ void intel_psr_disable(struct intel_dp *intel_dp,
> 
>  	mutex_unlock(&intel_dp->psr.lock);
>  	cancel_work_sync(&intel_dp->psr.work);
> -	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
>  }
> 
>  /**
> @@ -2432,7 +2300,6 @@ void intel_psr_pause(struct intel_dp *intel_dp)
>  	mutex_unlock(&psr->lock);
> 
>  	cancel_work_sync(&psr->work);
> -	cancel_delayed_work_sync(&psr->dc3co_work);
>  }
> 
>  /**
> @@ -3568,34 +3435,6 @@ void intel_psr_invalidate(struct intel_display *display,
>  		mutex_unlock(&intel_dp->psr.lock);
>  	}
>  }
> -/*
> - * When we will be completely rely on PSR2 S/W tracking in future,
> - * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP
> - * event also therefore tgl_dc3co_flush_locked() require to be changed
> - * accordingly in future.
> - */
> -static void
> -tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
> -		       enum fb_op_origin origin)
> -{
> -	struct intel_display *display = to_intel_display(intel_dp);
> -
> -	if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.sel_update_enabled ||
> -	    !intel_dp->psr.active)
> -		return;
> -
> -	/*
> -	 * At every frontbuffer flush flip event modified delay of delayed work,
> -	 * when delayed work schedules that means display has been idle.
> -	 */
> -	if (!(frontbuffer_bits &
> -	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
> -		return;
> -
> -	tgl_psr2_enable_dc3co(intel_dp);
> -	mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work,
> -			 intel_dp->psr.dc3co_exit_delay);
> -}
> 
>  static void _psr_flush_handle(struct intel_dp *intel_dp)  { @@ -3682,7 +3521,6
> @@ void intel_psr_flush(struct intel_display *display,
>  		if (origin == ORIGIN_FLIP ||
>  		    (origin == ORIGIN_CURSOR_UPDATE &&
>  		     !intel_dp->psr.psr2_sel_fetch_enabled)) {
> -			tgl_dc3co_flush_locked(intel_dp, frontbuffer_bits, origin);
>  			goto unlock;
>  		}
> 
> @@ -3741,7 +3579,6 @@ void intel_psr_init(struct intel_dp *intel_dp)
>  		intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link;
> 
>  	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
> -	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work,
> tgl_dc3co_disable_work);
>  	mutex_init(&intel_dp->psr.lock);
>  }
> 
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with DC_STATE_EN_UPTO_DC3CO
  2026-03-26 17:15 ` [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with DC_STATE_EN_UPTO_DC3CO Dibin Moolakadan Subrahmanian
@ 2026-04-13 20:51   ` Shankar, Uma
  2026-04-20 12:04     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 20:51 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with
> DC_STATE_EN_UPTO_DC3CO

Nit: Patch header can be re-phrased "Switch DC3Co enable from standalone bit to DC level encoding"

Changes look Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> On platforms prior to xe3, DC3CO was controlled via a standalone enable bit.
> Starting with xe3 DC3CO is encoded as part of the existing
> DC_STATE_EN_UPTO_DC* field.
> 
> No functional change, as DC3CO is not enabled on platforms prior to xe3.
> 
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_power.c      | 6 +++---
>  drivers/gpu/drm/i915/display/intel_display_power_well.c | 4 ++--
>  drivers/gpu/drm/i915/display/intel_display_regs.h       | 2 +-
>  drivers/gpu/drm/i915/display/intel_dmc_wl.c             | 2 +-
>  4 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
> b/drivers/gpu/drm/i915/display/intel_display_power.c
> index ec96b141c74c..0afae5c2f62b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> @@ -267,7 +267,7 @@ sanitize_target_dc_state(struct intel_display *display,
>  	static const u32 states[] = {
>  		DC_STATE_EN_UPTO_DC6,
>  		DC_STATE_EN_UPTO_DC5,
> -		DC_STATE_EN_DC3CO,
> +		DC_STATE_EN_UPTO_DC3CO,
>  		DC_STATE_DISABLE,
>  	};
>  	int i;
> @@ -999,10 +999,10 @@ static u32 get_allowed_dc_mask(struct intel_display
> *display, int enable_dc)
> 
>  	switch (requested_dc) {
>  	case 4:
> -		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6;
> +		mask |= DC_STATE_EN_UPTO_DC3CO |
> DC_STATE_EN_UPTO_DC6;
>  		break;
>  	case 3:
> -		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC5;
> +		mask |= DC_STATE_EN_UPTO_DC3CO |
> DC_STATE_EN_UPTO_DC5;
>  		break;
>  	case 2:
>  		mask |= DC_STATE_EN_UPTO_DC6;
> 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 6d5f07f7f590..9a948f5e2164 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> @@ -773,7 +773,7 @@ static u32 gen9_dc_mask(struct intel_display *display)
>  	mask = DC_STATE_EN_UPTO_DC5;
> 
>  	if (DISPLAY_VER(display) >= 12)
> -		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6
> +		mask |= DC_STATE_EN_UPTO_DC3CO |
> DC_STATE_EN_UPTO_DC6
>  					  | DC_STATE_EN_DC9;
>  	else if (DISPLAY_VER(display) == 11)
>  		mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9;
> @@ -1023,7 +1023,7 @@ static void bxt_verify_dpio_phy_power_wells(struct
> intel_display *display)  static bool gen9_dc_off_power_well_enabled(struct
> intel_display *display,
>  					   struct i915_power_well *power_well)  {
> -	return ((intel_de_read(display, DC_STATE_EN) &
> DC_STATE_EN_DC3CO) == 0 &&
> +	return ((intel_de_read(display, DC_STATE_EN) &
> DC_STATE_EN_UPTO_DC3CO)
> +== 0 &&
>  		(intel_de_read(display, DC_STATE_EN) &
> DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0);  }
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h
> b/drivers/gpu/drm/i915/display/intel_display_regs.h
> index 5838338f495a..d0196d4ad234 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
> @@ -3044,13 +3044,13 @@ enum skl_power_gate {
>  /* GEN9 DC */
>  #define DC_STATE_EN			_MMIO(0x45504)
>  #define  DC_STATE_DISABLE		0
> -#define  DC_STATE_EN_DC3CO		REG_BIT(30)
>  #define  DC_STATE_DC3CO_STATUS		REG_BIT(29)
>  #define  HOLD_PHY_CLKREQ_PG1_LATCH	REG_BIT(21)
>  #define  HOLD_PHY_PG1_LATCH		REG_BIT(20)
>  #define  DC_STATE_EN_UPTO_DC5		(1 << 0)
>  #define  DC_STATE_EN_DC9		(1 << 3)
>  #define  DC_STATE_EN_UPTO_DC6		(2 << 0)
> +#define  DC_STATE_EN_UPTO_DC3CO		(3 << 0)
>  #define  DC_STATE_EN_UPTO_DC5_DC6_MASK   0x3
> 
>  #define  DC_STATE_DEBUG                  _MMIO(0x45520)
> diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c
> b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
> index 73a3101514f3..9f403b7820ab 100644
> --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c
> +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
> @@ -260,7 +260,7 @@ static bool intel_dmc_wl_check_range(struct intel_display
> *display,
>  	 * the DMC and requires a DC exit for proper access.
>  	 */
>  	switch (dc_state) {
> -	case DC_STATE_EN_DC3CO:
> +	case DC_STATE_EN_UPTO_DC3CO:
>  		ranges = xe3lpd_dc3co_dmc_ranges;
>  		break;
>  	case DC_STATE_EN_UPTO_DC5:
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 03/19] drm/i915/display: Use FIELD_PREP() for DC state enable bits
  2026-03-26 17:15 ` [PATCH 03/19] drm/i915/display: Use FIELD_PREP() for DC state enable bits Dibin Moolakadan Subrahmanian
@ 2026-04-13 20:54   ` Shankar, Uma
  0 siblings, 0 replies; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 20:54 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 03/19] drm/i915/display: Use FIELD_PREP() for DC state enable
> bits
> 
> Replace open-coded shifts with REG_GENMASK() and REG_FIELD_PREP() for
> the DC state enable field.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Suggested-by: Jani Nikula <jani.nikula@linux.intel.com>
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_regs.h | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h
> b/drivers/gpu/drm/i915/display/intel_display_regs.h
> index d0196d4ad234..2bace331437c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
> @@ -3047,11 +3047,12 @@ enum skl_power_gate {
>  #define  DC_STATE_DC3CO_STATUS		REG_BIT(29)
>  #define  HOLD_PHY_CLKREQ_PG1_LATCH	REG_BIT(21)
>  #define  HOLD_PHY_PG1_LATCH		REG_BIT(20)
> -#define  DC_STATE_EN_UPTO_DC5		(1 << 0)
>  #define  DC_STATE_EN_DC9		(1 << 3)
> -#define  DC_STATE_EN_UPTO_DC6		(2 << 0)
> -#define  DC_STATE_EN_UPTO_DC3CO		(3 << 0)
> -#define  DC_STATE_EN_UPTO_DC5_DC6_MASK   0x3
> +#define  DC_STATE_EN_UPTO_DC5_DC6_MASK   REG_GENMASK(1, 0)
> +#define  DC_STATE_EN_DISABLE
> 	REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 0)
> +#define  DC_STATE_EN_UPTO_DC5
> 	REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 1)
> +#define  DC_STATE_EN_UPTO_DC6
> 	REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 2)
> +#define  DC_STATE_EN_UPTO_DC3CO
> 	REG_FIELD_PREP(DC_STATE_EN_UPTO_DC5_DC6_MASK, 3)
> 
>  #define  DC_STATE_DEBUG                  _MMIO(0x45520)
>  #define  DC_STATE_DEBUG_MASK_CORES	(1 << 0)
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 04/19] drm/i915/display: Add DC3CO DC_STATE enable/disable support
  2026-03-26 17:15 ` [PATCH 04/19] drm/i915/display: Add DC3CO DC_STATE enable/disable support Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:03   ` Shankar, Uma
  0 siblings, 0 replies; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:03 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 04/19] drm/i915/display: Add DC3CO DC_STATE enable/disable
> support
> 
> Add DC3CO handling to the dc_off power well sequencing and disable the DMC
> wakelock when exiting DC3CO.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> BSpec:75253
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  .../drm/i915/display/intel_display_power_well.c  | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> 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 9a948f5e2164..cb3dcd1460b2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> @@ -867,6 +867,13 @@ void gen9_set_dc_state(struct intel_display *display,
> u32 state)
>  	power_domains->dc_state = val & mask;
>  }
> 
> +static void xe3lpd_enable_dc3co(struct intel_display *display) {
> +	drm_dbg_kms(display->drm, "Enabling DC3CO\n");
> +	intel_dmc_wl_enable(display, DC_STATE_EN_UPTO_DC3CO);
> +	gen9_set_dc_state(display, DC_STATE_EN_UPTO_DC3CO); }
> +
>  static void assert_can_enable_dc5(struct intel_display *display)  {
>  	enum i915_power_well_id high_pg;
> @@ -1055,9 +1062,13 @@ void gen9_disable_dc_states(struct intel_display
> *display)
>  	}
> 
>  	if (old_state == DC_STATE_EN_UPTO_DC5 ||
> -	    old_state == DC_STATE_EN_UPTO_DC6)
> +	    old_state == DC_STATE_EN_UPTO_DC6 ||
> +	    old_state == DC_STATE_EN_UPTO_DC3CO)
>  		intel_dmc_wl_disable(display);
> 
> +	if (old_state == DC_STATE_EN_UPTO_DC3CO)
> +		return;
> +
>  	intel_cdclk_get_cdclk(display, &cdclk_config);
>  	/* Can't read out voltage_level so can't use intel_cdclk_changed() */
>  	drm_WARN_ON(display->drm,
> @@ -1093,6 +1104,9 @@ static void gen9_dc_off_power_well_disable(struct
> intel_display *display,
>  		return;
> 
>  	switch (power_domains->target_dc_state) {
> +	case DC_STATE_EN_UPTO_DC3CO:
> +		xe3lpd_enable_dc3co(display);
> +		break;
>  	case DC_STATE_EN_UPTO_DC6:
>  		skl_enable_dc6(display);
>  		break;
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 05/19] drm/i915/display: Validate target DC state against allowed_dc_mask
  2026-03-26 17:15 ` [PATCH 05/19] drm/i915/display: Validate target DC state against allowed_dc_mask Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:04   ` Shankar, Uma
  0 siblings, 0 replies; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:04 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 05/19] drm/i915/display: Validate target DC state against
> allowed_dc_mask
> 
> Validate the requested target DC state against allowed_dc_mask to avoid
> programming unsupported DC states.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_power.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
> b/drivers/gpu/drm/i915/display/intel_display_power.c
> index 0afae5c2f62b..12967db27c8d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> @@ -302,6 +302,13 @@ void intel_display_power_set_target_dc_state(struct
> intel_display *display,
>  	struct i915_power_domains *power_domains = &display->power.domains;
> 
>  	mutex_lock(&power_domains->lock);
> +
> +	if ((state & power_domains->allowed_dc_mask) != state) {
> +		drm_dbg_kms(display->drm,
> +			    "Rejecting DC state 0x%x (allowed mask 0x%x)\n",
> +			     state, power_domains->allowed_dc_mask);
> +		goto unlock;
> +	}
>  	power_well = lookup_power_well(display, SKL_DISP_DC_OFF);
> 
>  	if (drm_WARN_ON(display->drm, !power_well))
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum
  2026-03-26 17:15 ` [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:16   ` Shankar, Uma
  2026-04-20 12:12     ` Dibin Moolakadan Subrahmanian
  2026-04-14  7:11   ` Jani Nikula
  1 sibling, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:16 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO
> trigger enum

HAS_DC3CO has not been introduced as part of this series so no fix as such.
Sync with CMTG series to finalize a common macro.

> Fix HAS_DC3CO() based on display version and introduce an enum to track
> DC3CO enabling triggers.
> 
> BSpec: 75253
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  .../gpu/drm/i915/display/intel_display_device.h   |  2 +-
>  .../gpu/drm/i915/display/intel_display_power.h    | 15 +++++++++++++++
>  2 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h
> b/drivers/gpu/drm/i915/display/intel_display_device.h
> index 35e06fcf794d..002fe0ce951a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_device.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_device.h
> @@ -189,7 +189,7 @@ struct intel_display_platforms {
>  #define HAS_LRR(__display)		(DISPLAY_VER(__display) >= 12)
>  #define HAS_LSPCON(__display)		(IS_DISPLAY_VER(__display, 9,
> 10))
>  #define HAS_LT_PHY(__display)		((__display)->platform.novalake)
> -#define HAS_DC3CO(__display)		((__display)->platform.novalake)
> +#define HAS_DC3CO(__display)		(DISPLAY_VER(__display) >= 35)

This is the trigger for CI build failure. Fix it.

>  #define HAS_MBUS_JOINING(__display)	((__display)->platform.alderlake_p
> || DISPLAY_VER(__display) >= 14)
>  #define HAS_MSO(__display)		(DISPLAY_VER(__display) >= 12)
>  #define HAS_OVERLAY(__display)		(DISPLAY_INFO(__display)-
> >has_overlay)
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h
> b/drivers/gpu/drm/i915/display/intel_display_power.h
> index d616d5d09cbe..3fb45154864e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
> @@ -131,6 +131,21 @@ struct intel_power_domain_mask {
>  	DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);  };
> 
> +/*
> + * DC3CO enabling triggers (bitmask).
> + * DC3CO may be enabled when at least one of these triggers is active.
> + * Additional constraints may still apply.
> + */
> +enum intel_dc3co_trigger {
> +	DC3CO_TRIGGER_NONE	     = 0,
> +	DC3CO_TRIGGER_PSR2	     = BIT(0),
> +	DC3CO_TRIGGER_LOBF	     = BIT(1),
> +	DC3CO_TRIGGER_PANEL_REPLAY   = BIT(2),
> +	DC3CO_TRIGGER_ALL  = DC3CO_TRIGGER_PSR2 |
> +			     DC3CO_TRIGGER_LOBF |
> +			     DC3CO_TRIGGER_PANEL_REPLAY,
> +};
> +
>  struct i915_power_domains {
>  	/*
>  	 * Power wells needed for initialization at driver init and suspend
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support
  2026-03-26 17:15 ` [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:18   ` Shankar, Uma
  2026-04-20 12:21     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:18 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support
> 
> Add a helper to query DC3CO support from allowed_dc_mask.

Change looks good but I feel this can be squashed with some earlier patches.

> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_power.c | 7 +++++++
> drivers/gpu/drm/i915/display/intel_display_power.h | 1 +
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
> b/drivers/gpu/drm/i915/display/intel_display_power.c
> index 12967db27c8d..a3b0c8ad8bb5 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> @@ -365,6 +365,13 @@ u32 intel_display_power_get_current_dc_state(struct
> intel_display *display)
>  	return current_dc_state;
>  }
> 
> +bool intel_display_power_dc3co_supported(struct intel_display *display)
> +{
> +	struct i915_power_domains *power_domains = &display->power.domains;
> +
> +	return (power_domains->allowed_dc_mask &
> DC_STATE_EN_UPTO_DC3CO) ==
> +DC_STATE_EN_UPTO_DC3CO; }
> +
>  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 3fb45154864e..f57ce99a6039 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
> @@ -201,6 +201,7 @@ 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_dc3co_supported(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	[flat|nested] 49+ messages in thread

* RE: [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation
  2026-03-26 17:15 ` [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:42   ` Shankar, Uma
  2026-04-22 14:35     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:42 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation
> 
> Compute DC3CO eligibility during atomic_check based on pipe/port constraints
> and runtime triggers, and propagate the result via intel_atomic_state.
> 
> When DC3CO is allowed, request DC_STATE_EN_UPTO_DC3CO and reduce the
> DC entry delay. Otherwise, retain the existing delay and set default
> DC_STATE_EN_UPTO_DC6 .

Specify reasoning for reducing delay, would be good to add as comment.

> 
> BSpec: 75253
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 98 ++++++++++++++++++-
> drivers/gpu/drm/i915/display/intel_display.h  |  2 +-
>  .../drm/i915/display/intel_display_types.h    |  7 ++
>  3 files changed, 101 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index f20d5ebe06ed..df0eaf6ae76b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -5943,6 +5943,81 @@ static bool intel_pipes_need_modeset(struct
> intel_atomic_state *state,
>  	return false;
>  }
> 
> +bool intel_dc3co_allowed(struct intel_atomic_state *state) {
> +	return state && state->dc3co.allowed;
> +}
> +
> +static bool intel_dc3co_port_pipe_compatible(struct intel_dp *intel_dp,
> +					     const struct intel_crtc_state
> *crtc_state) {
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> +	enum port port = dig_port->base.port;
> +	int num_pipes = intel_crtc_num_joined_pipes(crtc_state);
> +
> +	return num_pipes == 1 && pipe <= PIPE_B && port <= PORT_B; }
> +
> +static void intel_dc3co_compute_state(struct intel_atomic_state *state)
> +{
> +	struct intel_display *display = to_intel_display(state);
> +	struct intel_crtc *crtc;
> +	struct intel_crtc_state *crtc_state;
> +	struct intel_encoder *encoder;
> +	struct intel_dp *intel_dp;
> +	int active_pipes = 0;
> +	u32 trigger = 0;
> +
> +	/* disable unless all conditions are met */
> +	state->dc3co.trigger = DC3CO_TRIGGER_NONE;
> +	state->dc3co.allowed = false;
> +
> +	if (!HAS_DC3CO(display))
> +		return;
> +
> +	if (state->modeset)
> +		return;
> +
> +	for_each_intel_crtc(display->drm, crtc) {
> +		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> +		if (!crtc_state)
> +			crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> +
> +		if (!crtc_state || !crtc_state->hw.active)
> +			continue;
> +
> +		active_pipes++;
> +
> +		if (active_pipes > 1)
> +			return;
> +
> +		for_each_intel_encoder_mask(display->drm, encoder,
> +					    crtc_state->uapi.encoder_mask) {
> +			if (encoder->type != INTEL_OUTPUT_EDP)
> +				return;
> +
> +			intel_dp = enc_to_intel_dp(encoder);
> +
> +			if (!intel_dc3co_port_pipe_compatible(intel_dp,
> crtc_state))
> +				return;
> +		}
> +
> +		if (crtc_state->has_lobf)
> +			trigger |= DC3CO_TRIGGER_LOBF;
> +		if (crtc_state->has_panel_replay)
> +			trigger |= DC3CO_TRIGGER_PANEL_REPLAY;
> +		if (crtc_state->has_sel_update)
> +			trigger |= DC3CO_TRIGGER_PSR2;
> +	}

Leave a blank line

> +	if (trigger) {
> +		state->dc3co.trigger = trigger;

Here if we have 2 pipes, trigger will still get updated. Harmless but it doesn't look nice.
Would be good to fix it to reflect default value for trigger if more than 1 crtc's.

> +		state->dc3co.allowed = true;
> +	}

Here as well.

> +	drm_dbg_kms(display->drm, "DC3CO allowed=%d trigger=0x%x\n",
> +		    state->dc3co.allowed, state->dc3co.trigger); }
> +
>  static int intel_atomic_check_joiner(struct intel_atomic_state *state,
>  				     struct intel_crtc *primary_crtc)  { @@ -6623,6
> +6698,7 @@ int intel_atomic_check(struct drm_device *dev,
>  	if (ret)
>  		goto fail;
> 
> +	intel_dc3co_compute_state(state);
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  					    new_crtc_state, i) {
>  		intel_color_assert_luts(new_crtc_state);
> @@ -7505,6 +7581,7 @@ static void intel_atomic_commit_tail(struct
> intel_atomic_state *state)
>  	struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {};
>  	struct ref_tracker *wakeref = NULL;
>  	int i;
> +	int power_async_delay;
> 
>  	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
>  		intel_atomic_dsb_prepare(state, crtc); @@ -7711,11 +7788,22
> @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  		 */
>  		intel_uncore_arm_unclaimed_mmio_detection(uncore);
>  	}
> -	/*
> -	 * Delay re-enabling DC states by 17 ms to avoid the off->on->off
> -	 * toggling overhead at and above 60 FPS.
> -	 */
> -	intel_display_power_put_async_delay(display,
> POWER_DOMAIN_DC_OFF, wakeref, 17);
> +
> +	if (intel_dc3co_allowed(state) &&
> +	    intel_display_power_dc3co_supported(display)) {
> +		intel_display_power_set_target_dc_state(display,
> DC_STATE_EN_UPTO_DC3CO);
> +		power_async_delay = 1;

Add comment explaining reason for 1ms delay.
What happens if DC3Co was already enabled. Do we need to enable again at every commit ?

> +	} else {
> +		/*
> +		 * Delay re-enabling DC states by 17 ms to avoid the off->on->off
> +		 * toggling overhead at and above 60 FPS.
> +		 */
> +		intel_display_power_set_target_dc_state(display,
> DC_STATE_EN_UPTO_DC6);
> +		power_async_delay = 17;
> +	}

Leave a blank line.

> +	intel_display_power_put_async_delay(display,
> +					    POWER_DOMAIN_DC_OFF, wakeref,
> power_async_delay);
> +
>  	intel_display_rpm_put(display, state->wakeref);
> 
>  	/*
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h
> b/drivers/gpu/drm/i915/display/intel_display.h
> index 552a59d19e0f..6eb84f9d8791 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -535,5 +535,5 @@ bool assert_port_valid(struct intel_display *display, enum
> port port);
> 
>  bool intel_scanout_needs_vtd_wa(struct intel_display *display);  int
> intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state);
> -
> +bool intel_dc3co_allowed(struct intel_atomic_state *state);
>  #endif
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 6830f911d94d..6c7f5bbbc821 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -632,6 +632,11 @@ struct dpll {
>  	int	p;
>  };
> 
> +struct intel_dc3co_state {
> +	bool allowed; /* DC3CO eligibility result */
> +	u32 trigger; /* Bitmask of active DC3CO triggers */ };
> +
>  struct intel_atomic_state {
>  	struct drm_atomic_state base;
> 
> @@ -658,6 +663,8 @@ struct intel_atomic_state {
>  	bool rps_interactive;
> 
>  	struct work_struct cleanup_work;
> +
> +	struct intel_dc3co_state dc3co;

Atomic_state may not be the right place for this, check and place it at right structure.

>  };
> 
>  struct intel_plane_state {
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state
  2026-03-26 17:15 ` [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:44   ` Shankar, Uma
  2026-04-20 12:26     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:44 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from
> intel_crtc_state
> 
> Remove dc3co_exitline from struct intel_crtc_state, as it is not used anywhere in
> the driver.
> 
> Also remove the corresponding register read in intel_psr_get_config().

Change Looks Good, but squash it with earlier patch (9) in the series.

> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_types.h | 1 -
>  drivers/gpu/drm/i915/display/intel_psr.c           | 1 -
>  2 files changed, 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 60366087038f..0a327c4df98d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1192,7 +1192,6 @@ struct intel_crtc_state {
>  	bool pkg_c_latency_used;
>  	/* Only used for state verification. */
>  	enum intel_panel_replay_dsc_support panel_replay_dsc_support;
> -	u32 dc3co_exitline;
>  	u16 su_y_granularity;
>  	u8 active_non_psr_pipes;
>  	const char *no_psr_reason;
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 40adbd1c8ddc..987d49536548 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -1822,7 +1822,6 @@ void intel_psr_get_config(struct intel_encoder
> *encoder,
>  	if (DISPLAY_VER(display) >= 12) {
>  		val = intel_de_read(display,
>  				    TRANS_EXITLINE(display, cpu_transcoder));
> -		pipe_config->dc3co_exitline =
> REG_FIELD_GET(EXITLINE_MASK, val);
>  	}
>  unlock:
>  	mutex_unlock(&intel_dp->psr.lock);
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 11/19] drm/i915/display: Store DC3CO eligibility in PSR state
  2026-03-26 17:15 ` [PATCH 11/19] drm/i915/display: Store DC3CO eligibility in PSR state Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:54   ` Shankar, Uma
  0 siblings, 0 replies; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:54 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 11/19] drm/i915/display: Store DC3CO eligibility in PSR state
> 
> Store DC3CO eligibility in intel_dp->psr during
> intel_psr_post_plane_update() so PSR configuration can take DC3CO into
> account.
> 
> This will be used to control PSR2 parameters such as idle frames
> 
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++
>  drivers/gpu/drm/i915/display/intel_psr.c           | 5 +++++
>  2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 0a327c4df98d..d0d2cda3d669 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1783,6 +1783,8 @@ struct intel_psr {
>  	ktime_t last_exit;
>  	bool sink_not_reliable;
>  	bool irq_aux_error;
> +	/* DC3CO eligibility used to control PSR configuration */
> +	bool dc3co_eligible;
>  	u16 su_w_granularity;
>  	u16 su_y_granularity;
>  	bool source_panel_replay_support;
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 987d49536548..bab254700a62 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -2239,6 +2239,8 @@ static void intel_psr_disable_locked(struct intel_dp
> *intel_dp)
>  	intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
>  	intel_dp->psr.active_non_psr_pipes = 0;
>  	intel_dp->psr.pkg_c_latency_used = 0;
> +	intel_dp->psr.dc3co_eligible = false;
> +

Drop the blank line.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

>  }
> 
>  /**
> @@ -3061,6 +3063,9 @@ void intel_psr_post_plane_update(struct
> intel_atomic_state *state,
>  		 */
>  		intel_dp->psr.busy_frontbuffer_bits = 0;
> 
> +		intel_dp->psr.dc3co_eligible = intel_dc3co_allowed(state) &&
> +			intel_display_power_dc3co_supported(display);
> +
>  		mutex_unlock(&psr->lock);
>  	}
>  }
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO
  2026-03-26 17:15 ` [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:56   ` Shankar, Uma
  2026-04-22 14:37     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:56 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO
> 
> Force idle_frames to 0 when DC3CO is eligible.
> 
> BSpec: 75253
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index bab254700a62..16a9f4111ac8 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -1040,10 +1040,13 @@ static void hsw_activate_psr2(struct intel_dp
> *intel_dp)
>  	u32 psr_val = 0;
>  	u8 idle_frames;
> 
> +	/* DC3CO requires idle_frames = 0 */
> +	if (intel_dp->psr.dc3co_eligible)
> +		idle_frames = 0;
>  	/* Wa_16025596647 */
> -	if ((DISPLAY_VER(display) == 20 ||
> -	     IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
> &&
> -	    is_dc5_dc6_blocked(intel_dp) && intel_dp->psr.pkg_c_latency_used)
> +	else if ((DISPLAY_VER(display) == 20 ||
> +		  IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0,
> STEP_B0)) &&
> +		 is_dc5_dc6_blocked(intel_dp) && intel_dp-
> >psr.pkg_c_latency_used)
>  		idle_frames = 0;

This condition itself can be extended instead of a new if block.

>  	else
>  		idle_frames = psr_compute_idle_frames(intel_dp);
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM
  2026-03-26 17:15 ` [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM Dibin Moolakadan Subrahmanian
@ 2026-04-13 21:58   ` Shankar, Uma
  2026-04-22 14:43     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 21:58 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM
> 
> Set PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL when DC3CO is allowed.

Change Looks Good, but squash this with patch 13.

> BSpec: 75253
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_alpm.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c
> b/drivers/gpu/drm/i915/display/intel_alpm.c
> index a7350ce8e716..9f92513a23c0 100644
> --- a/drivers/gpu/drm/i915/display/intel_alpm.c
> +++ b/drivers/gpu/drm/i915/display/intel_alpm.c
> @@ -365,6 +365,9 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
>  	struct intel_display *display = to_intel_display(intel_dp);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	u32 alpm_ctl;
> +	struct intel_atomic_state *state =
> +		to_intel_atomic_state(crtc_state->uapi.state);
> +
> 
>  	if (DISPLAY_VER(display) < 20 || (!intel_psr_needs_alpm(intel_dp,
> crtc_state) &&
>  					  !crtc_state->has_lobf))
> @@ -389,6 +392,12 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
>  			if (crtc_state->disable_as_sdp_when_pr_active)
>  				pr_alpm_ctl |=
> PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
> 
> +			if (intel_dc3co_allowed(state) &&
> +			    intel_display_power_dc3co_supported(display))
> +				pr_alpm_ctl |=
> PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
> +			else
> +				pr_alpm_ctl &=
> ~PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
> +
>  			intel_de_write(display, PR_ALPM_CTL(display,
> cpu_transcoder),
>  				       pr_alpm_ctl);
>  		}
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO
  2026-03-26 17:15 ` [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO Dibin Moolakadan Subrahmanian
@ 2026-04-13 22:11   ` Shankar, Uma
  2026-04-22 14:53     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 22:11 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO
> 
> For DC3CO, idle_frames is programmed to 0, so PSR does not enter deep sleep.
> Add delayed work to schedule DC3CO exit after an idle duration derived from
> frame time (minimum equivalent of 6 frames).
> 
> The work is re-armed from the PSR flush path on relevant frontbuffer activity, and
> once the display remains idle, DC3CO is disabled and DC6 is enabled to allow
> deeper power savings.
> 
> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  .../drm/i915/display/intel_display_types.h    |  2 +
>  drivers/gpu/drm/i915/display/intel_psr.c      | 48 +++++++++++++++++++
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index d0d2cda3d669..0c8958338f76 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1785,6 +1785,8 @@ struct intel_psr {
>  	bool irq_aux_error;
>  	/* DC3CO eligibility used to control PSR configuration */
>  	bool dc3co_eligible;
> +	/* DC3CO disable work*/

Add space before *

> +	struct delayed_work dc3co_work;
>  	u16 su_w_granularity;
>  	u16 su_y_granularity;
>  	bool source_panel_replay_support;
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 16a9f4111ac8..f3476118b8d0 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -1701,6 +1701,50 @@ static bool intel_psr_needs_wa_18037818876(struct
> intel_dp *intel_dp,
>  		!crtc_state->has_sel_update);
>  }
> 
> +static void psr2_dc3co_disable_locked(struct intel_dp *intel_dp) {
> +	struct intel_display *display = to_intel_display(intel_dp);
> +
> +	if (intel_dp->psr.dc3co_eligible) {
> +		intel_dp->psr.dc3co_eligible = false;
> +		intel_display_power_set_target_dc_state(display,
> DC_STATE_EN_UPTO_DC6);

Before switching to DC6, would be good to call cancel_delayed_work so that
it doesn't get scheduled later and mess up the state.

> +	}
> +}
> +
> +static void psr2_dc3co_disable_work(struct work_struct *work) {
> +	struct intel_dp *intel_dp =
> +		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
> +
> +	mutex_lock(&intel_dp->psr.lock);
> +	psr2_dc3co_disable_locked(intel_dp);
> +	mutex_unlock(&intel_dp->psr.lock);
> +}
> +
> +static void
> +psr2_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
> +			enum fb_op_origin origin)
> +{
> +	struct intel_display *display = to_intel_display(intel_dp);
> +
> +	if (!intel_dp->psr.dc3co_eligible)
> +		return;
> +
> +	if (!intel_dp->psr.sel_update_enabled ||
> +	    !intel_dp->psr.active)
> +		return;
> +	/*
> +	 * At every frontbuffer flush flip event modified delay of delayed work,
> +	 * when delayed work schedules that means display has been idle.
> +	 */
> +	if (!(frontbuffer_bits &
> +	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
> +		return;
> +
> +	mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work,
> +			 intel_dp->psr.dc3co_exit_delay);

Where is this exit_delay assigned, please check. If its 0, work may get executed immediately.

> +}
> +
>  static
>  void intel_psr_set_non_psr_pipes(struct intel_dp *intel_dp,
>  				 struct intel_crtc_state *crtc_state) @@ -2273,6
> +2317,7 @@ void intel_psr_disable(struct intel_dp *intel_dp,
> 
>  	mutex_unlock(&intel_dp->psr.lock);
>  	cancel_work_sync(&intel_dp->psr.work);
> +	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
>  }
> 
>  /**
> @@ -2303,6 +2348,7 @@ void intel_psr_pause(struct intel_dp *intel_dp)
>  	mutex_unlock(&psr->lock);
> 
>  	cancel_work_sync(&psr->work);
> +	cancel_delayed_work_sync(&psr->dc3co_work);
>  }
> 
>  /**
> @@ -3527,6 +3573,7 @@ void intel_psr_flush(struct intel_display *display,
>  		if (origin == ORIGIN_FLIP ||
>  		    (origin == ORIGIN_CURSOR_UPDATE &&
>  		     !intel_dp->psr.psr2_sel_fetch_enabled)) {
> +			psr2_dc3co_flush_locked(intel_dp, frontbuffer_bits,
> origin);
>  			goto unlock;
>  		}
> 
> @@ -3585,6 +3632,7 @@ void intel_psr_init(struct intel_dp *intel_dp)
>  		intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link;
> 
>  	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
> +	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work,
> psr2_dc3co_disable_work);
>  	mutex_init(&intel_dp->psr.lock);
>  }
> 
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 16/19] drm/i915/display: Add helper to enable DC counter
  2026-03-26 17:15 ` [PATCH 16/19] drm/i915/display: Add helper to enable DC counter Dibin Moolakadan Subrahmanian
@ 2026-04-13 22:14   ` Shankar, Uma
  0 siblings, 0 replies; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 22:14 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 16/19] drm/i915/display: Add helper to enable DC counter
> 
> Add xe3lpd_enable_dc_count() to enable the DC_COUNT_EN register.
> Also define DC_STATE_DC3CO_RESIDENCY to read DC3CO residency.
> Needed to retrieve DC residency for DC3CO.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_power_well.c | 5 +++++
> drivers/gpu/drm/i915/display/intel_display_power_well.h | 1 +
>  drivers/gpu/drm/i915/display/intel_display_regs.h       | 5 +++++
>  drivers/gpu/drm/i915/display/intel_dmc.c                | 3 +++
>  4 files changed, 14 insertions(+)
> 
> 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 cb3dcd1460b2..15521442e6d4 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> @@ -867,6 +867,11 @@ void gen9_set_dc_state(struct intel_display *display,
> u32 state)
>  	power_domains->dc_state = val & mask;
>  }
> 
> +void xe3lpd_enable_dc_count(struct intel_display *display) {
> +	intel_de_write(display, DC_COUNT_EN,
> DC_COUNT_EN_COUNTER_ENABLE); }
> +
>  static void xe3lpd_enable_dc3co(struct intel_display *display)  {
>  	drm_dbg_kms(display->drm, "Enabling DC3CO\n"); diff --git
> a/drivers/gpu/drm/i915/display/intel_display_power_well.h
> b/drivers/gpu/drm/i915/display/intel_display_power_well.h
> index 8f5524da2d06..0ce64b894436 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.h
> @@ -159,6 +159,7 @@ void gen9_set_dc_state(struct intel_display *display, u32
> state);  void gen9_disable_dc_states(struct intel_display *display);  void
> bxt_enable_dc9(struct intel_display *display);  void bxt_disable_dc9(struct
> intel_display *display);
> +void xe3lpd_enable_dc_count(struct intel_display *display);
> 
>  extern const struct i915_power_well_ops i9xx_always_on_power_well_ops;
> extern const struct i915_power_well_ops chv_pipe_power_well_ops; diff --git
> a/drivers/gpu/drm/i915/display/intel_display_regs.h
> b/drivers/gpu/drm/i915/display/intel_display_regs.h
> index 2bace331437c..8b59e1ff2590 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
> @@ -3058,6 +3058,11 @@ enum skl_power_gate {
>  #define  DC_STATE_DEBUG_MASK_CORES	(1 << 0)
>  #define  DC_STATE_DEBUG_MASK_MEMORY_UP	(1 << 1)
> 
> +#define DC_COUNT_EN			_MMIO(0x457B4)
> +#define DC_COUNT_EN_COUNTER_ENABLE	REG_BIT(31)
> +
> +#define DC_STATE_DC3CO_RESIDENCY	_MMIO(0x457B8)
> +
>  #define D_COMP_BDW			_MMIO(0x138144)
> 
>  /* Pipe WM_LINETIME - watermark line time */ diff --git
> a/drivers/gpu/drm/i915/display/intel_dmc.c
> b/drivers/gpu/drm/i915/display/intel_dmc.c
> index 90ba932d940a..74d18806d01f 100644
> --- a/drivers/gpu/drm/i915/display/intel_dmc.c
> +++ b/drivers/gpu/drm/i915/display/intel_dmc.c
> @@ -937,6 +937,9 @@ void intel_dmc_load_program(struct intel_display
> *display)
> 
>  	gen9_set_dc_state_debugmask(display);
> 
> +	if (DISPLAY_VER(display) >= 35)
> +		xe3lpd_enable_dc_count(display);
> +
>  	pipedmc_clock_gating_wa(display, false);  }
> 
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 17/19] drm/i915/display: Remove DC3CO DMC debugfs
  2026-03-26 17:15 ` [PATCH 17/19] drm/i915/display: Remove DC3CO DMC debugfs Dibin Moolakadan Subrahmanian
@ 2026-04-13 22:17   ` Shankar, Uma
  0 siblings, 0 replies; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 22:17 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 17/19] drm/i915/display: Remove DC3CO DMC debugfs
> 
> DC3CO is not enabled on TGL and DG1. Remove the debugfs entry for DC3CO
> counts. A new debugfs entry for Xe3LP will be added in a subsequent patch.

Squash this with patch 1.

> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dmc.c | 6 ------
>  1 file changed, 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c
> b/drivers/gpu/drm/i915/display/intel_dmc.c
> index 74d18806d01f..f0ebdab089ca 100644
> --- a/drivers/gpu/drm/i915/display/intel_dmc.c
> +++ b/drivers/gpu/drm/i915/display/intel_dmc.c
> @@ -1645,19 +1645,13 @@ static int intel_dmc_debugfs_status_show(struct
> seq_file *m, void *unused)
>  		   DMC_VERSION_MINOR(dmc->version));
> 
>  	if (DISPLAY_VER(display) >= 12) {
> -		i915_reg_t dc3co_reg;
> -
>  		if (display->platform.dgfx || DISPLAY_VER(display) >= 14) {
> -			dc3co_reg = DG1_DMC_DEBUG3;
>  			dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
>  		} else {
> -			dc3co_reg = TGL_DMC_DEBUG3;
>  			dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
>  			dc6_reg = TGL_DMC_DEBUG_DC6_COUNT;
>  		}
> 
> -		seq_printf(m, "DC3CO count: %d\n",
> -			   intel_de_read(display, dc3co_reg));
>  	} else {
>  		dc5_reg = display->platform.broxton ?
> BXT_DMC_DC3_DC5_COUNT :
>  			SKL_DMC_DC3_DC5_COUNT;
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 18/19] drm/i915/display: Add DC3CO count and residency in dmc debugfs
  2026-03-26 17:15 ` [PATCH 18/19] drm/i915/display: Add DC3CO count and residency in dmc debugfs Dibin Moolakadan Subrahmanian
@ 2026-04-13 22:19   ` Shankar, Uma
  0 siblings, 0 replies; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 22:19 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 18/19] drm/i915/display: Add DC3CO count and residency in
> dmc debugfs
> 
> Expose DC3CO count and residency for xe3lp platforms via debugfs.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dmc.c      | 8 +++++++-
>  drivers/gpu/drm/i915/display/intel_dmc_regs.h | 2 ++
>  2 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c
> b/drivers/gpu/drm/i915/display/intel_dmc.c
> index f0ebdab089ca..6f24ee620f2e 100644
> --- a/drivers/gpu/drm/i915/display/intel_dmc.c
> +++ b/drivers/gpu/drm/i915/display/intel_dmc.c
> @@ -1645,7 +1645,13 @@ static int intel_dmc_debugfs_status_show(struct
> seq_file *m, void *unused)
>  		   DMC_VERSION_MINOR(dmc->version));
> 
>  	if (DISPLAY_VER(display) >= 12) {
> -		if (display->platform.dgfx || DISPLAY_VER(display) >= 14) {
> +		if (DISPLAY_VER(display) >= 35) {
> +			seq_printf(m, "DC3CO count: %d\n",
> +				   intel_de_read(display,
> XE3P_DMC_DC3CO_COUNT));
> +
> +			seq_printf(m, "DC3CO residency: %d\n",
> +				   intel_de_read(display,
> DC_STATE_DC3CO_RESIDENCY));
> +		} else if (display->platform.dgfx || DISPLAY_VER(display) >= 14) {
>  			dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
>  		} else {
>  			dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
> diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> index 38e342b45af0..1998549b6318 100644
> --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h
> @@ -531,6 +531,8 @@ enum pipedmc_event_id {
>  #define TGL_DMC_DEBUG3		_MMIO(0x101090)
>  #define DG1_DMC_DEBUG3		_MMIO(0x13415c)
> 
> +#define XE3P_DMC_DC3CO_COUNT	_MMIO(0x8f05C)
> +
>  #define DMC_WAKELOCK_CFG	_MMIO(0x8F1B0)
>  #define  DMC_WAKELOCK_CFG_ENABLE REG_BIT(31)
>  #define DMC_WAKELOCK1_CTL	_MMIO(0x8F140)
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from DC3CO
  2026-03-26 17:15 ` [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from DC3CO Dibin Moolakadan Subrahmanian
@ 2026-04-13 22:21   ` Shankar, Uma
  2026-04-22 14:56     ` Dibin Moolakadan Subrahmanian
  0 siblings, 1 reply; 49+ messages in thread
From: Shankar, Uma @ 2026-04-13 22:21 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar



> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> Sent: Thursday, March 26, 2026 10:46 PM
> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
> <suresh.kumar.kurmi@intel.com>
> Subject: [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from
> DC3CO
> 
> After 6 idle frames, DC3CO is exited and DC6 is enabled.
> Reprogram idle frames so that the deeper states can be entered.

Change Looks good but should be squashed with earlier patches adding PSR2 idle frames.

> Signed-off-by: Dibin Moolakadan Subrahmanian
> <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index f3476118b8d0..dcf33359dc9c 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -1708,6 +1708,7 @@ static void psr2_dc3co_disable_locked(struct intel_dp
> *intel_dp)
>  	if (intel_dp->psr.dc3co_eligible) {
>  		intel_dp->psr.dc3co_eligible = false;
>  		intel_display_power_set_target_dc_state(display,
> DC_STATE_EN_UPTO_DC6);
> +		psr2_program_idle_frames(intel_dp,
> psr_compute_idle_frames(intel_dp));
>  	}
>  }
> 
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum
  2026-03-26 17:15 ` [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum Dibin Moolakadan Subrahmanian
  2026-04-13 21:16   ` Shankar, Uma
@ 2026-04-14  7:11   ` Jani Nikula
  2026-04-20 12:17     ` Dibin Moolakadan Subrahmanian
  1 sibling, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2026-04-14  7:11 UTC (permalink / raw)
  To: Dibin Moolakadan Subrahmanian, intel-gfx, intel-xe
  Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi

On Thu, 26 Mar 2026, Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com> wrote:
> Fix HAS_DC3CO() based on display version and introduce an enum to
> track DC3CO enabling triggers.
>
> BSpec: 75253
> Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
> ---
>  .../gpu/drm/i915/display/intel_display_device.h   |  2 +-
>  .../gpu/drm/i915/display/intel_display_power.h    | 15 +++++++++++++++
>  2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
> index 35e06fcf794d..002fe0ce951a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_device.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_device.h
> @@ -189,7 +189,7 @@ struct intel_display_platforms {
>  #define HAS_LRR(__display)		(DISPLAY_VER(__display) >= 12)
>  #define HAS_LSPCON(__display)		(IS_DISPLAY_VER(__display, 9, 10))
>  #define HAS_LT_PHY(__display)		((__display)->platform.novalake)
> -#define HAS_DC3CO(__display)		((__display)->platform.novalake)
> +#define HAS_DC3CO(__display)		(DISPLAY_VER(__display) >= 35)
>  #define HAS_MBUS_JOINING(__display)	((__display)->platform.alderlake_p || DISPLAY_VER(__display) >= 14)
>  #define HAS_MSO(__display)		(DISPLAY_VER(__display) >= 12)
>  #define HAS_OVERLAY(__display)		(DISPLAY_INFO(__display)->has_overlay)
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
> index d616d5d09cbe..3fb45154864e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
> @@ -131,6 +131,21 @@ struct intel_power_domain_mask {
>  	DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);
>  };
>  
> +/*
> + * DC3CO enabling triggers (bitmask).
> + * DC3CO may be enabled when at least one of these triggers is active.
> + * Additional constraints may still apply.
> + */
> +enum intel_dc3co_trigger {
> +	DC3CO_TRIGGER_NONE	     = 0,
> +	DC3CO_TRIGGER_PSR2	     = BIT(0),
> +	DC3CO_TRIGGER_LOBF	     = BIT(1),
> +	DC3CO_TRIGGER_PANEL_REPLAY   = BIT(2),
> +	DC3CO_TRIGGER_ALL  = DC3CO_TRIGGER_PSR2 |
> +			     DC3CO_TRIGGER_LOBF |
> +			     DC3CO_TRIGGER_PANEL_REPLAY,
> +};

Enumerations are enumerations and bitmasks are bitmasks, and I don't
think they should be mixed like this.

Moreover, the enum as a type isn't even used anywhere.

BR,
Jani.


> +
>  struct i915_power_domains {
>  	/*
>  	 * Power wells needed for initialization at driver init and suspend

-- 
Jani Nikula, Intel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 01/19] drm/i915/display: Remove TGL DC3CO support
  2026-04-13 20:40   ` Shankar, Uma
@ 2026-04-20 12:01     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-20 12:01 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 02:10, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 01/19] drm/i915/display: Remove TGL DC3CO support
>>
>> Remove all Tiger Lake DC3CO-related functions, as the feature is not enabled and
>> not used. The existing structure members are intentionally left in place and will be
>> cleaned up in subsequent patches.
>>
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   .../i915/display/intel_display_power_well.c   |  25 ---
>>   .../drm/i915/display/intel_display_types.h    |   1 -
>>   drivers/gpu/drm/i915/display/intel_psr.c      | 163 ------------------
>>   3 files changed, 189 deletions(-)
>>
>> 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 f855f0f88694..6d5f07f7f590 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
>> @@ -867,23 +867,6 @@ void gen9_set_dc_state(struct intel_display *display,
>> u32 state)
>>   	power_domains->dc_state = val & mask;
>>   }
>>
>> -static void tgl_enable_dc3co(struct intel_display *display) -{
>> -	drm_dbg_kms(display->drm, "Enabling DC3CO\n");
>> -	gen9_set_dc_state(display, DC_STATE_EN_DC3CO);
>> -}
>> -
>> -static void tgl_disable_dc3co(struct intel_display *display) -{
>> -	drm_dbg_kms(display->drm, "Disabling DC3CO\n");
>> -	intel_de_rmw(display, DC_STATE_EN, DC_STATE_DC3CO_STATUS, 0);
>> -	gen9_set_dc_state(display, DC_STATE_DISABLE);
>> -	/*
>> -	 * Delay of 200us DC3CO Exit time B.Spec 49196
>> -	 */
>> -	usleep_range(200, 210);
>> -}
>> -
>>   static void assert_can_enable_dc5(struct intel_display *display)  {
>>   	enum i915_power_well_id high_pg;
>> @@ -1062,11 +1045,6 @@ void gen9_disable_dc_states(struct intel_display
>> *display)
>>   	struct intel_cdclk_config cdclk_config = {};
>>   	u32 old_state = power_domains->dc_state;
>>
>> -	if (power_domains->target_dc_state == DC_STATE_EN_DC3CO) {
>> -		tgl_disable_dc3co(display);
>> -		return;
>> -	}
>> -
>>   	if (HAS_DISPLAY(display)) {
>>   		intel_dmc_wl_get_noreg(display);
>>   		gen9_set_dc_state(display, DC_STATE_DISABLE); @@ -1115,9
>> +1093,6 @@ static void gen9_dc_off_power_well_disable(struct intel_display
>> *display,
>>   		return;
>>
>>   	switch (power_domains->target_dc_state) {
>> -	case DC_STATE_EN_DC3CO:
>> -		tgl_enable_dc3co(display);
>> -		break;
>>   	case DC_STATE_EN_UPTO_DC6:
>>   		skl_enable_dc6(display);
>>   		break;
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
>> b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index b4c3d8537a99..6830f911d94d 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -1784,7 +1784,6 @@ struct intel_psr {
>>   	bool panel_replay_enabled;
>>   	u32 dc3co_exitline;
>>   	u32 dc3co_exit_delay;
>> -	struct delayed_work dc3co_work;
>>   	u8 entry_setup_frames;
>>
>>   	u8 io_wake_lines;
>> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
>> b/drivers/gpu/drm/i915/display/intel_psr.c
>> index 5041a5a138d1..29900576e117 100644
>> --- a/drivers/gpu/drm/i915/display/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
>> @@ -85,22 +85,6 @@
>>    * issues the self-refresh re-enable code is done from a work queue, which
>>    * must be correctly synchronized/cancelled when shutting down the pipe."
>>    *
>> - * DC3CO (DC3 clock off)
>> - *
>> - * On top of PSR2, GEN12 adds a intermediate power savings state that turns
>> - * clock off automatically during PSR2 idle state.
>> - * The smaller overhead of DC3co entry/exit vs. the overhead of PSR2 deep
>> sleep
>> - * entry/exit allows the HW to enter a low-power state even when page flipping
>> - * periodically (for instance a 30fps video playback scenario).
>> - *
>> - * Every time a flips occurs PSR2 will get out of deep sleep state(if it was),
>> - * so DC3CO is enabled and tgl_dc3co_disable_work is schedule to run after 6
>> - * frames, if no other flip occurs and the function above is executed, DC3CO is
>> - * disabled and PSR2 is configured to enter deep sleep, resetting again in case
>> - * of another flip.
>> - * Front buffer modifications do not trigger DC3CO activation on purpose as it
>> - * would bring a lot of complexity and most of the moderns systems will only
>> - * use page flips.
>>    */
>>
>>   /*
>> @@ -1178,108 +1162,6 @@ static void psr2_program_idle_frames(struct intel_dp
>> *intel_dp,
>>   		     EDP_PSR2_IDLE_FRAMES(idle_frames));
>>   }
>>
>> -static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp) -{
>> -	struct intel_display *display = to_intel_display(intel_dp);
>> -
>> -	psr2_program_idle_frames(intel_dp, 0);
>> -	intel_display_power_set_target_dc_state(display,
>> DC_STATE_EN_DC3CO);
>> -}
>> -
>> -static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp) -{
>> -	struct intel_display *display = to_intel_display(intel_dp);
>> -
>> -	intel_display_power_set_target_dc_state(display,
>> DC_STATE_EN_UPTO_DC6);
>> -	psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp));
>> -}
>> -
>> -static void tgl_dc3co_disable_work(struct work_struct *work) -{
>> -	struct intel_dp *intel_dp =
>> -		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
>> -
>> -	mutex_lock(&intel_dp->psr.lock);
>> -	/* If delayed work is pending, it is not idle */
>> -	if (delayed_work_pending(&intel_dp->psr.dc3co_work))
>> -		goto unlock;
>> -
>> -	tgl_psr2_disable_dc3co(intel_dp);
>> -unlock:
>> -	mutex_unlock(&intel_dp->psr.lock);
>> -}
>> -
>> -static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp) -{
>> -	if (!intel_dp->psr.dc3co_exitline)
>> -		return;
>> -
>> -	cancel_delayed_work(&intel_dp->psr.dc3co_work);
>> -	/* Before PSR2 exit disallow dc3co*/
>> -	tgl_psr2_disable_dc3co(intel_dp);
>> -}
>> -
>> -static bool
>> -dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp,
>> -			      struct intel_crtc_state *crtc_state)
>> -{
>> -	struct intel_display *display = to_intel_display(intel_dp);
>> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>> -	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>> -	enum port port = dig_port->base.port;
>> -
>> -	if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14)
>> -		return pipe <= PIPE_B && port <= PORT_B;
>> -	else
>> -		return pipe == PIPE_A && port == PORT_A;
>> -}
>> -
>> -static void
>> -tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
>> -				  struct intel_crtc_state *crtc_state)
>> -{
>> -	struct intel_display *display = to_intel_display(intel_dp);
>> -	const u32 crtc_vdisplay = crtc_state->uapi.adjusted_mode.crtc_vdisplay;
>> -	struct i915_power_domains *power_domains = &display->power.domains;
>> -	u32 exit_scanlines;
>> -
>> -	/*
>> -	 * FIXME: Due to the changed sequence of activating/deactivating
>> DC3CO,
>> -	 * disable DC3CO until the changed dc3co activating/deactivating
>> sequence
>> -	 * is applied. B.Specs:49196
>> -	 */
>> -	return;
>> -
>> -	/*
>> -	 * DMC's DC3CO exit mechanism has an issue with Selective Fecth
>> -	 * TODO: when the issue is addressed, this restriction should be removed.
>> -	 */
>> -	if (crtc_state->enable_psr2_sel_fetch)
>> -		return;
>> -
>> -	if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC3CO))
>> -		return;
>> -
>> -	if (!dc3co_is_pipe_port_compatible(intel_dp, crtc_state))
>> -		return;
>> -
>> -	/* Wa_16011303918:adl-p */
>> -	if (intel_display_wa(display, INTEL_DISPLAY_WA_16011303918))
>> -		return;
>> -
>> -	/*
>> -	 * DC3CO Exit time 200us B.Spec 49196
>> -	 * PSR2 transcoder Early Exit scanlines = ROUNDUP(200 / line time) + 1
>> -	 */
>> -	exit_scanlines =
>> -		intel_usecs_to_scanlines(&crtc_state->uapi.adjusted_mode, 200)
>> + 1;
>> -
>> -	if (drm_WARN_ON(display->drm, exit_scanlines > crtc_vdisplay))
>> -		return;
>> -
>> -	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
>> -}
>> -
>>   static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
>>   					      struct intel_crtc_state *crtc_state)  {
>> @@ -1622,8 +1504,6 @@ static bool intel_psr2_config_valid(struct intel_dp
>> *intel_dp,
>>   		return false;
>>   	}
>>
>> -	tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
>> -
>>   	return true;
>>   }
>>
>> @@ -2071,16 +1951,6 @@ static void intel_psr_enable_source(struct intel_dp
>> *intel_dp,
>>
>>   	psr_irq_control(intel_dp);
>>
>> -	/*
>> -	 * TODO: if future platforms supports DC3CO in more than one
>> -	 * transcoder, EXITLINE will need to be unset when disabling PSR
>> -	 */
>> -	if (intel_dp->psr.dc3co_exitline)
>> -		intel_de_rmw(display,
>> -			     TRANS_EXITLINE(display, cpu_transcoder),
>> -			     EXITLINE_MASK,
>> -			     intel_dp->psr.dc3co_exitline << EXITLINE_SHIFT |
>> EXITLINE_ENABLE);
>> -
>>   	if (HAS_PSR_HW_TRACKING(display) &&
>> HAS_PSR2_SEL_FETCH(display))
>>   		intel_de_rmw(display, CHICKEN_PAR1_1,
>> IGNORE_PSR2_HW_TRACKING,
>>   			     intel_dp->psr.psr2_sel_fetch_enabled ?
>> @@ -2258,7 +2128,6 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
>>   		intel_de_rmw(display, TRANS_DP2_CTL(intel_dp-
>>> psr.transcoder),
>>   			     TRANS_DP2_PANEL_REPLAY_ENABLE, 0);
>>   	} else if (intel_dp->psr.sel_update_enabled) {
>> -		tgl_disallow_dc3co_on_psr2_exit(intel_dp);
>>
> Nit: This leaves a blank line
>
> With above fixed, this is
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>

I will remove the blank line.

>
>>   		val = intel_de_rmw(display,
>>   				   EDP_PSR2_CTL(display, cpu_transcoder), @@
>> -2401,7 +2270,6 @@ void intel_psr_disable(struct intel_dp *intel_dp,
>>
>>   	mutex_unlock(&intel_dp->psr.lock);
>>   	cancel_work_sync(&intel_dp->psr.work);
>> -	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
>>   }
>>
>>   /**
>> @@ -2432,7 +2300,6 @@ void intel_psr_pause(struct intel_dp *intel_dp)
>>   	mutex_unlock(&psr->lock);
>>
>>   	cancel_work_sync(&psr->work);
>> -	cancel_delayed_work_sync(&psr->dc3co_work);
>>   }
>>
>>   /**
>> @@ -3568,34 +3435,6 @@ void intel_psr_invalidate(struct intel_display *display,
>>   		mutex_unlock(&intel_dp->psr.lock);
>>   	}
>>   }
>> -/*
>> - * When we will be completely rely on PSR2 S/W tracking in future,
>> - * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP
>> - * event also therefore tgl_dc3co_flush_locked() require to be changed
>> - * accordingly in future.
>> - */
>> -static void
>> -tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
>> -		       enum fb_op_origin origin)
>> -{
>> -	struct intel_display *display = to_intel_display(intel_dp);
>> -
>> -	if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.sel_update_enabled ||
>> -	    !intel_dp->psr.active)
>> -		return;
>> -
>> -	/*
>> -	 * At every frontbuffer flush flip event modified delay of delayed work,
>> -	 * when delayed work schedules that means display has been idle.
>> -	 */
>> -	if (!(frontbuffer_bits &
>> -	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
>> -		return;
>> -
>> -	tgl_psr2_enable_dc3co(intel_dp);
>> -	mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work,
>> -			 intel_dp->psr.dc3co_exit_delay);
>> -}
>>
>>   static void _psr_flush_handle(struct intel_dp *intel_dp)  { @@ -3682,7 +3521,6
>> @@ void intel_psr_flush(struct intel_display *display,
>>   		if (origin == ORIGIN_FLIP ||
>>   		    (origin == ORIGIN_CURSOR_UPDATE &&
>>   		     !intel_dp->psr.psr2_sel_fetch_enabled)) {
>> -			tgl_dc3co_flush_locked(intel_dp, frontbuffer_bits, origin);
>>   			goto unlock;
>>   		}
>>
>> @@ -3741,7 +3579,6 @@ void intel_psr_init(struct intel_dp *intel_dp)
>>   		intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link;
>>
>>   	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
>> -	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work,
>> tgl_dc3co_disable_work);
>>   	mutex_init(&intel_dp->psr.lock);
>>   }
>>
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with DC_STATE_EN_UPTO_DC3CO
  2026-04-13 20:51   ` Shankar, Uma
@ 2026-04-20 12:04     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-20 12:04 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar

On 14-04-2026 02:21, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with
>> DC_STATE_EN_UPTO_DC3CO
> Nit: Patch header can be re-phrased "Switch DC3Co enable from standalone bit to DC level encoding"
>
> Changes look Good to me.
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>

I will update the patch header as suggested.

>> On platforms prior to xe3, DC3CO was controlled via a standalone enable bit.
>> Starting with xe3 DC3CO is encoded as part of the existing
>> DC_STATE_EN_UPTO_DC* field.
>>
>> No functional change, as DC3CO is not enabled on platforms prior to xe3.
>>
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_display_power.c      | 6 +++---
>>   drivers/gpu/drm/i915/display/intel_display_power_well.c | 4 ++--
>>   drivers/gpu/drm/i915/display/intel_display_regs.h       | 2 +-
>>   drivers/gpu/drm/i915/display/intel_dmc_wl.c             | 2 +-
>>   4 files changed, 7 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
>> b/drivers/gpu/drm/i915/display/intel_display_power.c
>> index ec96b141c74c..0afae5c2f62b 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
>> @@ -267,7 +267,7 @@ sanitize_target_dc_state(struct intel_display *display,
>>   	static const u32 states[] = {
>>   		DC_STATE_EN_UPTO_DC6,
>>   		DC_STATE_EN_UPTO_DC5,
>> -		DC_STATE_EN_DC3CO,
>> +		DC_STATE_EN_UPTO_DC3CO,
>>   		DC_STATE_DISABLE,
>>   	};
>>   	int i;
>> @@ -999,10 +999,10 @@ static u32 get_allowed_dc_mask(struct intel_display
>> *display, int enable_dc)
>>
>>   	switch (requested_dc) {
>>   	case 4:
>> -		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6;
>> +		mask |= DC_STATE_EN_UPTO_DC3CO |
>> DC_STATE_EN_UPTO_DC6;
>>   		break;
>>   	case 3:
>> -		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC5;
>> +		mask |= DC_STATE_EN_UPTO_DC3CO |
>> DC_STATE_EN_UPTO_DC5;
>>   		break;
>>   	case 2:
>>   		mask |= DC_STATE_EN_UPTO_DC6;
>> 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 6d5f07f7f590..9a948f5e2164 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
>> @@ -773,7 +773,7 @@ static u32 gen9_dc_mask(struct intel_display *display)
>>   	mask = DC_STATE_EN_UPTO_DC5;
>>
>>   	if (DISPLAY_VER(display) >= 12)
>> -		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6
>> +		mask |= DC_STATE_EN_UPTO_DC3CO |
>> DC_STATE_EN_UPTO_DC6
>>   					  | DC_STATE_EN_DC9;
>>   	else if (DISPLAY_VER(display) == 11)
>>   		mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9;
>> @@ -1023,7 +1023,7 @@ static void bxt_verify_dpio_phy_power_wells(struct
>> intel_display *display)  static bool gen9_dc_off_power_well_enabled(struct
>> intel_display *display,
>>   					   struct i915_power_well *power_well)  {
>> -	return ((intel_de_read(display, DC_STATE_EN) &
>> DC_STATE_EN_DC3CO) == 0 &&
>> +	return ((intel_de_read(display, DC_STATE_EN) &
>> DC_STATE_EN_UPTO_DC3CO)
>> +== 0 &&
>>   		(intel_de_read(display, DC_STATE_EN) &
>> DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0);  }
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h
>> b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> index 5838338f495a..d0196d4ad234 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> @@ -3044,13 +3044,13 @@ enum skl_power_gate {
>>   /* GEN9 DC */
>>   #define DC_STATE_EN			_MMIO(0x45504)
>>   #define  DC_STATE_DISABLE		0
>> -#define  DC_STATE_EN_DC3CO		REG_BIT(30)
>>   #define  DC_STATE_DC3CO_STATUS		REG_BIT(29)
>>   #define  HOLD_PHY_CLKREQ_PG1_LATCH	REG_BIT(21)
>>   #define  HOLD_PHY_PG1_LATCH		REG_BIT(20)
>>   #define  DC_STATE_EN_UPTO_DC5		(1 << 0)
>>   #define  DC_STATE_EN_DC9		(1 << 3)
>>   #define  DC_STATE_EN_UPTO_DC6		(2 << 0)
>> +#define  DC_STATE_EN_UPTO_DC3CO		(3 << 0)
>>   #define  DC_STATE_EN_UPTO_DC5_DC6_MASK   0x3
>>
>>   #define  DC_STATE_DEBUG                  _MMIO(0x45520)
>> diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c
>> b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
>> index 73a3101514f3..9f403b7820ab 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
>> @@ -260,7 +260,7 @@ static bool intel_dmc_wl_check_range(struct intel_display
>> *display,
>>   	 * the DMC and requires a DC exit for proper access.
>>   	 */
>>   	switch (dc_state) {
>> -	case DC_STATE_EN_DC3CO:
>> +	case DC_STATE_EN_UPTO_DC3CO:
>>   		ranges = xe3lpd_dc3co_dmc_ranges;
>>   		break;
>>   	case DC_STATE_EN_UPTO_DC5:
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum
  2026-04-13 21:16   ` Shankar, Uma
@ 2026-04-20 12:12     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-20 12:12 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 02:46, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO
>> trigger enum
> HAS_DC3CO has not been introduced as part of this series so no fix as such.
> Sync with CMTG series to finalize a common macro.
>> Fix HAS_DC3CO() based on display version and introduce an enum to track
>> DC3CO enabling triggers.
>>
>> BSpec: 75253
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   .../gpu/drm/i915/display/intel_display_device.h   |  2 +-
>>   .../gpu/drm/i915/display/intel_display_power.h    | 15 +++++++++++++++
>>   2 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h
>> b/drivers/gpu/drm/i915/display/intel_display_device.h
>> index 35e06fcf794d..002fe0ce951a 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_device.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_device.h
>> @@ -189,7 +189,7 @@ struct intel_display_platforms {
>>   #define HAS_LRR(__display)		(DISPLAY_VER(__display) >= 12)
>>   #define HAS_LSPCON(__display)		(IS_DISPLAY_VER(__display, 9,
>> 10))
>>   #define HAS_LT_PHY(__display)		((__display)->platform.novalake)
>> -#define HAS_DC3CO(__display)		((__display)->platform.novalake)
>> +#define HAS_DC3CO(__display)		(DISPLAY_VER(__display) >= 35)
> This is the trigger for CI build failure. Fix it.

I will add it as new macro so build will pass and align with CMTG
once CMTG changes are finalized.

>
>>   #define HAS_MBUS_JOINING(__display)	((__display)->platform.alderlake_p
>> || DISPLAY_VER(__display) >= 14)
>>   #define HAS_MSO(__display)		(DISPLAY_VER(__display) >= 12)
>>   #define HAS_OVERLAY(__display)		(DISPLAY_INFO(__display)-
>>> has_overlay)
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h
>> b/drivers/gpu/drm/i915/display/intel_display_power.h
>> index d616d5d09cbe..3fb45154864e 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
>> @@ -131,6 +131,21 @@ struct intel_power_domain_mask {
>>   	DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);  };
>>
>> +/*
>> + * DC3CO enabling triggers (bitmask).
>> + * DC3CO may be enabled when at least one of these triggers is active.
>> + * Additional constraints may still apply.
>> + */
>> +enum intel_dc3co_trigger {
>> +	DC3CO_TRIGGER_NONE	     = 0,
>> +	DC3CO_TRIGGER_PSR2	     = BIT(0),
>> +	DC3CO_TRIGGER_LOBF	     = BIT(1),
>> +	DC3CO_TRIGGER_PANEL_REPLAY   = BIT(2),
>> +	DC3CO_TRIGGER_ALL  = DC3CO_TRIGGER_PSR2 |
>> +			     DC3CO_TRIGGER_LOBF |
>> +			     DC3CO_TRIGGER_PANEL_REPLAY,
>> +};
>> +
>>   struct i915_power_domains {
>>   	/*
>>   	 * Power wells needed for initialization at driver init and suspend
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum
  2026-04-14  7:11   ` Jani Nikula
@ 2026-04-20 12:17     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-20 12:17 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx, intel-xe
  Cc: animesh.manna, uma.shankar, suresh.kumar.kurmi


On 14-04-2026 12:41, Jani Nikula wrote:
> On Thu, 26 Mar 2026, Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com> wrote:
>> Fix HAS_DC3CO() based on display version and introduce an enum to
>> track DC3CO enabling triggers.
>>
>> BSpec: 75253
>> Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   .../gpu/drm/i915/display/intel_display_device.h   |  2 +-
>>   .../gpu/drm/i915/display/intel_display_power.h    | 15 +++++++++++++++
>>   2 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
>> index 35e06fcf794d..002fe0ce951a 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_device.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_device.h
>> @@ -189,7 +189,7 @@ struct intel_display_platforms {
>>   #define HAS_LRR(__display)		(DISPLAY_VER(__display) >= 12)
>>   #define HAS_LSPCON(__display)		(IS_DISPLAY_VER(__display, 9, 10))
>>   #define HAS_LT_PHY(__display)		((__display)->platform.novalake)
>> -#define HAS_DC3CO(__display)		((__display)->platform.novalake)
>> +#define HAS_DC3CO(__display)		(DISPLAY_VER(__display) >= 35)
>>   #define HAS_MBUS_JOINING(__display)	((__display)->platform.alderlake_p || DISPLAY_VER(__display) >= 14)
>>   #define HAS_MSO(__display)		(DISPLAY_VER(__display) >= 12)
>>   #define HAS_OVERLAY(__display)		(DISPLAY_INFO(__display)->has_overlay)
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
>> index d616d5d09cbe..3fb45154864e 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
>> @@ -131,6 +131,21 @@ struct intel_power_domain_mask {
>>   	DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);
>>   };
>>   
>> +/*
>> + * DC3CO enabling triggers (bitmask).
>> + * DC3CO may be enabled when at least one of these triggers is active.
>> + * Additional constraints may still apply.
>> + */
>> +enum intel_dc3co_trigger {
>> +	DC3CO_TRIGGER_NONE	     = 0,
>> +	DC3CO_TRIGGER_PSR2	     = BIT(0),
>> +	DC3CO_TRIGGER_LOBF	     = BIT(1),
>> +	DC3CO_TRIGGER_PANEL_REPLAY   = BIT(2),
>> +	DC3CO_TRIGGER_ALL  = DC3CO_TRIGGER_PSR2 |
>> +			     DC3CO_TRIGGER_LOBF |
>> +			     DC3CO_TRIGGER_PANEL_REPLAY,
>> +};
> Enumerations are enumerations and bitmasks are bitmasks, and I don't
> think they should be mixed like this.
>
> Moreover, the enum as a type isn't even used anywhere.
>
> BR,
> Jani.

I will move this definitions to #define and move the definitions to
the correct patch.

>
>
>> +
>>   struct i915_power_domains {
>>   	/*
>>   	 * Power wells needed for initialization at driver init and suspend

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support
  2026-04-13 21:18   ` Shankar, Uma
@ 2026-04-20 12:21     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-20 12:21 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 02:48, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support
>>
>> Add a helper to query DC3CO support from allowed_dc_mask.
> Change looks good but I feel this can be squashed with some earlier patches.

I will  squash this into patch 05.

>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_display_power.c | 7 +++++++
>> drivers/gpu/drm/i915/display/intel_display_power.h | 1 +
>>   2 files changed, 8 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
>> b/drivers/gpu/drm/i915/display/intel_display_power.c
>> index 12967db27c8d..a3b0c8ad8bb5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
>> @@ -365,6 +365,13 @@ u32 intel_display_power_get_current_dc_state(struct
>> intel_display *display)
>>   	return current_dc_state;
>>   }
>>
>> +bool intel_display_power_dc3co_supported(struct intel_display *display)
>> +{
>> +	struct i915_power_domains *power_domains = &display->power.domains;
>> +
>> +	return (power_domains->allowed_dc_mask &
>> DC_STATE_EN_UPTO_DC3CO) ==
>> +DC_STATE_EN_UPTO_DC3CO; }
>> +
>>   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 3fb45154864e..f57ce99a6039 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
>> @@ -201,6 +201,7 @@ 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_dc3co_supported(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	[flat|nested] 49+ messages in thread

* Re: [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state
  2026-04-13 21:44   ` Shankar, Uma
@ 2026-04-20 12:26     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-20 12:26 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 03:14, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from
>> intel_crtc_state
>>
>> Remove dc3co_exitline from struct intel_crtc_state, as it is not used anywhere in
>> the driver.
>>
>> Also remove the corresponding register read in intel_psr_get_config().
> Change Looks Good, but squash it with earlier patch (9) in the series.

I will squash this and patch 09 into patch 01,
as they all remove existing DC3CO structures.

>
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_display_types.h | 1 -
>>   drivers/gpu/drm/i915/display/intel_psr.c           | 1 -
>>   2 files changed, 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
>> b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 60366087038f..0a327c4df98d 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -1192,7 +1192,6 @@ struct intel_crtc_state {
>>   	bool pkg_c_latency_used;
>>   	/* Only used for state verification. */
>>   	enum intel_panel_replay_dsc_support panel_replay_dsc_support;
>> -	u32 dc3co_exitline;
>>   	u16 su_y_granularity;
>>   	u8 active_non_psr_pipes;
>>   	const char *no_psr_reason;
>> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
>> b/drivers/gpu/drm/i915/display/intel_psr.c
>> index 40adbd1c8ddc..987d49536548 100644
>> --- a/drivers/gpu/drm/i915/display/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
>> @@ -1822,7 +1822,6 @@ void intel_psr_get_config(struct intel_encoder
>> *encoder,
>>   	if (DISPLAY_VER(display) >= 12) {
>>   		val = intel_de_read(display,
>>   				    TRANS_EXITLINE(display, cpu_transcoder));
>> -		pipe_config->dc3co_exitline =
>> REG_FIELD_GET(EXITLINE_MASK, val);
>>   	}
>>   unlock:
>>   	mutex_unlock(&intel_dp->psr.lock);
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation
  2026-04-13 21:42   ` Shankar, Uma
@ 2026-04-22 14:35     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-22 14:35 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 03:12, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation
>>
>> Compute DC3CO eligibility during atomic_check based on pipe/port constraints
>> and runtime triggers, and propagate the result via intel_atomic_state.
>>
>> When DC3CO is allowed, request DC_STATE_EN_UPTO_DC3CO and reduce the
>> DC entry delay. Otherwise, retain the existing delay and set default
>> DC_STATE_EN_UPTO_DC6 .
> Specify reasoning for reducing delay, would be good to add as comment.

I will add reason as comment

>> BSpec: 75253
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_display.c  | 98 ++++++++++++++++++-
>> drivers/gpu/drm/i915/display/intel_display.h  |  2 +-
>>   .../drm/i915/display/intel_display_types.h    |  7 ++
>>   3 files changed, 101 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
>> b/drivers/gpu/drm/i915/display/intel_display.c
>> index f20d5ebe06ed..df0eaf6ae76b 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -5943,6 +5943,81 @@ static bool intel_pipes_need_modeset(struct
>> intel_atomic_state *state,
>>   	return false;
>>   }
>>
>> +bool intel_dc3co_allowed(struct intel_atomic_state *state) {
>> +	return state && state->dc3co.allowed;
>> +}
>> +
>> +static bool intel_dc3co_port_pipe_compatible(struct intel_dp *intel_dp,
>> +					     const struct intel_crtc_state
>> *crtc_state) {
>> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>> +	enum port port = dig_port->base.port;
>> +	int num_pipes = intel_crtc_num_joined_pipes(crtc_state);
>> +
>> +	return num_pipes == 1 && pipe <= PIPE_B && port <= PORT_B; }
>> +
>> +static void intel_dc3co_compute_state(struct intel_atomic_state *state)
>> +{
>> +	struct intel_display *display = to_intel_display(state);
>> +	struct intel_crtc *crtc;
>> +	struct intel_crtc_state *crtc_state;
>> +	struct intel_encoder *encoder;
>> +	struct intel_dp *intel_dp;
>> +	int active_pipes = 0;
>> +	u32 trigger = 0;
>> +
>> +	/* disable unless all conditions are met */
>> +	state->dc3co.trigger = DC3CO_TRIGGER_NONE;
>> +	state->dc3co.allowed = false;
>> +
>> +	if (!HAS_DC3CO(display))
>> +		return;
>> +
>> +	if (state->modeset)
>> +		return;
>> +
>> +	for_each_intel_crtc(display->drm, crtc) {
>> +		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
>> +		if (!crtc_state)
>> +			crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
>> +
>> +		if (!crtc_state || !crtc_state->hw.active)
>> +			continue;
>> +
>> +		active_pipes++;
>> +
>> +		if (active_pipes > 1)
>> +			return;
>> +
>> +		for_each_intel_encoder_mask(display->drm, encoder,
>> +					    crtc_state->uapi.encoder_mask) {
>> +			if (encoder->type != INTEL_OUTPUT_EDP)
>> +				return;
>> +
>> +			intel_dp = enc_to_intel_dp(encoder);
>> +
>> +			if (!intel_dc3co_port_pipe_compatible(intel_dp,
>> crtc_state))
>> +				return;
>> +		}
>> +
>> +		if (crtc_state->has_lobf)
>> +			trigger |= DC3CO_TRIGGER_LOBF;
>> +		if (crtc_state->has_panel_replay)
>> +			trigger |= DC3CO_TRIGGER_PANEL_REPLAY;
>> +		if (crtc_state->has_sel_update)
>> +			trigger |= DC3CO_TRIGGER_PSR2;
>> +	}
> Leave a blank line

will fix this.

>
>> +	if (trigger) {
>> +		state->dc3co.trigger = trigger;
> Here if we have 2 pipes, trigger will still get updated. Harmless but it doesn't look nice.
> Would be good to fix it to reflect default value for trigger if more than 1 crtc's.

when two pipes are active control wont reach here, It will return from
for loop itself.

>> +		state->dc3co.allowed = true;
>> +	}
> Here as well.
>
>> +	drm_dbg_kms(display->drm, "DC3CO allowed=%d trigger=0x%x\n",
>> +		    state->dc3co.allowed, state->dc3co.trigger); }
>> +
>>   static int intel_atomic_check_joiner(struct intel_atomic_state *state,
>>   				     struct intel_crtc *primary_crtc)  { @@ -6623,6
>> +6698,7 @@ int intel_atomic_check(struct drm_device *dev,
>>   	if (ret)
>>   		goto fail;
>>
>> +	intel_dc3co_compute_state(state);
>>   	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>>   					    new_crtc_state, i) {
>>   		intel_color_assert_luts(new_crtc_state);
>> @@ -7505,6 +7581,7 @@ static void intel_atomic_commit_tail(struct
>> intel_atomic_state *state)
>>   	struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {};
>>   	struct ref_tracker *wakeref = NULL;
>>   	int i;
>> +	int power_async_delay;
>>
>>   	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
>>   		intel_atomic_dsb_prepare(state, crtc); @@ -7711,11 +7788,22
>> @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>>   		 */
>>   		intel_uncore_arm_unclaimed_mmio_detection(uncore);
>>   	}
>> -	/*
>> -	 * Delay re-enabling DC states by 17 ms to avoid the off->on->off
>> -	 * toggling overhead at and above 60 FPS.
>> -	 */
>> -	intel_display_power_put_async_delay(display,
>> POWER_DOMAIN_DC_OFF, wakeref, 17);
>> +
>> +	if (intel_dc3co_allowed(state) &&
>> +	    intel_display_power_dc3co_supported(display)) {
>> +		intel_display_power_set_target_dc_state(display,
>> DC_STATE_EN_UPTO_DC3CO);
>> +		power_async_delay = 1;
> Add comment explaining reason for 1ms delay.

I will add comment.

> What happens if DC3Co was already enabled. Do we need to enable again at every commit ?

DC state is disabled in the beginning of this function, so it looks okay to re enable here.

>
>> +	} else {
>> +		/*
>> +		 * Delay re-enabling DC states by 17 ms to avoid the off->on->off
>> +		 * toggling overhead at and above 60 FPS.
>> +		 */
>> +		intel_display_power_set_target_dc_state(display,
>> DC_STATE_EN_UPTO_DC6);
>> +		power_async_delay = 17;
>> +	}
> Leave a blank line.
>
>> +	intel_display_power_put_async_delay(display,
>> +					    POWER_DOMAIN_DC_OFF, wakeref,
>> power_async_delay);
>> +
>>   	intel_display_rpm_put(display, state->wakeref);
>>
>>   	/*
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.h
>> b/drivers/gpu/drm/i915/display/intel_display.h
>> index 552a59d19e0f..6eb84f9d8791 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display.h
>> @@ -535,5 +535,5 @@ bool assert_port_valid(struct intel_display *display, enum
>> port port);
>>
>>   bool intel_scanout_needs_vtd_wa(struct intel_display *display);  int
>> intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state);
>> -
>> +bool intel_dc3co_allowed(struct intel_atomic_state *state);
>>   #endif
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
>> b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 6830f911d94d..6c7f5bbbc821 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -632,6 +632,11 @@ struct dpll {
>>   	int	p;
>>   };
>>
>> +struct intel_dc3co_state {
>> +	bool allowed; /* DC3CO eligibility result */
>> +	u32 trigger; /* Bitmask of active DC3CO triggers */ };
>> +
>>   struct intel_atomic_state {
>>   	struct drm_atomic_state base;
>>
>> @@ -658,6 +663,8 @@ struct intel_atomic_state {
>>   	bool rps_interactive;
>>
>>   	struct work_struct cleanup_work;
>> +
>> +	struct intel_dc3co_state dc3co;
> Atomic_state may not be the right place for this, check and place it at right structure.

I will dc3co from atomic state.

>
>>   };
>>
>>   struct intel_plane_state {
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO
  2026-04-13 21:56   ` Shankar, Uma
@ 2026-04-22 14:37     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-22 14:37 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 03:26, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO
>>
>> Force idle_frames to 0 when DC3CO is eligible.
>>
>> BSpec: 75253
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_psr.c | 9 ++++++---
>>   1 file changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
>> b/drivers/gpu/drm/i915/display/intel_psr.c
>> index bab254700a62..16a9f4111ac8 100644
>> --- a/drivers/gpu/drm/i915/display/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
>> @@ -1040,10 +1040,13 @@ static void hsw_activate_psr2(struct intel_dp
>> *intel_dp)
>>   	u32 psr_val = 0;
>>   	u8 idle_frames;
>>
>> +	/* DC3CO requires idle_frames = 0 */
>> +	if (intel_dp->psr.dc3co_eligible)
>> +		idle_frames = 0;
>>   	/* Wa_16025596647 */
>> -	if ((DISPLAY_VER(display) == 20 ||
>> -	     IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
>> &&
>> -	    is_dc5_dc6_blocked(intel_dp) && intel_dp->psr.pkg_c_latency_used)
>> +	else if ((DISPLAY_VER(display) == 20 ||
>> +		  IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0,
>> STEP_B0)) &&
>> +		 is_dc5_dc6_blocked(intel_dp) && intel_dp-
>>> psr.pkg_c_latency_used)
>>   		idle_frames = 0;
> This condition itself can be extended instead of a new if block.

I will add dc3co condition to the existing block.

>
>>   	else
>>   		idle_frames = psr_compute_idle_frames(intel_dp);
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM
  2026-04-13 21:58   ` Shankar, Uma
@ 2026-04-22 14:43     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-22 14:43 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 03:28, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM
>>
>> Set PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL when DC3CO is allowed.
> Change Looks Good, but squash this with patch 13.

I will squash this into path 13.

>
>> BSpec: 75253
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_alpm.c | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c
>> b/drivers/gpu/drm/i915/display/intel_alpm.c
>> index a7350ce8e716..9f92513a23c0 100644
>> --- a/drivers/gpu/drm/i915/display/intel_alpm.c
>> +++ b/drivers/gpu/drm/i915/display/intel_alpm.c
>> @@ -365,6 +365,9 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
>>   	struct intel_display *display = to_intel_display(intel_dp);
>>   	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>   	u32 alpm_ctl;
>> +	struct intel_atomic_state *state =
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>> +
>>
>>   	if (DISPLAY_VER(display) < 20 || (!intel_psr_needs_alpm(intel_dp,
>> crtc_state) &&
>>   					  !crtc_state->has_lobf))
>> @@ -389,6 +392,12 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
>>   			if (crtc_state->disable_as_sdp_when_pr_active)
>>   				pr_alpm_ctl |=
>> PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
>>
>> +			if (intel_dc3co_allowed(state) &&
>> +			    intel_display_power_dc3co_supported(display))
>> +				pr_alpm_ctl |=
>> PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
>> +			else
>> +				pr_alpm_ctl &=
>> ~PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
>> +
>>   			intel_de_write(display, PR_ALPM_CTL(display,
>> cpu_transcoder),
>>   				       pr_alpm_ctl);
>>   		}
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO
  2026-04-13 22:11   ` Shankar, Uma
@ 2026-04-22 14:53     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-22 14:53 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar

On 14-04-2026 03:41, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO
>>
>> For DC3CO, idle_frames is programmed to 0, so PSR does not enter deep sleep.
>> Add delayed work to schedule DC3CO exit after an idle duration derived from
>> frame time (minimum equivalent of 6 frames).
>>
>> The work is re-armed from the PSR flush path on relevant frontbuffer activity, and
>> once the display remains idle, DC3CO is disabled and DC6 is enabled to allow
>> deeper power savings.
>>
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   .../drm/i915/display/intel_display_types.h    |  2 +
>>   drivers/gpu/drm/i915/display/intel_psr.c      | 48 +++++++++++++++++++
>>   2 files changed, 50 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
>> b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index d0d2cda3d669..0c8958338f76 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -1785,6 +1785,8 @@ struct intel_psr {
>>   	bool irq_aux_error;
>>   	/* DC3CO eligibility used to control PSR configuration */
>>   	bool dc3co_eligible;
>> +	/* DC3CO disable work*/
> Add space before *
>
>> +	struct delayed_work dc3co_work;
>>   	u16 su_w_granularity;
>>   	u16 su_y_granularity;
>>   	bool source_panel_replay_support;
>> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
>> b/drivers/gpu/drm/i915/display/intel_psr.c
>> index 16a9f4111ac8..f3476118b8d0 100644
>> --- a/drivers/gpu/drm/i915/display/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
>> @@ -1701,6 +1701,50 @@ static bool intel_psr_needs_wa_18037818876(struct
>> intel_dp *intel_dp,
>>   		!crtc_state->has_sel_update);
>>   }
>>
>> +static void psr2_dc3co_disable_locked(struct intel_dp *intel_dp) {
>> +	struct intel_display *display = to_intel_display(intel_dp);
>> +
>> +	if (intel_dp->psr.dc3co_eligible) {
>> +		intel_dp->psr.dc3co_eligible = false;
>> +		intel_display_power_set_target_dc_state(display,
>> DC_STATE_EN_UPTO_DC6);
> Before switching to DC6, would be good to call cancel_delayed_work so that
> it doesn't get scheduled later and mess up the state.

This function is called frompsr2_dc3co_disable_work() itself, I will add cancel_delayed_work
to intel_psr_disable_locked().

>
>> +	}
>> +}
>> +
>> +static void psr2_dc3co_disable_work(struct work_struct *work) {
>> +	struct intel_dp *intel_dp =
>> +		container_of(work, typeof(*intel_dp), psr.dc3co_work.work);
>> +
>> +	mutex_lock(&intel_dp->psr.lock);
>> +	psr2_dc3co_disable_locked(intel_dp);
>> +	mutex_unlock(&intel_dp->psr.lock);
>> +}
>> +
>> +static void
>> +psr2_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
>> +			enum fb_op_origin origin)
>> +{
>> +	struct intel_display *display = to_intel_display(intel_dp);
>> +
>> +	if (!intel_dp->psr.dc3co_eligible)
>> +		return;
>> +
>> +	if (!intel_dp->psr.sel_update_enabled ||
>> +	    !intel_dp->psr.active)
>> +		return;
>> +	/*
>> +	 * At every frontbuffer flush flip event modified delay of delayed work,
>> +	 * when delayed work schedules that means display has been idle.
>> +	 */
>> +	if (!(frontbuffer_bits &
>> +	    INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe)))
>> +		return;
>> +
>> +	mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work,
>> +			 intel_dp->psr.dc3co_exit_delay);
> Where is this exit_delay assigned, please check. If its 0, work may get executed immediately.

It is assigned in intel_psr_enable_locked() along with other psr struct members.

>
>> +}
>> +
>>   static
>>   void intel_psr_set_non_psr_pipes(struct intel_dp *intel_dp,
>>   				 struct intel_crtc_state *crtc_state) @@ -2273,6
>> +2317,7 @@ void intel_psr_disable(struct intel_dp *intel_dp,
>>
>>   	mutex_unlock(&intel_dp->psr.lock);
>>   	cancel_work_sync(&intel_dp->psr.work);
>> +	cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
>>   }
>>
>>   /**
>> @@ -2303,6 +2348,7 @@ void intel_psr_pause(struct intel_dp *intel_dp)
>>   	mutex_unlock(&psr->lock);
>>
>>   	cancel_work_sync(&psr->work);
>> +	cancel_delayed_work_sync(&psr->dc3co_work);
>>   }
>>
>>   /**
>> @@ -3527,6 +3573,7 @@ void intel_psr_flush(struct intel_display *display,
>>   		if (origin == ORIGIN_FLIP ||
>>   		    (origin == ORIGIN_CURSOR_UPDATE &&
>>   		     !intel_dp->psr.psr2_sel_fetch_enabled)) {
>> +			psr2_dc3co_flush_locked(intel_dp, frontbuffer_bits,
>> origin);
>>   			goto unlock;
>>   		}
>>
>> @@ -3585,6 +3632,7 @@ void intel_psr_init(struct intel_dp *intel_dp)
>>   		intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link;
>>
>>   	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
>> +	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work,
>> psr2_dc3co_disable_work);
>>   	mutex_init(&intel_dp->psr.lock);
>>   }
>>
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from DC3CO
  2026-04-13 22:21   ` Shankar, Uma
@ 2026-04-22 14:56     ` Dibin Moolakadan Subrahmanian
  0 siblings, 0 replies; 49+ messages in thread
From: Dibin Moolakadan Subrahmanian @ 2026-04-22 14:56 UTC (permalink / raw)
  To: Shankar, Uma, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
  Cc: Manna, Animesh, Kurmi, Suresh Kumar


On 14-04-2026 03:51, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> Sent: Thursday, March 26, 2026 10:46 PM
>> To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
>> Cc: Manna, Animesh <animesh.manna@intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; Kurmi, Suresh Kumar
>> <suresh.kumar.kurmi@intel.com>
>> Subject: [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from
>> DC3CO
>>
>> After 6 idle frames, DC3CO is exited and DC6 is enabled.
>> Reprogram idle frames so that the deeper states can be entered.
> Change Looks good but should be squashed with earlier patches adding PSR2 idle frames.

I will squash this into patch 15.

>
>> Signed-off-by: Dibin Moolakadan Subrahmanian
>> <dibin.moolakadan.subrahmanian@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_psr.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
>> b/drivers/gpu/drm/i915/display/intel_psr.c
>> index f3476118b8d0..dcf33359dc9c 100644
>> --- a/drivers/gpu/drm/i915/display/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
>> @@ -1708,6 +1708,7 @@ static void psr2_dc3co_disable_locked(struct intel_dp
>> *intel_dp)
>>   	if (intel_dp->psr.dc3co_eligible) {
>>   		intel_dp->psr.dc3co_eligible = false;
>>   		intel_display_power_set_target_dc_state(display,
>> DC_STATE_EN_UPTO_DC6);
>> +		psr2_program_idle_frames(intel_dp,
>> psr_compute_idle_frames(intel_dp));
>>   	}
>>   }
>>
>> --
>> 2.43.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2026-04-22 14:56 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-26 17:15 [PATCH 00/19] drm/i915/display: Add DC3CO support Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 01/19] drm/i915/display: Remove TGL " Dibin Moolakadan Subrahmanian
2026-04-13 20:40   ` Shankar, Uma
2026-04-20 12:01     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 02/19] drm/i915/display: Replace DC_STATE_EN_DC3CO with DC_STATE_EN_UPTO_DC3CO Dibin Moolakadan Subrahmanian
2026-04-13 20:51   ` Shankar, Uma
2026-04-20 12:04     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 03/19] drm/i915/display: Use FIELD_PREP() for DC state enable bits Dibin Moolakadan Subrahmanian
2026-04-13 20:54   ` Shankar, Uma
2026-03-26 17:15 ` [PATCH 04/19] drm/i915/display: Add DC3CO DC_STATE enable/disable support Dibin Moolakadan Subrahmanian
2026-04-13 21:03   ` Shankar, Uma
2026-03-26 17:15 ` [PATCH 05/19] drm/i915/display: Validate target DC state against allowed_dc_mask Dibin Moolakadan Subrahmanian
2026-04-13 21:04   ` Shankar, Uma
2026-03-26 17:15 ` [PATCH 06/19] drm/i915/display: Fix HAS_DC3CO() and add DC3CO trigger enum Dibin Moolakadan Subrahmanian
2026-04-13 21:16   ` Shankar, Uma
2026-04-20 12:12     ` Dibin Moolakadan Subrahmanian
2026-04-14  7:11   ` Jani Nikula
2026-04-20 12:17     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 07/19] drm/i915/display: Add helper to check DC3CO support Dibin Moolakadan Subrahmanian
2026-04-13 21:18   ` Shankar, Uma
2026-04-20 12:21     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 08/19] drm/i915/display: Add DC3CO eligibility computation Dibin Moolakadan Subrahmanian
2026-04-13 21:42   ` Shankar, Uma
2026-04-22 14:35     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 09/19] drm/i915/display: Remove unused PSR dc3co_exitline field Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 10/19] drm/i915/display: Remove unused dc3co_exitline from intel_crtc_state Dibin Moolakadan Subrahmanian
2026-04-13 21:44   ` Shankar, Uma
2026-04-20 12:26     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 11/19] drm/i915/display: Store DC3CO eligibility in PSR state Dibin Moolakadan Subrahmanian
2026-04-13 21:54   ` Shankar, Uma
2026-03-26 17:15 ` [PATCH 12/19] drm/i915/display: PSR2: Set idle_frames to 0 for DC3CO Dibin Moolakadan Subrahmanian
2026-04-13 21:56   ` Shankar, Uma
2026-04-22 14:37     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 13/19] drm/i915/display: Define DC3CO idle protocol bit in PR_ALPM_CTL Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 14/19] drm/i915/display: Enable DC3CO idle protocol in ALPM Dibin Moolakadan Subrahmanian
2026-04-13 21:58   ` Shankar, Uma
2026-04-22 14:43     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 15/19] drm/i915/display: PSR Add delayed work to exit DC3CO Dibin Moolakadan Subrahmanian
2026-04-13 22:11   ` Shankar, Uma
2026-04-22 14:53     ` Dibin Moolakadan Subrahmanian
2026-03-26 17:15 ` [PATCH 16/19] drm/i915/display: Add helper to enable DC counter Dibin Moolakadan Subrahmanian
2026-04-13 22:14   ` Shankar, Uma
2026-03-26 17:15 ` [PATCH 17/19] drm/i915/display: Remove DC3CO DMC debugfs Dibin Moolakadan Subrahmanian
2026-04-13 22:17   ` Shankar, Uma
2026-03-26 17:15 ` [PATCH 18/19] drm/i915/display: Add DC3CO count and residency in dmc debugfs Dibin Moolakadan Subrahmanian
2026-04-13 22:19   ` Shankar, Uma
2026-03-26 17:15 ` [PATCH 19/19] drm/i915/display: PSR set idle frames while exit from DC3CO Dibin Moolakadan Subrahmanian
2026-04-13 22:21   ` Shankar, Uma
2026-04-22 14:56     ` Dibin Moolakadan Subrahmanian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox