public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH 00/15] Optimize vrr.guardband and fix LRR
@ 2025-09-28  7:05 Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 01/15] drm/i915/vrr: Use crtc_vsync_start/end for computing vrr.vsync_start/end Ankit Nautiyal
                   ` (15 more replies)
  0 siblings, 16 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal

Instead of setting vrr.guardband to vblank, use optimal guardband that
works for most of the cases. This will help in avoiding need of change
in guardband and fix the LRR feature that needs seamless switching to
a lower refresh rate.

First few patches fix/refactor and extract common functions required for
dsc/scaler prefill time computation. Later patches use these helpers to
compute an optimized guardband.

Also, for seamless_mn where vtotal is same but mode clock is changed to
seamlessly switch to lower rate, re-compute the vrr timings.

Few things that still need work:
-The timestamps corresponding with next start of vactive still need to be
fixed with the new scheme.
-Re-enabling CMRR

Rev2:
-Address comments from Mitul.
-Extract helpers for dsc/scaler prefill latencies.
-Fix downscaling factor for chroma subsampling.
-Use missing pkg C max latency.
-Fix guardband computation for seamless mn, always use vblank for
higher resolution.

Rev3:
-Drop patches for computing and storing PSR/Panel Replay wake times
latencies and use existing helpers to compute these in intel_alpm.c.
-Drop patch to change the Vmin as it was not required.

Rev4:
-Rebase
-Drop patch for checking bounds for scaler array access.
-Use a new flag for setting vrr timings for seamless drrs.

Rev5:
-Address comments from Mitul, Jani:
-Refactor few helpers for computing latencies.
-Rename the helper to check the guardband to intel_crtc_guardband_atomic_check()
-Refactor the helper intel_panel_highest_mode().

Rev6:
-Rebase
-Address review comments from Mitul.
-Improve documentation for and other minor fixes in Patch#12

Rev7:
-Address comments from Jani.
-Move the latency helpers from intel_display.c to intel_vrr.c and rename
the helpers appropriately.
-Drop redundant check for HAS_VRR with intel_vrr_possible().

Rev8:
-Fix CI issues.
-For fixed RR wait for delayed vblank before dsb interrupt.

Rev9:
-Fix vrr.vsync_start/end timings for 3D modes (patch#1)
-Rewrite the patch to wait for delayed vblank before dsb interrupt
(patch #11)
-Fix the flipline and vmin timings with optimized guardband (patch#12)

Rev10:
-Address comments from Ville: Use min guardband computation for setting
the vblank delay and set the crtc_vblank_start to delayed vblank.
(Patch#13)
-Modify the TRANS_SET_CONTEXT_LATENCY as per new guardband and use
vrr.guardband to readback vblank_start. (Patch#11)

-From previous revision:
->Drop patch#11 "drm/i915/dsb: Align flipdone with delayed vblank using
guardband wait", as this is no longer required.
->Modify Patch#12 "drm/i915/vrr: Use static guardband to support seamless
LRR switching" to only introduce a helper to compute the fix guardband.
Modify the commit message and the subject.

Rev11:
-Drop patches that are no longer required:
 -Patch for clamping SCL.
 -Patch to use vrr.vsync to compute vtotal
-Use guardband check for all platforms supporting VRR. (Patch#8)
-Add new patch to determine when to use optimized guardband. (Patch#11)
 Use optimized guardband whenever the VRR TG is active.
-Separate out patch to recompute the vblank start for optimized
 guardband. (Patch#12)

Rev12:
-Address issue with VRR for platforms which do not have VRR TG always
 active. For such platforms when switching to VRR, the vblank start is
 shifted for optimizing/reducing the guardband. This causes mismatch
 between old and new CRTC states and triggering unnecessary full modesets.
-Rename allow_vblank_delay_fastset() to allow_vblank_delay_fastset_lrr() to
 clarify its role in handling vblank delay via LRR codepaths. (Patch#14)
-Introduce allow_vblank_delay_fastset() to extend the logic and allow
 vblank delay when optimized guardband is used. (Patch#15)

Ankit Nautiyal (15):
  drm/i915/vrr: Use crtc_vsync_start/end for computing
    vrr.vsync_start/end
  drm/i915/skl_watermark: Fix the scaling factor for chroma subsampling
  drm/i915/skl_watermark: Pass linetime as argument to latency helpers
  drm/i915/skl_scaler: Introduce helper for chroma downscale factor
  drm/i915/display: Extract helpers to set dsc/scaler prefill latencies
  drm/i915/dp: Add SDP latency computation helper
  drm/i915/alpm: Add function to compute max link-wake latency
  drm/i915/display: Add guardband check for feature latencies
  drm/i915/skl_watermark: Remove redundant latency checks from vblank
    validation
  drm/i915/vrr: Introduce helper to compute min static guardband
  drm/i915/vrr: Use optimized guardband when VRR TG is active
  drm/i915/vrr: Prepare for movement of vblank start for optimized
    guardband
  drm/i915/display: Recompute crtc_vblank_start for optimized guardband
  drm/i915/display:
    s/allow_vblank_delay_fastset/allow_vblank_delay_fastset_lrr
  drm/i915/display: Use optimized guardband to set vblank start

 drivers/gpu/drm/i915/display/intel_alpm.c    |  15 ++
 drivers/gpu/drm/i915/display/intel_alpm.h    |   2 +
 drivers/gpu/drm/i915/display/intel_display.c | 230 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_dp.c      |  47 ++++
 drivers/gpu/drm/i915/display/intel_dp.h      |   2 +
 drivers/gpu/drm/i915/display/intel_vdsc.c    |  17 ++
 drivers/gpu/drm/i915/display/intel_vdsc.h    |   4 +
 drivers/gpu/drm/i915/display/intel_vrr.c     | 146 +++++++++++-
 drivers/gpu/drm/i915/display/intel_vrr.h     |   3 +
 drivers/gpu/drm/i915/display/skl_scaler.c    |  21 ++
 drivers/gpu/drm/i915/display/skl_scaler.h    |  10 +
 drivers/gpu/drm/i915/display/skl_watermark.c |  89 +------
 drivers/gpu/drm/i915/display/skl_watermark.h |   1 +
 13 files changed, 491 insertions(+), 96 deletions(-)

-- 
2.45.2


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

* [PATCH 01/15] drm/i915/vrr: Use crtc_vsync_start/end for computing vrr.vsync_start/end
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 02/15] drm/i915/skl_watermark: Fix the scaling factor for chroma subsampling Ankit Nautiyal
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Uma Shankar

Use adjusted_mode->crtc_vsync_start/end instead of
adjusted_mode->vsync_start while computing vrr.vsync_start/end.
For most modes, these are same but for 3D/stereo modes the
crtc_vsync_start is different than vsync_start.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 190c51be5cbc..4bc14b5e685f 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -394,10 +394,10 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
 	if (HAS_AS_SDP(display)) {
 		crtc_state->vrr.vsync_start =
 			(crtc_state->hw.adjusted_mode.crtc_vtotal -
-			 crtc_state->hw.adjusted_mode.vsync_start);
+			 crtc_state->hw.adjusted_mode.crtc_vsync_start);
 		crtc_state->vrr.vsync_end =
 			(crtc_state->hw.adjusted_mode.crtc_vtotal -
-			 crtc_state->hw.adjusted_mode.vsync_end);
+			 crtc_state->hw.adjusted_mode.crtc_vsync_end);
 	}
 }
 
-- 
2.45.2


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

* [PATCH 02/15] drm/i915/skl_watermark: Fix the scaling factor for chroma subsampling
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 01/15] drm/i915/vrr: Use crtc_vsync_start/end for computing vrr.vsync_start/end Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 03/15] drm/i915/skl_watermark: Pass linetime as argument to latency helpers Ankit Nautiyal
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

The Bspec:70151, mentions Chroma subsampling is a 2x downscale
operation. This means that the downscale factor is 2 in each direction.
So correct the downscaling factor to 4.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 9eb28d935757..4b1ef4fa8ed2 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -2188,7 +2188,7 @@ dsc_prefill_latency(const struct intel_crtc_state *crtc_state)
 				    crtc_state->hw.adjusted_mode.clock);
 	int num_scaler_users = hweight32(scaler_state->scaler_users);
 	int chroma_downscaling_factor =
-		crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1;
+		crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 4 : 1;
 	u32 dsc_prefill_latency = 0;
 
 	if (!crtc_state->dsc.compression_enable ||
@@ -2231,7 +2231,7 @@ scaler_prefill_latency(const struct intel_crtc_state *crtc_state)
 		u64 hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16);
 		u64 vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16);
 		int chroma_downscaling_factor =
-			crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1;
+			crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 4 : 1;
 		int latency;
 
 		latency = DIV_ROUND_UP_ULL((4 * linetime * hscale_k * vscale_k *
-- 
2.45.2


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

* [PATCH 03/15] drm/i915/skl_watermark: Pass linetime as argument to latency helpers
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 01/15] drm/i915/vrr: Use crtc_vsync_start/end for computing vrr.vsync_start/end Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 02/15] drm/i915/skl_watermark: Fix the scaling factor for chroma subsampling Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 04/15] drm/i915/skl_scaler: Introduce helper for chroma downscale factor Ankit Nautiyal
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

Refactor dsc_prefill_latency and scaler_prefill_latency to take
linetime as an explicit parameter instead of computing it internally.

This avoids redundant calculations and simplifies scanline conversion
logic in skl_is_vblank_too_short().

This change also facilitates future extraction of these helpers for use
cases where latencies are computed for an optimized guardband, based on the
highest resolution mode, rather than the current mode.

v2: Sum all latency numbers and use intel_usecs_to_scanlines() to
convert to scanlines. (Ville).

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 4b1ef4fa8ed2..be87a861eb70 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -2179,13 +2179,11 @@ cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state)
 }
 
 static int
-dsc_prefill_latency(const struct intel_crtc_state *crtc_state)
+dsc_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	const struct intel_crtc_scaler_state *scaler_state =
 					&crtc_state->scaler_state;
-	int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal,
-				    crtc_state->hw.adjusted_mode.clock);
 	int num_scaler_users = hweight32(scaler_state->scaler_users);
 	int chroma_downscaling_factor =
 		crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 4 : 1;
@@ -2209,18 +2207,16 @@ dsc_prefill_latency(const struct intel_crtc_state *crtc_state)
 
 	dsc_prefill_latency *= cdclk_prefill_adjustment(crtc_state);
 
-	return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, dsc_prefill_latency);
+	return dsc_prefill_latency;
 }
 
 static int
-scaler_prefill_latency(const struct intel_crtc_state *crtc_state)
+scaler_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 {
 	const struct intel_crtc_scaler_state *scaler_state =
 					&crtc_state->scaler_state;
 	int num_scaler_users = hweight32(scaler_state->scaler_users);
 	int scaler_prefill_latency = 0;
-	int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal,
-				    crtc_state->hw.adjusted_mode.clock);
 
 	if (!num_scaler_users)
 		return scaler_prefill_latency;
@@ -2241,7 +2237,7 @@ scaler_prefill_latency(const struct intel_crtc_state *crtc_state)
 
 	scaler_prefill_latency *= cdclk_prefill_adjustment(crtc_state);
 
-	return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, scaler_prefill_latency);
+	return scaler_prefill_latency;
 }
 
 static bool
@@ -2250,11 +2246,14 @@ skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state,
 {
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
+	int linetime = DIV_ROUND_UP(1000 * adjusted_mode->htotal,
+				    adjusted_mode->clock);
+
+	latency += scaler_prefill_latency(crtc_state, linetime) +
+		   dsc_prefill_latency(crtc_state, linetime);
 
 	return crtc_state->framestart_delay +
 		intel_usecs_to_scanlines(adjusted_mode, latency) +
-		scaler_prefill_latency(crtc_state) +
-		dsc_prefill_latency(crtc_state) +
 		wm0_lines >
 		adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start;
 }
-- 
2.45.2


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

* [PATCH 04/15] drm/i915/skl_scaler: Introduce helper for chroma downscale factor
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (2 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 03/15] drm/i915/skl_watermark: Pass linetime as argument to latency helpers Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 05/15] drm/i915/display: Extract helpers to set dsc/scaler prefill latencies Ankit Nautiyal
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

For 444 to 420 output format conversion, scaler uses 2x downscaling in
each direction. Introduce skl_scaler_chroma_downscale_factor() to
encapsulate the chroma subsampling adjustment used in scaler/dsc
pre-fill latency calculations.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
 drivers/gpu/drm/i915/display/skl_scaler.c    | 5 +++++
 drivers/gpu/drm/i915/display/skl_scaler.h    | 3 +++
 drivers/gpu/drm/i915/display/skl_watermark.c | 7 +++----
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c
index c6cccf170ff1..af2cbd54c32e 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.c
+++ b/drivers/gpu/drm/i915/display/skl_scaler.c
@@ -968,3 +968,8 @@ void adl_scaler_ecc_unmask(const struct intel_crtc_state *crtc_state)
 			  1);
 	intel_de_write(display, XELPD_DISPLAY_ERR_FATAL_MASK, 0);
 }
+
+int skl_scaler_chroma_downscale_factor(const struct intel_crtc_state *crtc_state)
+{
+	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 4 : 1;
+}
diff --git a/drivers/gpu/drm/i915/display/skl_scaler.h b/drivers/gpu/drm/i915/display/skl_scaler.h
index 12a19016c5f6..257330d4c329 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.h
+++ b/drivers/gpu/drm/i915/display/skl_scaler.h
@@ -45,4 +45,7 @@ skl_scaler_mode_valid(struct intel_display *display,
 void adl_scaler_ecc_mask(const struct intel_crtc_state *crtc_state);
 
 void adl_scaler_ecc_unmask(const struct intel_crtc_state *crtc_state);
+
+int skl_scaler_chroma_downscale_factor(const struct intel_crtc_state *crtc_state);
+
 #endif
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index be87a861eb70..2da54569f06a 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -30,6 +30,7 @@
 #include "intel_plane.h"
 #include "intel_wm.h"
 #include "skl_universal_plane_regs.h"
+#include "skl_scaler.h"
 #include "skl_watermark.h"
 #include "skl_watermark_regs.h"
 
@@ -2185,8 +2186,7 @@ dsc_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 	const struct intel_crtc_scaler_state *scaler_state =
 					&crtc_state->scaler_state;
 	int num_scaler_users = hweight32(scaler_state->scaler_users);
-	int chroma_downscaling_factor =
-		crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 4 : 1;
+	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
 	u32 dsc_prefill_latency = 0;
 
 	if (!crtc_state->dsc.compression_enable ||
@@ -2226,8 +2226,7 @@ scaler_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 	if (num_scaler_users > 1) {
 		u64 hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16);
 		u64 vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16);
-		int chroma_downscaling_factor =
-			crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 4 : 1;
+		int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
 		int latency;
 
 		latency = DIV_ROUND_UP_ULL((4 * linetime * hscale_k * vscale_k *
-- 
2.45.2


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

* [PATCH 05/15] drm/i915/display: Extract helpers to set dsc/scaler prefill latencies
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (3 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 04/15] drm/i915/skl_scaler: Introduce helper for chroma downscale factor Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 06/15] drm/i915/dp: Add SDP latency computation helper Ankit Nautiyal
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

Currently dsc/scaler prefill latencies are handled during watermark
calculations. With the optimized guardband, we need to compute the
latencies to find the minimum guardband that works for most cases.
Extract the helpers to compute these latencies, so that they can be used
while computing vrr guardband.

While at it, put declarations in reverse xmas tree order for better
redability.

v2: Initialize {h,v}scale_k to 0, and simplify the check in
intel_display_scaler_prefill_latency(). (Mitul)

v3: Move helpers from intel_display.c to intel_vrr.c as they are specific
to account for latencies to program vrr guardband. (Jani)

v4: Move helpers to dsc/scaler files. (Ville)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
 drivers/gpu/drm/i915/display/intel_vdsc.c    | 17 +++++++
 drivers/gpu/drm/i915/display/intel_vdsc.h    |  4 ++
 drivers/gpu/drm/i915/display/skl_scaler.c    | 16 +++++++
 drivers/gpu/drm/i915/display/skl_scaler.h    |  7 +++
 drivers/gpu/drm/i915/display/skl_watermark.c | 47 +++++++++-----------
 5 files changed, 66 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 8e799e225af1..e59d62994798 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -1077,3 +1077,20 @@ int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
 
 	return min_cdclk;
 }
+
+int intel_dsc_guardband_latency(int num_scaler_users, u64 *hscale, u64 *vscale,
+				int chroma_downscaling_factor,
+				int cdclk_prefill_adjustment,
+				int linetime)
+{
+	int dsc_prefill_latency;
+
+	dsc_prefill_latency = DIV_ROUND_UP(15 * linetime * chroma_downscaling_factor, 10);
+
+	for (int i = 0; i < num_scaler_users; i++)
+		dsc_prefill_latency = DIV_ROUND_UP_ULL(dsc_prefill_latency * hscale[i] * vscale[i],
+						       1000000);
+	dsc_prefill_latency *= cdclk_prefill_adjustment;
+
+	return dsc_prefill_latency;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 9e2812f99dd7..60aecadf95bf 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -32,5 +32,9 @@ void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
 void intel_vdsc_state_dump(struct drm_printer *p, int indent,
 			   const struct intel_crtc_state *crtc_state);
 int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state);
+int intel_dsc_guardband_latency(int num_scaler_users, u64 *hscale, u64 *vscale,
+				int chroma_downscaling_factor,
+				int cdclk_prefill_adjustment,
+				int linetime);
 
 #endif /* __INTEL_VDSC_H__ */
diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c
index af2cbd54c32e..69130744c09e 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.c
+++ b/drivers/gpu/drm/i915/display/skl_scaler.c
@@ -973,3 +973,19 @@ int skl_scaler_chroma_downscale_factor(const struct intel_crtc_state *crtc_state
 {
 	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 4 : 1;
 }
+
+int skl_scaler_guardband_latency(int num_scaler_users, u64 hscale, u64 vscale,
+				 int chroma_downscaling_factor,
+				 int cdclk_prefill_adjustment,
+				 int linetime)
+{
+	int scaler_prefill_latency;
+
+	scaler_prefill_latency = 4 * linetime +
+				 DIV_ROUND_UP_ULL((4 * linetime * hscale * vscale *
+						   chroma_downscaling_factor), 1000000);
+
+	scaler_prefill_latency *= cdclk_prefill_adjustment;
+
+	return scaler_prefill_latency;
+}
diff --git a/drivers/gpu/drm/i915/display/skl_scaler.h b/drivers/gpu/drm/i915/display/skl_scaler.h
index 257330d4c329..5aa53d576aba 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.h
+++ b/drivers/gpu/drm/i915/display/skl_scaler.h
@@ -5,6 +5,8 @@
 #ifndef INTEL_SCALER_H
 #define INTEL_SCALER_H
 
+#include <linux/types.h>
+
 enum drm_mode_status;
 struct drm_display_mode;
 struct intel_atomic_state;
@@ -48,4 +50,9 @@ void adl_scaler_ecc_unmask(const struct intel_crtc_state *crtc_state);
 
 int skl_scaler_chroma_downscale_factor(const struct intel_crtc_state *crtc_state);
 
+int skl_scaler_guardband_latency(int num_scaler_users, u64 hscale, u64 vscale,
+				 int chroma_downscaling_factor,
+				 int cdclk_prefill_adjustment,
+				 int linetime);
+
 #endif
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 2da54569f06a..deb43f0c348a 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -28,6 +28,7 @@
 #include "intel_flipq.h"
 #include "intel_pcode.h"
 #include "intel_plane.h"
+#include "intel_vdsc.h"
 #include "intel_wm.h"
 #include "skl_universal_plane_regs.h"
 #include "skl_scaler.h"
@@ -2182,11 +2183,12 @@ cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state)
 static int
 dsc_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 {
+	const struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
+	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	const struct intel_crtc_scaler_state *scaler_state =
-					&crtc_state->scaler_state;
 	int num_scaler_users = hweight32(scaler_state->scaler_users);
-	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
+	u64 hscale_k[ARRAY_SIZE(scaler_state->scalers)];
+	u64 vscale_k[ARRAY_SIZE(scaler_state->scalers)];
 	u32 dsc_prefill_latency = 0;
 
 	if (!crtc_state->dsc.compression_enable ||
@@ -2194,18 +2196,16 @@ dsc_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 	    num_scaler_users > crtc->num_scalers)
 		return dsc_prefill_latency;
 
-	dsc_prefill_latency = DIV_ROUND_UP(15 * linetime * chroma_downscaling_factor, 10);
-
 	for (int i = 0; i < num_scaler_users; i++) {
-		u64 hscale_k, vscale_k;
-
-		hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16);
-		vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16);
-		dsc_prefill_latency = DIV_ROUND_UP_ULL(dsc_prefill_latency * hscale_k * vscale_k,
-						       1000000);
+		hscale_k[i] = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16);
+		vscale_k[i] = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16);
 	}
 
-	dsc_prefill_latency *= cdclk_prefill_adjustment(crtc_state);
+	dsc_prefill_latency =
+		intel_dsc_guardband_latency(num_scaler_users, hscale_k, vscale_k,
+					    chroma_downscaling_factor,
+					    cdclk_prefill_adjustment(crtc_state),
+					    linetime);
 
 	return dsc_prefill_latency;
 }
@@ -2213,28 +2213,25 @@ dsc_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 static int
 scaler_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
 {
-	const struct intel_crtc_scaler_state *scaler_state =
-					&crtc_state->scaler_state;
+	const struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
+	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
 	int num_scaler_users = hweight32(scaler_state->scaler_users);
+	u64 hscale_k = 0, vscale_k = 0;
 	int scaler_prefill_latency = 0;
 
 	if (!num_scaler_users)
 		return scaler_prefill_latency;
 
-	scaler_prefill_latency = 4 * linetime;
-
 	if (num_scaler_users > 1) {
-		u64 hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16);
-		u64 vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16);
-		int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
-		int latency;
-
-		latency = DIV_ROUND_UP_ULL((4 * linetime * hscale_k * vscale_k *
-					    chroma_downscaling_factor), 1000000);
-		scaler_prefill_latency += latency;
+		hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16);
+		vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16);
 	}
 
-	scaler_prefill_latency *= cdclk_prefill_adjustment(crtc_state);
+	scaler_prefill_latency =
+		skl_scaler_guardband_latency(num_scaler_users, hscale_k, vscale_k,
+					     chroma_downscaling_factor,
+					     cdclk_prefill_adjustment(crtc_state),
+					     linetime);
 
 	return scaler_prefill_latency;
 }
-- 
2.45.2


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

* [PATCH 06/15] drm/i915/dp: Add SDP latency computation helper
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (4 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 05/15] drm/i915/display: Extract helpers to set dsc/scaler prefill latencies Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 07/15] drm/i915/alpm: Add function to compute max link-wake latency Ankit Nautiyal
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

Add a helper to compute vblank time needed for transmitting specific
DisplayPort SDPs like PPS, GAMUT_METADATA, and VSC_EXT. Latency is
based on line count per packet type and current line time.

Used to ensure adequate vblank when features like DSC/HDR are enabled.

Bspec: 70151
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 47 +++++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.h |  2 ++
 2 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 2eab591a8ef5..83c46e4680b3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6857,3 +6857,50 @@ void intel_dp_mst_resume(struct intel_display *display)
 		}
 	}
 }
+
+static
+int intel_dp_get_sdp_latency(u32 type, int linetime_us)
+{
+	int lines;
+
+	switch (type) {
+	case DP_SDP_VSC_EXT_VESA:
+	case DP_SDP_VSC_EXT_CEA:
+		lines = 10;
+		break;
+	case HDMI_PACKET_TYPE_GAMUT_METADATA:
+		lines = 8;
+		break;
+	case DP_SDP_PPS:
+		lines = 6;
+		break;
+	default:
+		lines = 0;
+		break;
+	}
+
+	return lines * linetime_us;
+}
+
+int intel_dp_compute_sdp_latency(const struct intel_crtc_state *crtc_state,
+				 bool assume_all_enabled)
+{
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+	int sdp_latency = 0;
+	int linetime_us;
+
+	linetime_us = DIV_ROUND_UP(adjusted_mode->crtc_htotal * 1000,
+				   adjusted_mode->crtc_clock);
+	if (assume_all_enabled ||
+	    crtc_state->infoframes.enable &
+	    intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA))
+		sdp_latency = max(sdp_latency,
+				  intel_dp_get_sdp_latency(HDMI_PACKET_TYPE_GAMUT_METADATA,
+							   linetime_us));
+
+	if (assume_all_enabled || crtc_state->dsc.compression_enable)
+		sdp_latency = max(sdp_latency,
+				  intel_dp_get_sdp_latency(DP_SDP_PPS, linetime_us));
+
+	return sdp_latency;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index f90cfd1dbbd0..d222749b191c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -215,5 +215,7 @@ int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state,
 int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector);
 void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool force_on_external);
 bool intel_dp_in_hdr_mode(const struct drm_connector_state *conn_state);
+int intel_dp_compute_sdp_latency(const struct intel_crtc_state *crtc_state,
+				 bool assume_all_enabled);
 
 #endif /* __INTEL_DP_H__ */
-- 
2.45.2


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

* [PATCH 07/15] drm/i915/alpm: Add function to compute max link-wake latency
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (5 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 06/15] drm/i915/dp: Add SDP latency computation helper Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 08/15] drm/i915/display: Add guardband check for feature latencies Ankit Nautiyal
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

Introduce a helper to compute the max link wake latency when using
Auxless/Aux wake mechanism for PSR/Panel Replay/LOBF features.

This will be used to compute the minimum guardband so that the link wake
latencies are accounted and these features work smoothly for higher
refresh rate panels.

Bspec: 70151, 71477
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
 drivers/gpu/drm/i915/display/intel_alpm.c | 15 +++++++++++++++
 drivers/gpu/drm/i915/display/intel_alpm.h |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
index 749119cc0b28..df380ecf7d0f 100644
--- a/drivers/gpu/drm/i915/display/intel_alpm.c
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -598,3 +598,18 @@ bool intel_alpm_get_error(struct intel_dp *intel_dp)
 
 	return false;
 }
+
+int intel_alpm_compute_max_link_wake_latency(const struct intel_crtc_state *crtc_state,
+					     bool assume_all_enabled)
+{
+	int psr2_vblank_time = 0;
+	int auxless_wake_time = 0;
+
+	if (assume_all_enabled || crtc_state->has_sel_update)
+		psr2_vblank_time =  io_buffer_wake_time(crtc_state);
+
+	if (assume_all_enabled || crtc_state->has_panel_replay)
+		auxless_wake_time = _lnl_compute_aux_less_wake_time(crtc_state);
+
+	return max(psr2_vblank_time, auxless_wake_time);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.h b/drivers/gpu/drm/i915/display/intel_alpm.h
index a861c20b5d79..b371827af356 100644
--- a/drivers/gpu/drm/i915/display/intel_alpm.h
+++ b/drivers/gpu/drm/i915/display/intel_alpm.h
@@ -38,4 +38,6 @@ bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp,
 				 const struct intel_crtc_state *crtc_state);
 void intel_alpm_disable(struct intel_dp *intel_dp);
 bool intel_alpm_get_error(struct intel_dp *intel_dp);
+int intel_alpm_compute_max_link_wake_latency(const struct intel_crtc_state *crtc_state,
+					     bool assume_all_enabled);
 #endif
-- 
2.45.2


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

* [PATCH 08/15] drm/i915/display: Add guardband check for feature latencies
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (6 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 07/15] drm/i915/alpm: Add function to compute max link-wake latency Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 09/15] drm/i915/skl_watermark: Remove redundant latency checks from vblank validation Ankit Nautiyal
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

Add a check during atomic crtc check phase to ensure the programmed VRR
guardband is sufficient to cover latencies introduced by enabled features
such as DSC, PSR/PR, scalers, and DP SDPs.

Currently, the guardband is programmed to match the vblank length, so
existing checks in skl_is_vblank_too_short() are valid. However, upcoming
changes will optimize the guardband independently of vblank, making those
checks incorrect.

Introduce an explicit guardband check to prepare for future updates
that will remove checking against the vblank length and later program an
optimized guardband.

Note: Need some work to account for package C state latency and the use
of PKG_C_Latency register. When PKG_C_LATENCY is configured hardware will
automatically wake from package C states before framestart so that
package C state latency can be considered to be 0.

v2: Use new helper for PSR2/Panel Replay latency.

v3:
- Align the name of helper with intel_crtc_atomic_check and rename it to
  intel_crtc_guardband_atomic_check(). (Jani)
- Simplify checks in the helper. (Mitul)
- Make a separate helper to compute wm0 prefill time. (Mitul)

v4: Drop redundant HAS_VRR() check. (Jani).

v5:
- Use intel_usecs_to_scanlines() instead of hand rolled stuff. (Ville)
- Allow guardband check on all VRR supporting platforms.
- Add a TODO note for accounting for pkgc latency.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com> (#v3)
---
 drivers/gpu/drm/i915/display/intel_display.c | 147 +++++++++++++++++++
 drivers/gpu/drm/i915/display/skl_watermark.c |   2 +-
 drivers/gpu/drm/i915/display/skl_watermark.h |   1 +
 3 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b57efd870774..ec415b939770 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4189,6 +4189,147 @@ static int hsw_compute_linetime_wm(struct intel_atomic_state *state,
 	return 0;
 }
 
+static int
+cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_display *display = to_intel_display(crtc_state);
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(crtc_state->uapi.state);
+	const struct intel_cdclk_state *cdclk_state;
+
+	cdclk_state = intel_atomic_get_cdclk_state(state);
+	if (IS_ERR(cdclk_state)) {
+		drm_WARN_ON(display->drm, PTR_ERR(cdclk_state));
+		return 1;
+	}
+
+	return min(1, DIV_ROUND_UP(crtc_state->pixel_rate,
+				   2 * intel_cdclk_logical(cdclk_state)));
+}
+
+static int
+dsc_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
+{
+	const struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
+	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	int num_scaler_users = hweight32(scaler_state->scaler_users);
+	u64 hscale_k[ARRAY_SIZE(scaler_state->scalers)];
+	u64 vscale_k[ARRAY_SIZE(scaler_state->scalers)];
+	u32 dsc_prefill_latency = 0;
+
+	if (!crtc_state->dsc.compression_enable ||
+	    !num_scaler_users ||
+	    num_scaler_users > crtc->num_scalers)
+		return dsc_prefill_latency;
+
+	for (int i = 0; i < num_scaler_users; i++) {
+		hscale_k[i] = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16);
+		vscale_k[i] = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16);
+	}
+
+	dsc_prefill_latency =
+		intel_dsc_guardband_latency(num_scaler_users, hscale_k, vscale_k,
+					    chroma_downscaling_factor,
+					    cdclk_prefill_adjustment(crtc_state),
+					    linetime);
+
+	return dsc_prefill_latency;
+}
+
+static int
+scaler_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
+{
+	const struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
+	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
+	int num_scaler_users = hweight32(scaler_state->scaler_users);
+	u64 hscale_k = 0, vscale_k = 0;
+	int scaler_prefill_latency = 0;
+
+	if (!num_scaler_users)
+		return scaler_prefill_latency;
+
+	if (num_scaler_users > 1) {
+		hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16);
+		vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16);
+	}
+
+	scaler_prefill_latency =
+		skl_scaler_guardband_latency(num_scaler_users, hscale_k, vscale_k,
+					     chroma_downscaling_factor,
+					     cdclk_prefill_adjustment(crtc_state),
+					     linetime);
+
+	return scaler_prefill_latency;
+}
+
+static int
+wm0_prefill_latency(int linetime_us, int max_wm0_lines)
+{
+	return 20 + linetime_us * max_wm0_lines;
+}
+
+static int intel_crtc_guardband_atomic_check(struct intel_crtc_state *crtc_state)
+{
+	struct intel_display *display = to_intel_display(crtc_state);
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+	int dsc_prefill_time = 0;
+	int scaler_prefill_time;
+	int wm0_prefill_time;
+	int psr2_pr_latency;
+	int min_guardband;
+	int guardband_us;
+	int sagv_latency;
+	int linetime_us;
+	int sdp_latency;
+	int pm_delay;
+
+	if (!adjusted_mode->crtc_clock)
+		return 0;
+
+	linetime_us = DIV_ROUND_UP(adjusted_mode->crtc_htotal * 1000,
+				   adjusted_mode->crtc_clock);
+
+	/*
+	 * #TODO
+	 * Account for package C state latency and setting of PKG_C_LATENCY
+	 * register.
+	 * When PKG_C_LATENCY is configured (not all 1s), hardware will
+	 * automatically wake from package C states before framestart so
+	 * that package C state latency can be considered to be 0.
+	 *
+	 * Use max of sagv and package C state latency.
+	 */
+	sagv_latency = display->sagv.block_time_us;
+
+	wm0_prefill_time = wm0_prefill_latency(linetime_us, skl_max_wm0_lines(crtc_state));
+
+	scaler_prefill_time = scaler_prefill_latency(crtc_state, linetime_us);
+
+	dsc_prefill_time = dsc_prefill_latency(crtc_state, linetime_us);
+
+	pm_delay = crtc_state->framestart_delay +
+		   sagv_latency +
+		   wm0_prefill_time +
+		   scaler_prefill_time +
+		   dsc_prefill_time;
+
+	psr2_pr_latency = intel_alpm_compute_max_link_wake_latency(crtc_state, false);
+	sdp_latency = intel_dp_compute_sdp_latency(crtc_state, false);
+
+	guardband_us = max(sdp_latency, psr2_pr_latency);
+	guardband_us = max(guardband_us, pm_delay);
+	min_guardband = intel_usecs_to_scanlines(adjusted_mode, guardband_us);
+
+	if (crtc_state->vrr.guardband < min_guardband) {
+		drm_dbg_kms(display->drm, "vrr.guardband %d < min guardband %d\n",
+			    crtc_state->vrr.guardband, min_guardband);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int intel_crtc_atomic_check(struct intel_atomic_state *state,
 				   struct intel_crtc *crtc)
 {
@@ -4251,6 +4392,12 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
 	if (ret)
 		return ret;
 
+	if (intel_vrr_possible(crtc_state)) {
+		ret = intel_crtc_guardband_atomic_check(crtc_state);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index deb43f0c348a..9a368bb9e92a 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -2254,7 +2254,7 @@ skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state,
 		adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start;
 }
 
-static int skl_max_wm0_lines(const struct intel_crtc_state *crtc_state)
+int skl_max_wm0_lines(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum plane_id plane_id;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h
index 62790816f030..8706c2010ebe 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark.h
@@ -78,6 +78,7 @@ void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state);
 void intel_program_dpkgc_latency(struct intel_atomic_state *state);
 
 bool intel_dbuf_pmdemand_needs_update(struct intel_atomic_state *state);
+int skl_max_wm0_lines(const struct intel_crtc_state *crtc_state);
 
 #endif /* __SKL_WATERMARK_H__ */
 
-- 
2.45.2


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

* [PATCH 09/15] drm/i915/skl_watermark: Remove redundant latency checks from vblank validation
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (7 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 08/15] drm/i915/display: Add guardband check for feature latencies Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 10/15] drm/i915/vrr: Introduce helper to compute min static guardband Ankit Nautiyal
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

Drop DSC and scaler prefill latency checks from skl_is_vblank_too_short().
These are now covered by the guardband validation added during the atomic
CRTC check phase.

This cleanup prepares for future changes where the guardband will be
optimized independently of vblank length, making vblank-based checks
obsolete.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 80 --------------------
 1 file changed, 80 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 9a368bb9e92a..73e5b2d8ae83 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -28,7 +28,6 @@
 #include "intel_flipq.h"
 #include "intel_pcode.h"
 #include "intel_plane.h"
-#include "intel_vdsc.h"
 #include "intel_wm.h"
 #include "skl_universal_plane_regs.h"
 #include "skl_scaler.h"
@@ -2162,91 +2161,12 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
 	return 0;
 }
 
-static int
-cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state)
-{
-	struct intel_display *display = to_intel_display(crtc_state);
-	struct intel_atomic_state *state =
-		to_intel_atomic_state(crtc_state->uapi.state);
-	const struct intel_cdclk_state *cdclk_state;
-
-	cdclk_state = intel_atomic_get_cdclk_state(state);
-	if (IS_ERR(cdclk_state)) {
-		drm_WARN_ON(display->drm, PTR_ERR(cdclk_state));
-		return 1;
-	}
-
-	return min(1, DIV_ROUND_UP(crtc_state->pixel_rate,
-				   2 * intel_cdclk_logical(cdclk_state)));
-}
-
-static int
-dsc_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
-{
-	const struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
-	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	int num_scaler_users = hweight32(scaler_state->scaler_users);
-	u64 hscale_k[ARRAY_SIZE(scaler_state->scalers)];
-	u64 vscale_k[ARRAY_SIZE(scaler_state->scalers)];
-	u32 dsc_prefill_latency = 0;
-
-	if (!crtc_state->dsc.compression_enable ||
-	    !num_scaler_users ||
-	    num_scaler_users > crtc->num_scalers)
-		return dsc_prefill_latency;
-
-	for (int i = 0; i < num_scaler_users; i++) {
-		hscale_k[i] = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16);
-		vscale_k[i] = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16);
-	}
-
-	dsc_prefill_latency =
-		intel_dsc_guardband_latency(num_scaler_users, hscale_k, vscale_k,
-					    chroma_downscaling_factor,
-					    cdclk_prefill_adjustment(crtc_state),
-					    linetime);
-
-	return dsc_prefill_latency;
-}
-
-static int
-scaler_prefill_latency(const struct intel_crtc_state *crtc_state, int linetime)
-{
-	const struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
-	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
-	int num_scaler_users = hweight32(scaler_state->scaler_users);
-	u64 hscale_k = 0, vscale_k = 0;
-	int scaler_prefill_latency = 0;
-
-	if (!num_scaler_users)
-		return scaler_prefill_latency;
-
-	if (num_scaler_users > 1) {
-		hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16);
-		vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16);
-	}
-
-	scaler_prefill_latency =
-		skl_scaler_guardband_latency(num_scaler_users, hscale_k, vscale_k,
-					     chroma_downscaling_factor,
-					     cdclk_prefill_adjustment(crtc_state),
-					     linetime);
-
-	return scaler_prefill_latency;
-}
-
 static bool
 skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state,
 			int wm0_lines, int latency)
 {
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
-	int linetime = DIV_ROUND_UP(1000 * adjusted_mode->htotal,
-				    adjusted_mode->clock);
-
-	latency += scaler_prefill_latency(crtc_state, linetime) +
-		   dsc_prefill_latency(crtc_state, linetime);
 
 	return crtc_state->framestart_delay +
 		intel_usecs_to_scanlines(adjusted_mode, latency) +
-- 
2.45.2


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

* [PATCH 10/15] drm/i915/vrr: Introduce helper to compute min static guardband
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (8 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 09/15] drm/i915/skl_watermark: Remove redundant latency checks from vblank validation Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 11/15] drm/i915/vrr: Use optimized guardband when VRR TG is active Ankit Nautiyal
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal, Mitul Golani

In the current VRR implementation, vrr.vmin and vrr.guardband are set such
that they do not need to change when switching from fixed refresh rate to
variable refresh rate. Specifically, vrr.guardband is always set to match
the vblank length. This approach works for most cases, but not for LRR,
where the guardband would need to change while the VRR timing generator is
still active.

With the VRR TG always active, live updates to guardband are unsafe and not
recommended. To ensure hardware safety, guardband was moved out of the
!fastset block, meaning any change now requires a full modeset.
This breaks seamless LRR switching, which was previously supported.

Since the problem arises from guardband being matched to the vblank length,
solution is to use a minimal, sufficient static value, instead. So we use a
static guardband defined during mode-set that fits within the smallest
expected vblank and remains unchanged in case of features like LRR where
vtotal changes. To compute this minimum guardband we take into account
latencies/delays due to different features as mentioned in the Bspec.

Introduce a helper to compute the minimal sufficient guardband.

v2: Use helpers for dsc/scaler prefill latencies. (Mitul)
Account for pkgc latency and take max of pkgc and sagv latencies.

v3: Use new helper for PSR2/Panel Replay latency.

v4: Avoid re-setting the Vmin/Flipline for optimized guardband.

v5:
- Refactor the function to make it as a helper which can be used to
  update crtc_vblank_start and guardband can then be derived from it.
  (Ville)
- Modify the subject and commit message for the same.

v6: Use intel_usecs_to_scanlines() instead of hand rolled stuff. (Ville)

Bspec: 70151
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com> (#v3)
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 117 +++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_vrr.h |   2 +
 2 files changed, 119 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 4bc14b5e685f..a43e5ee2d3ac 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -6,12 +6,18 @@
 
 #include <drm/drm_print.h>
 
+#include "intel_alpm.h"
+#include "intel_crtc.h"
 #include "intel_de.h"
 #include "intel_display_regs.h"
 #include "intel_display_types.h"
 #include "intel_dp.h"
+#include "intel_dp.h"
+#include "intel_vdsc.h"
 #include "intel_vrr.h"
 #include "intel_vrr_regs.h"
+#include "skl_scaler.h"
+#include "skl_watermark.h"
 
 #define FIXED_POINT_PRECISION		100
 #define CMRR_PRECISION_TOLERANCE	10
@@ -839,3 +845,114 @@ int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state)
 	return intel_vrr_vmin_vblank_start(crtc_state) -
 	       crtc_state->set_context_latency;
 }
+
+static
+int scaler_prefill_latency(struct intel_crtc_state *crtc_state, int linetime_us)
+{
+	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
+	u64 hscale_k, vscale_k;
+	int cdclk_adjustment;
+	int num_scaler_users;
+
+	/*
+	 * Assuming:
+	 * Both scaler enabled.
+	 * scaler 1 downscaling factor as 2 x 2 (Horiz x Vert)
+	 * scaler 2 downscaling factor as 2 x 1 (Horiz x Vert)
+	 * Cdclk Adjustment : 1
+	 */
+	num_scaler_users = 2;
+	hscale_k = 2 * 1000;
+	vscale_k = 2 * 1000;
+	cdclk_adjustment = 1;
+
+	return skl_scaler_guardband_latency(num_scaler_users, hscale_k, vscale_k,
+					    chroma_downscaling_factor,
+					    cdclk_adjustment,
+					    linetime_us);
+}
+
+static
+int dsc_prefill_latency(struct intel_crtc_state *crtc_state, int linetime_us)
+{
+#define MAX_SCALERS 2
+	int chroma_downscaling_factor = skl_scaler_chroma_downscale_factor(crtc_state);
+	u64 hscale_k[MAX_SCALERS], vscale_k[MAX_SCALERS];
+	int cdclk_adjustment;
+	int num_scaler_users;
+
+	/*
+	 * Assuming:
+	 * Both scaler enabled.
+	 * scaler 1 downscaling factor as 2 x 2 (Horiz x Vert)
+	 * scaler 2 downscaling factor as 2 x 1 (Horiz x Vert)
+	 * Cdclk Adjustment : 1
+	 */
+	num_scaler_users = MAX_SCALERS;
+	hscale_k[0] = 2 * 1000;
+	vscale_k[0] = 2 * 1000;
+	hscale_k[1] = 2 * 1000;
+	vscale_k[1] = 1 * 1000;
+
+	cdclk_adjustment = 1;
+
+	return intel_dsc_guardband_latency(num_scaler_users, hscale_k, vscale_k,
+					   chroma_downscaling_factor,
+					   cdclk_adjustment,
+					   linetime_us);
+}
+
+int intel_vrr_compute_guardband(struct intel_crtc_state *crtc_state,
+				struct intel_connector *connector)
+{
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+	struct intel_display *display = to_intel_display(crtc_state);
+	int dsc_prefill_time = 0;
+	int psr2_pr_latency = 0;
+	int scaler_prefill_time;
+	int wm0_prefill_time;
+	int pkgc_max_latency;
+	int sagv_latency;
+	int sdp_latency = 0;
+	int guardband_us;
+	int linetime_us;
+	int guardband;
+	int pm_delay;
+
+	linetime_us = DIV_ROUND_UP(adjusted_mode->crtc_htotal * 1000,
+				   adjusted_mode->crtc_clock);
+
+	pkgc_max_latency = skl_watermark_max_latency(display, 1);
+	sagv_latency = display->sagv.block_time_us;
+
+	/* Assuming max wm0 lines = 4 */
+	wm0_prefill_time = 4 * linetime_us + 20;
+
+	scaler_prefill_time = scaler_prefill_latency(crtc_state, linetime_us);
+
+	if (crtc_state->dsc.compression_enable)
+		dsc_prefill_time = dsc_prefill_latency(crtc_state, linetime_us);
+
+	pm_delay = crtc_state->framestart_delay +
+		   max(sagv_latency, pkgc_max_latency) +
+		   wm0_prefill_time +
+		   scaler_prefill_time +
+		   dsc_prefill_time;
+
+	switch (connector->base.connector_type) {
+	case DRM_MODE_CONNECTOR_eDP:
+	case DRM_MODE_CONNECTOR_DisplayPort:
+		psr2_pr_latency = intel_alpm_compute_max_link_wake_latency(crtc_state, true);
+		sdp_latency = intel_dp_compute_sdp_latency(crtc_state, true);
+		break;
+	default:
+		break;
+	}
+
+	guardband_us = max(sdp_latency, psr2_pr_latency);
+	guardband_us = max(guardband_us, pm_delay);
+
+	guardband = intel_usecs_to_scanlines(adjusted_mode, guardband_us);
+
+	return guardband;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h
index 7317f8730089..d332e5a0a1c1 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.h
+++ b/drivers/gpu/drm/i915/display/intel_vrr.h
@@ -42,5 +42,7 @@ void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state);
 bool intel_vrr_always_use_vrr_tg(struct intel_display *display);
 int intel_vrr_safe_window_start(const struct intel_crtc_state *crtc_state);
 int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state);
+int intel_vrr_compute_guardband(struct intel_crtc_state *crtc_state,
+				struct intel_connector *connector);
 
 #endif /* __INTEL_VRR_H__ */
-- 
2.45.2


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

* [PATCH 11/15] drm/i915/vrr: Use optimized guardband when VRR TG is active
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (9 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 10/15] drm/i915/vrr: Introduce helper to compute min static guardband Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 12/15] drm/i915/vrr: Prepare for movement of vblank start for optimized guardband Ankit Nautiyal
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal

We want to use the optimized/reduced guardband whenever we are using the
VRR timing generator, as the legacy timing generator doesn't need vrr
guardband.

On platforms where the VRR timing generator is always ON, we optimize the
guardband regardless of whether the display is operating in fixed or
variable refresh rate mode.

On platforms where the VRR timing generator is not always ON, we optimize
the guardband only when VRR is enabled.

Add a helper intel_vrr_use_optimized_guardband() to determine if the
optimized/reduced guardband should be used.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 7 +++++++
 drivers/gpu/drm/i915/display/intel_vrr.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index a43e5ee2d3ac..ff6848de21b5 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -956,3 +956,10 @@ int intel_vrr_compute_guardband(struct intel_crtc_state *crtc_state,
 
 	return guardband;
 }
+
+bool intel_vrr_use_optimized_guardband(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_display *display = to_intel_display(crtc_state);
+
+	return intel_vrr_always_use_vrr_tg(display) || crtc_state->vrr.enable;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h
index d332e5a0a1c1..0c741c2a5bbd 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.h
+++ b/drivers/gpu/drm/i915/display/intel_vrr.h
@@ -44,5 +44,6 @@ int intel_vrr_safe_window_start(const struct intel_crtc_state *crtc_state);
 int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state);
 int intel_vrr_compute_guardband(struct intel_crtc_state *crtc_state,
 				struct intel_connector *connector);
+bool intel_vrr_use_optimized_guardband(const struct intel_crtc_state *crtc_state);
 
 #endif /* __INTEL_VRR_H__ */
-- 
2.45.2


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

* [PATCH 12/15] drm/i915/vrr: Prepare for movement of vblank start for optimized guardband
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (10 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 11/15] drm/i915/vrr: Use optimized guardband when VRR TG is active Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 13/15] drm/i915/display: Recompute crtc_vblank_start " Ankit Nautiyal
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal

Currently, the guardband is computed as: vmin - vdisplay, because the
guardband matches the length of the vblank interval. We then make sure
that this value is atmost equal to the max guardband with SCL and other
delays taken into account.

However, with the optimized/reduced guardband logic, the delayed vblank
will be  positioned further away from the undelayed vblank. So with the
optimization enabled, the guardband should instead be computed as:
vmin - vblank_start.

Update the guardband calculation in intel_vrr_compute_config_late() to use
vblank_start when optimization is enabled.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index ff6848de21b5..0b4694a1e2b5 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -443,12 +443,17 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state)
 {
 	struct intel_display *display = to_intel_display(crtc_state);
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+	int guardband;
 
 	if (!intel_vrr_possible(crtc_state))
 		return;
 
-	crtc_state->vrr.guardband = min(crtc_state->vrr.vmin - adjusted_mode->crtc_vdisplay,
-					intel_vrr_max_guardband(crtc_state));
+	if (intel_vrr_use_optimized_guardband(crtc_state))
+		guardband = crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start;
+	else
+		guardband = crtc_state->vrr.vmin - adjusted_mode->crtc_vdisplay;
+
+	crtc_state->vrr.guardband = min(guardband, intel_vrr_max_guardband(crtc_state));
 
 	if (DISPLAY_VER(display) < 13)
 		crtc_state->vrr.pipeline_full =
-- 
2.45.2


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

* [PATCH 13/15] drm/i915/display: Recompute crtc_vblank_start for optimized guardband
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (11 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 12/15] drm/i915/vrr: Prepare for movement of vblank start for optimized guardband Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 14/15] drm/i915/display: s/allow_vblank_delay_fastset/allow_vblank_delay_fastset_lrr Ankit Nautiyal
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal

Currently crtc_vblank_start is read out either from VBLANK_START (pre
ADL) or from set context latency and vactive, in
intel_get_transcoder_timings().

As we move the delayed vblank to reduce the guardband, we need to use
the guardband to readout the new vblank start.

Recompute and overwrite the new vblank start when optimized guardband is
used in intel_vrr_get_config().

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 0b4694a1e2b5..dfd4f7456db0 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -832,6 +832,15 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
 	 */
 	if (crtc_state->vrr.enable)
 		crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+
+	/*
+	 * If guardband is optimized then vblank start is vtotal - vblank_start
+	 */
+	if (intel_vrr_use_optimized_guardband(crtc_state))
+		crtc_state->hw.adjusted_mode.crtc_vblank_start =
+			crtc_state->hw.adjusted_mode.crtc_vtotal -
+			crtc_state->vrr.guardband;
+
 }
 
 int intel_vrr_safe_window_start(const struct intel_crtc_state *crtc_state)
-- 
2.45.2


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

* [PATCH 14/15] drm/i915/display: s/allow_vblank_delay_fastset/allow_vblank_delay_fastset_lrr
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (12 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 13/15] drm/i915/display: Recompute crtc_vblank_start " Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-28  7:05 ` [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start Ankit Nautiyal
  2025-09-28  8:07 ` ✗ i915.CI.BAT: failure for Optimize vrr.guardband and fix LRR (rev12) Patchwork
  15 siblings, 0 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal

The function allow_vblank_delay_fastset specifically checks for conditions
under which vblank delay is allowed via LRR codepaths. To make its purpose
clearer and prepare for future extensions, rename it to
allow_vblank_delay_fastset_lrr.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index ec415b939770..4135f9be53fd 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5097,7 +5097,7 @@ pipe_config_cx0pll_mismatch(struct drm_printer *p, bool fastset,
 	intel_cx0pll_dump_hw_state(display, b);
 }
 
-static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_state)
+static bool allow_vblank_delay_fastset_lrr(const struct intel_crtc_state *old_crtc_state)
 {
 	struct intel_display *display = to_intel_display(old_crtc_state);
 
@@ -5242,7 +5242,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_I(name.crtc_hsync_start); \
 	PIPE_CONF_CHECK_I(name.crtc_hsync_end); \
 	PIPE_CONF_CHECK_I(name.crtc_vdisplay); \
-	if (!fastset || !allow_vblank_delay_fastset(current_config)) \
+	if (!fastset || !allow_vblank_delay_fastset_lrr(current_config)) \
 		PIPE_CONF_CHECK_I(name.crtc_vblank_start); \
 	PIPE_CONF_CHECK_I(name.crtc_vsync_start); \
 	PIPE_CONF_CHECK_I(name.crtc_vsync_end); \
@@ -5851,7 +5851,7 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
 		drm_dbg_kms(display->drm, "[CRTC:%d:%s] fastset requirement not met, forcing full modeset\n",
 			    crtc->base.base.id, crtc->base.name);
 	} else {
-		if (allow_vblank_delay_fastset(old_crtc_state))
+		if (allow_vblank_delay_fastset_lrr(old_crtc_state))
 			new_crtc_state->update_lrr = true;
 		new_crtc_state->uapi.mode_changed = false;
 	}
-- 
2.45.2


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

* [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (13 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 14/15] drm/i915/display: s/allow_vblank_delay_fastset/allow_vblank_delay_fastset_lrr Ankit Nautiyal
@ 2025-09-28  7:05 ` Ankit Nautiyal
  2025-09-29  8:45   ` Ville Syrjälä
  2025-09-29  9:00   ` Ville Syrjälä
  2025-09-28  8:07 ` ✗ i915.CI.BAT: failure for Optimize vrr.guardband and fix LRR (rev12) Patchwork
  15 siblings, 2 replies; 27+ messages in thread
From: Ankit Nautiyal @ 2025-09-28  7:05 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala, Ankit Nautiyal

As we move towards using a shorter, optimized guardband, we need to adjust
how the delayed vblank start is computed.

Use the helper intel_vrr_compute_guardband() to calculate the optimized
guardband. Since this is measured from the vblank end, we shift the
vblank-start accordingly.

Calculate the minimum delay required based on the guardband and apply it in
intel_crtc_vblank_delay() to update crtc_vblank_start.

Additionally, introduce a new allow_vblank_delay_fastset() helper that
combines the existing LRR-based logic with an additional check for the
optimized guardband usage.

v2:
- Check if optimized guardband is more than vblank length and add debug
  print.
- Extend vblank delay fastset logic to cover optimized guardband.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 79 +++++++++++++++++++-
 1 file changed, 76 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 4135f9be53fd..97a3121a204f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2361,6 +2361,67 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
 	return 0;
 }
 
+static
+int intel_crtc_min_guardband_delay(struct intel_atomic_state *state,
+				   struct intel_crtc *crtc)
+{
+	struct intel_display *display = to_intel_display(state);
+	struct intel_crtc_state *crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct drm_display_mode *adjusted_mode =
+		&crtc_state->hw.adjusted_mode;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *drm_connector;
+	int vblank_length;
+	int i;
+
+	if (!intel_vrr_use_optimized_guardband(crtc_state))
+		return 0;
+
+	vblank_length = crtc_state->vrr.vmin -
+			adjusted_mode->crtc_vdisplay;
+
+	for_each_new_connector_in_state(&state->base,
+					drm_connector,
+					conn_state, i) {
+		int guardband;
+		struct intel_connector *connector;
+
+		if (conn_state->crtc != &crtc->base)
+			continue;
+
+		connector = to_intel_connector(drm_connector);
+		guardband = intel_vrr_compute_guardband(crtc_state,
+							connector);
+		if (guardband > vblank_length) {
+			drm_dbg_kms(display->drm,
+				    "[CRTC:%d:%s] Cannot optimize guardband (%d) exceeds max (%d)\n",
+				    crtc->base.base.id, crtc->base.name,
+				    guardband,
+				    vblank_length);
+			return 0;
+		}
+
+		return vblank_length - guardband;
+	}
+
+	return 0;
+}
+
+static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
+				    struct intel_crtc *crtc)
+{
+	struct intel_crtc_state *crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *adjusted_mode =
+		&crtc_state->hw.adjusted_mode;
+	int vblank_delay = 0;
+
+	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
+
+	adjusted_mode->crtc_vblank_start += vblank_delay;
+}
+
 static int intel_crtc_set_context_latency(struct intel_crtc_state *crtc_state)
 {
 	struct intel_display *display = to_intel_display(crtc_state);
@@ -2413,6 +2474,7 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
 	ret = intel_crtc_compute_set_context_latency(state, crtc);
 	if (ret)
 		return ret;
+	intel_crtc_vblank_delay(state, crtc);
 
 	ret = intel_dpll_crtc_compute_clock(state, crtc);
 	if (ret)
@@ -5101,13 +5163,24 @@ static bool allow_vblank_delay_fastset_lrr(const struct intel_crtc_state *old_cr
 {
 	struct intel_display *display = to_intel_display(old_crtc_state);
 
+	return HAS_LRR(display) && old_crtc_state->inherited &&
+		!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
+}
+
+static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_state,
+				       const struct intel_crtc_state *new_crtc_state)
+{
 	/*
 	 * Allow fastboot to fix up vblank delay (handled via LRR
 	 * codepaths), a bit dodgy as the registers aren't
 	 * double buffered but seems to be working more or less...
+	 *
+	 * Additionally, with the optimized guardband the vblank start
+	 * is moved further away from the undelayed vblank. Allow this
+	 * vblank delay when optimized guardband is used.
 	 */
-	return HAS_LRR(display) && old_crtc_state->inherited &&
-		!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
+	return allow_vblank_delay_fastset_lrr(old_crtc_state) ||
+	       intel_vrr_use_optimized_guardband(new_crtc_state);
 }
 
 bool
@@ -5242,7 +5315,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_I(name.crtc_hsync_start); \
 	PIPE_CONF_CHECK_I(name.crtc_hsync_end); \
 	PIPE_CONF_CHECK_I(name.crtc_vdisplay); \
-	if (!fastset || !allow_vblank_delay_fastset_lrr(current_config)) \
+	if (!fastset || !allow_vblank_delay_fastset(current_config, pipe_config)) \
 		PIPE_CONF_CHECK_I(name.crtc_vblank_start); \
 	PIPE_CONF_CHECK_I(name.crtc_vsync_start); \
 	PIPE_CONF_CHECK_I(name.crtc_vsync_end); \
-- 
2.45.2


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

* ✗ i915.CI.BAT: failure for Optimize vrr.guardband and fix LRR (rev12)
  2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
                   ` (14 preceding siblings ...)
  2025-09-28  7:05 ` [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start Ankit Nautiyal
@ 2025-09-28  8:07 ` Patchwork
  15 siblings, 0 replies; 27+ messages in thread
From: Patchwork @ 2025-09-28  8:07 UTC (permalink / raw)
  To: Ankit Nautiyal; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 7663 bytes --]

== Series Details ==

Series: Optimize vrr.guardband and fix LRR (rev12)
URL   : https://patchwork.freedesktop.org/series/151245/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_17276 -> Patchwork_151245v12
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_151245v12 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_151245v12, please notify your bug team (I915-ci-infra@lists.freedesktop.org) to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/index.html

Participating hosts (43 -> 43)
------------------------------

  Additional (1): bat-adls-6 
  Missing    (1): fi-snb-2520m 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_151245v12:

### IGT changes ###

#### Possible regressions ####

  * igt@i915_selftest@live@hugepages:
    - bat-arlh-2:         [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17276/bat-arlh-2/igt@i915_selftest@live@hugepages.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-arlh-2/igt@i915_selftest@live@hugepages.html

  
Known issues
------------

  Here are the changes found in Patchwork_151245v12 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@dmabuf@all-tests:
    - bat-apl-1:          [PASS][3] -> [ABORT][4] ([i915#12904]) +1 other test abort
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17276/bat-apl-1/igt@dmabuf@all-tests.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-apl-1/igt@dmabuf@all-tests.html

  * igt@gem_lmem_swapping@parallel-random-engines:
    - bat-adls-6:         NOTRUN -> [SKIP][5] ([i915#4613]) +3 other tests skip
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@gem_lmem_swapping@parallel-random-engines.html

  * igt@gem_tiled_pread_basic:
    - bat-adls-6:         NOTRUN -> [SKIP][6] ([i915#3282])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@gem_tiled_pread_basic.html

  * igt@i915_selftest@live:
    - fi-bsw-n3050:       [PASS][7] -> [DMESG-FAIL][8] ([i915#14808]) +1 other test dmesg-fail
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17276/fi-bsw-n3050/igt@i915_selftest@live.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/fi-bsw-n3050/igt@i915_selftest@live.html
    - bat-arlh-2:         [PASS][9] -> [INCOMPLETE][10] ([i915#14803] / [i915#14838])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17276/bat-arlh-2/igt@i915_selftest@live.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-arlh-2/igt@i915_selftest@live.html

  * igt@i915_selftest@live@workarounds:
    - bat-arlh-3:         [PASS][11] -> [DMESG-FAIL][12] ([i915#12061]) +1 other test dmesg-fail
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17276/bat-arlh-3/igt@i915_selftest@live@workarounds.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-arlh-3/igt@i915_selftest@live@workarounds.html

  * igt@intel_hwmon@hwmon-read:
    - bat-adls-6:         NOTRUN -> [SKIP][13] ([i915#7707]) +1 other test skip
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@intel_hwmon@hwmon-read.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - bat-adls-6:         NOTRUN -> [SKIP][14] ([i915#4103]) +1 other test skip
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_dsc@dsc-basic:
    - bat-adls-6:         NOTRUN -> [SKIP][15] ([i915#3555] / [i915#3840])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@kms_dsc@dsc-basic.html

  * igt@kms_force_connector_basic@force-load-detect:
    - bat-adls-6:         NOTRUN -> [SKIP][16]
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_hdmi_inject@inject-audio:
    - fi-tgl-1115g4:      [PASS][17] -> [FAIL][18] ([i915#14867])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17276/fi-tgl-1115g4/igt@kms_hdmi_inject@inject-audio.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/fi-tgl-1115g4/igt@kms_hdmi_inject@inject-audio.html

  * igt@kms_pm_backlight@basic-brightness:
    - bat-adls-6:         NOTRUN -> [SKIP][19] ([i915#5354])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@kms_pm_backlight@basic-brightness.html

  * igt@kms_psr@psr-primary-mmap-gtt:
    - bat-adls-6:         NOTRUN -> [SKIP][20] ([i915#1072] / [i915#9732]) +3 other tests skip
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@kms_psr@psr-primary-mmap-gtt.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - bat-adls-6:         NOTRUN -> [SKIP][21] ([i915#3555])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@kms_setmode@basic-clone-single-crtc.html

  * igt@prime_vgem@basic-fence-read:
    - bat-adls-6:         NOTRUN -> [SKIP][22] ([i915#3291]) +2 other tests skip
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-adls-6/igt@prime_vgem@basic-fence-read.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@workarounds:
    - bat-mtlp-6:         [DMESG-FAIL][23] ([i915#12061]) -> [PASS][24] +1 other test pass
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17276/bat-mtlp-6/igt@i915_selftest@live@workarounds.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/bat-mtlp-6/igt@i915_selftest@live@workarounds.html

  
  [i915#1072]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/1072
  [i915#12061]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12061
  [i915#12904]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12904
  [i915#14803]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14803
  [i915#14808]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14808
  [i915#14838]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14838
  [i915#14867]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14867
  [i915#3282]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3282
  [i915#3291]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3291
  [i915#3555]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3555
  [i915#3840]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3840
  [i915#4103]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4103
  [i915#4613]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4613
  [i915#5354]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5354
  [i915#7707]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/7707
  [i915#9732]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9732


Build changes
-------------

  * Linux: CI_DRM_17276 -> Patchwork_151245v12

  CI-20190529: 20190529
  CI_DRM_17276: 3008c5c8e2fade05918e6d8c456572c91f30d412 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_8554: 8554
  Patchwork_151245v12: 3008c5c8e2fade05918e6d8c456572c91f30d412 @ git://anongit.freedesktop.org/gfx-ci/linux

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_151245v12/index.html

[-- Attachment #2: Type: text/html, Size: 8815 bytes --]

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-09-28  7:05 ` [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start Ankit Nautiyal
@ 2025-09-29  8:45   ` Ville Syrjälä
  2025-09-29  9:09     ` Ville Syrjälä
                       ` (2 more replies)
  2025-09-29  9:00   ` Ville Syrjälä
  1 sibling, 3 replies; 27+ messages in thread
From: Ville Syrjälä @ 2025-09-29  8:45 UTC (permalink / raw)
  To: Ankit Nautiyal; +Cc: intel-gfx, intel-xe

On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
> +				    struct intel_crtc *crtc)
> +{
> +	struct intel_crtc_state *crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +	struct drm_display_mode *adjusted_mode =
> +		&crtc_state->hw.adjusted_mode;
> +	int vblank_delay = 0;
> +
> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
> +
> +	adjusted_mode->crtc_vblank_start += vblank_delay;

The situation with crtc_vblank_start is already kinda broken,
and I think we need to fix that first somehow.

Currently crtc_vblank_start is assumed to be the vblank_start
for the fixed refresh rate case. That value can be different
from the variable refresh rate case whenever
always_use_vrr_tg()==false. On icl/tgl it's always different
due to the extra vblank delay, and also on adl+ it could be
different if we were to use an optimized guardband.

I think there are a few options how we might solve this:
1. keep crtc_vblank_start as is, and make sure every user of it
   gets adjusted to also deal with the vrr case correctly
2. enable always_use_vrr_tg() whenever there might be switch
   between vrr and fixed refresh rate, which I think would mean
   crtc_state->vrr.in_range==true.

I kinda like option 2 because then we'll be doing the vrr vs.
fixed refresh rate always the same way. However we haven't really
tested that mode of operation on the older platforms, so I'd
rather not bet all your work on that working. If we later run
into problems with that then we'd have to revert everything.

So I think we should start with option 1, adjust all the
crtc_vblank_start users approriately (I don't think there are
too many of them), and adjust crtc_vblank_start to match
the guardband only when always_use_vrr_tg()==true.

After that I think we might still have some potential issues/race
conditions around the actual vrr <-> fixed refresh rate switch.
Those might require more work later, or if we decide at that point
to try option 2 maybe we could sidestep some/all of them.

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-09-28  7:05 ` [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start Ankit Nautiyal
  2025-09-29  8:45   ` Ville Syrjälä
@ 2025-09-29  9:00   ` Ville Syrjälä
  2025-10-01 10:41     ` Nautiyal, Ankit K
  1 sibling, 1 reply; 27+ messages in thread
From: Ville Syrjälä @ 2025-09-29  9:00 UTC (permalink / raw)
  To: Ankit Nautiyal; +Cc: intel-gfx, intel-xe

On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
> As we move towards using a shorter, optimized guardband, we need to adjust
> how the delayed vblank start is computed.
> 
> Use the helper intel_vrr_compute_guardband() to calculate the optimized
> guardband. Since this is measured from the vblank end, we shift the
> vblank-start accordingly.
> 
> Calculate the minimum delay required based on the guardband and apply it in
> intel_crtc_vblank_delay() to update crtc_vblank_start.
> 
> Additionally, introduce a new allow_vblank_delay_fastset() helper that
> combines the existing LRR-based logic with an additional check for the
> optimized guardband usage.
> 
> v2:
> - Check if optimized guardband is more than vblank length and add debug
>   print.
> - Extend vblank delay fastset logic to cover optimized guardband.
> 
> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 79 +++++++++++++++++++-
>  1 file changed, 76 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 4135f9be53fd..97a3121a204f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -2361,6 +2361,67 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
>  	return 0;
>  }
>  
> +static
> +int intel_crtc_min_guardband_delay(struct intel_atomic_state *state,
> +				   struct intel_crtc *crtc)
> +{
> +	struct intel_display *display = to_intel_display(state);
> +	struct intel_crtc_state *crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +	const struct drm_display_mode *adjusted_mode =
> +		&crtc_state->hw.adjusted_mode;
> +	struct drm_connector_state *conn_state;
> +	struct drm_connector *drm_connector;
> +	int vblank_length;
> +	int i;
> +
> +	if (!intel_vrr_use_optimized_guardband(crtc_state))
> +		return 0;
> +
> +	vblank_length = crtc_state->vrr.vmin -
> +			adjusted_mode->crtc_vdisplay;
> +
> +	for_each_new_connector_in_state(&state->base,
> +					drm_connector,
> +					conn_state, i) {
> +		int guardband;
> +		struct intel_connector *connector;
> +
> +		if (conn_state->crtc != &crtc->base)
> +			continue;
> +
> +		connector = to_intel_connector(drm_connector);
> +		guardband = intel_vrr_compute_guardband(crtc_state,
> +							connector);
> +		if (guardband > vblank_length) {
> +			drm_dbg_kms(display->drm,
> +				    "[CRTC:%d:%s] Cannot optimize guardband (%d) exceeds max (%d)\n",
> +				    crtc->base.base.id, crtc->base.name,
> +				    guardband,
> +				    vblank_length);
> +			return 0;
> +		}
> +
> +		return vblank_length - guardband;
> +	}
> +
> +	return 0;
> +}
> +
> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
> +				    struct intel_crtc *crtc)
> +{
> +	struct intel_crtc_state *crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +	struct drm_display_mode *adjusted_mode =
> +		&crtc_state->hw.adjusted_mode;
> +	int vblank_delay = 0;
> +
> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
> +
> +	adjusted_mode->crtc_vblank_start += vblank_delay;
> +}
> +
>  static int intel_crtc_set_context_latency(struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_display *display = to_intel_display(crtc_state);
> @@ -2413,6 +2474,7 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
>  	ret = intel_crtc_compute_set_context_latency(state, crtc);
>  	if (ret)
>  		return ret;
> +	intel_crtc_vblank_delay(state, crtc);

IMO we should get rid of all this vblank_delay terminology here.
This one I think should just be our current
intel_vrr_compute_config_late() (renamed to eg.
intel_vrr_compute_guardband()).

After which we just have to solve all the chicken vs. egg problems
to really compute the approriate optimized guardband value.
  
>  	ret = intel_dpll_crtc_compute_clock(state, crtc);
>  	if (ret)
> @@ -5101,13 +5163,24 @@ static bool allow_vblank_delay_fastset_lrr(const struct intel_crtc_state *old_cr
>  {
>  	struct intel_display *display = to_intel_display(old_crtc_state);
>  
> +	return HAS_LRR(display) && old_crtc_state->inherited &&
> +		!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
> +}
> +
> +static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_state,
> +				       const struct intel_crtc_state *new_crtc_state)
> +{
>  	/*
>  	 * Allow fastboot to fix up vblank delay (handled via LRR
>  	 * codepaths), a bit dodgy as the registers aren't
>  	 * double buffered but seems to be working more or less...
> +	 *
> +	 * Additionally, with the optimized guardband the vblank start
> +	 * is moved further away from the undelayed vblank. Allow this
> +	 * vblank delay when optimized guardband is used.
>  	 */
> -	return HAS_LRR(display) && old_crtc_state->inherited &&
> -		!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
> +	return allow_vblank_delay_fastset_lrr(old_crtc_state) ||
> +	       intel_vrr_use_optimized_guardband(new_crtc_state);
>  }
>  
>  bool
> @@ -5242,7 +5315,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_I(name.crtc_hsync_start); \
>  	PIPE_CONF_CHECK_I(name.crtc_hsync_end); \
>  	PIPE_CONF_CHECK_I(name.crtc_vdisplay); \
> -	if (!fastset || !allow_vblank_delay_fastset_lrr(current_config)) \
> +	if (!fastset || !allow_vblank_delay_fastset(current_config, pipe_config)) \
>  		PIPE_CONF_CHECK_I(name.crtc_vblank_start); \
>  	PIPE_CONF_CHECK_I(name.crtc_vsync_start); \
>  	PIPE_CONF_CHECK_I(name.crtc_vsync_end); \
> -- 
> 2.45.2

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-09-29  8:45   ` Ville Syrjälä
@ 2025-09-29  9:09     ` Ville Syrjälä
  2025-09-29  9:21     ` Ville Syrjälä
  2025-10-01 10:34     ` Nautiyal, Ankit K
  2 siblings, 0 replies; 27+ messages in thread
From: Ville Syrjälä @ 2025-09-29  9:09 UTC (permalink / raw)
  To: Ankit Nautiyal; +Cc: intel-gfx, intel-xe

On Mon, Sep 29, 2025 at 11:45:19AM +0300, Ville Syrjälä wrote:
> On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
> > +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
> > +				    struct intel_crtc *crtc)
> > +{
> > +	struct intel_crtc_state *crtc_state =
> > +		intel_atomic_get_new_crtc_state(state, crtc);
> > +	struct drm_display_mode *adjusted_mode =
> > +		&crtc_state->hw.adjusted_mode;
> > +	int vblank_delay = 0;
> > +
> > +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
> > +
> > +	adjusted_mode->crtc_vblank_start += vblank_delay;
> 
> The situation with crtc_vblank_start is already kinda broken,
> and I think we need to fix that first somehow.
> 
> Currently crtc_vblank_start is assumed to be the vblank_start
> for the fixed refresh rate case. That value can be different
> from the variable refresh rate case whenever
> always_use_vrr_tg()==false. On icl/tgl it's always different
> due to the extra vblank delay, and also on adl+ it could be
> different if we were to use an optimized guardband.
> 
> I think there are a few options how we might solve this:
> 1. keep crtc_vblank_start as is, and make sure every user of it
>    gets adjusted to also deal with the vrr case correctly
> 2. enable always_use_vrr_tg() whenever there might be switch
>    between vrr and fixed refresh rate, which I think would mean
>    crtc_state->vrr.in_range==true.

And just as a reminder in case I think of it again later:
3. use an optimized guardband only when always_use_vrr_tg()==true

But that wouldn't actually solve the already existing issue
on icl/tgl. So not really a good option.


-- 
Ville Syrjälä
Intel

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-09-29  8:45   ` Ville Syrjälä
  2025-09-29  9:09     ` Ville Syrjälä
@ 2025-09-29  9:21     ` Ville Syrjälä
  2025-10-01 10:34     ` Nautiyal, Ankit K
  2 siblings, 0 replies; 27+ messages in thread
From: Ville Syrjälä @ 2025-09-29  9:21 UTC (permalink / raw)
  To: Ankit Nautiyal; +Cc: intel-gfx, intel-xe

On Mon, Sep 29, 2025 at 11:45:19AM +0300, Ville Syrjälä wrote:
> On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
> > +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
> > +				    struct intel_crtc *crtc)
> > +{
> > +	struct intel_crtc_state *crtc_state =
> > +		intel_atomic_get_new_crtc_state(state, crtc);
> > +	struct drm_display_mode *adjusted_mode =
> > +		&crtc_state->hw.adjusted_mode;
> > +	int vblank_delay = 0;
> > +
> > +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
> > +
> > +	adjusted_mode->crtc_vblank_start += vblank_delay;
> 
> The situation with crtc_vblank_start is already kinda broken,
> and I think we need to fix that first somehow.
> 
> Currently crtc_vblank_start is assumed to be the vblank_start
> for the fixed refresh rate case. That value can be different
> from the variable refresh rate case whenever
> always_use_vrr_tg()==false. On icl/tgl it's always different
> due to the extra vblank delay, and also on adl+ it could be
> different if we were to use an optimized guardband.
> 
> I think there are a few options how we might solve this:
> 1. keep crtc_vblank_start as is, and make sure every user of it
>    gets adjusted to also deal with the vrr case correctly
> 2. enable always_use_vrr_tg() whenever there might be switch
>    between vrr and fixed refresh rate, which I think would mean
>    crtc_state->vrr.in_range==true.

One slight downside with option 2 would that we migth lose
fastboot support. Dunno if we could come up with a scheme that
prefers option 2 while still allowing the live legacy TG -> VRR
TG change during fastboot...

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-09-29  8:45   ` Ville Syrjälä
  2025-09-29  9:09     ` Ville Syrjälä
  2025-09-29  9:21     ` Ville Syrjälä
@ 2025-10-01 10:34     ` Nautiyal, Ankit K
  2025-10-01 12:10       ` Ville Syrjälä
  2 siblings, 1 reply; 27+ messages in thread
From: Nautiyal, Ankit K @ 2025-10-01 10:34 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, intel-xe


On 9/29/2025 2:15 PM, Ville Syrjälä wrote:
> On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
>> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
>> +				    struct intel_crtc *crtc)
>> +{
>> +	struct intel_crtc_state *crtc_state =
>> +		intel_atomic_get_new_crtc_state(state, crtc);
>> +	struct drm_display_mode *adjusted_mode =
>> +		&crtc_state->hw.adjusted_mode;
>> +	int vblank_delay = 0;
>> +
>> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
>> +
>> +	adjusted_mode->crtc_vblank_start += vblank_delay;
> The situation with crtc_vblank_start is already kinda broken,
> and I think we need to fix that first somehow.
>
> Currently crtc_vblank_start is assumed to be the vblank_start
> for the fixed refresh rate case. That value can be different
> from the variable refresh rate case whenever
> always_use_vrr_tg()==false. On icl/tgl it's always different
> due to the extra vblank delay, and also on adl+ it could be
> different if we were to use an optimized guardband.
>
> I think there are a few options how we might solve this:
> 1. keep crtc_vblank_start as is, and make sure every user of it
>     gets adjusted to also deal with the vrr case correctly


Alright, so we avoid changing the vblank_start.
It means for platforms with always_use_vrr_tg()==true we directly set 
the value for guardband. (Currently I was getting it from vmin_vtotal - 
vblank_start)
For platforms ADL+ with always always_use_vrr_tg()== false for the fixed 
refresh rate case, guardband is full vblank_length for variable refresh 
rate set the guardband directly.

As you have mentioned need to check which all places we need vblank_start.

For ICL/TGL we do not use optimization for now, right?
The extra_vblank_delay quirk is already handled while filling the 
registers.


> 2. enable always_use_vrr_tg() whenever there might be switch
>     between vrr and fixed refresh rate, which I think would mean
>     crtc_state->vrr.in_range==true.
I think I didnt get this part:
Do you mean later at some point we move to option 2: 
always_use_vrr_tg()==true for all platforms.(Need to check if we can do 
it for ICL, TGL).



>
> I kinda like option 2 because then we'll be doing the vrr vs.
> fixed refresh rate always the same way. However we haven't really
> tested that mode of operation on the older platforms, so I'd
> rather not bet all your work on that working. If we later run
> into problems with that then we'd have to revert everything.
>
> So I think we should start with option 1, adjust all the
> crtc_vblank_start users approriately (I don't think there are
> too many of them), and adjust crtc_vblank_start to match
> the guardband only when always_use_vrr_tg()==true.

Sure will start with this for now.

Thanks & Regards,

Ankit


>
> After that I think we might still have some potential issues/race
> conditions around the actual vrr <-> fixed refresh rate switch.
> Those might require more work later, or if we decide at that point
> to try option 2 maybe we could sidestep some/all of them.
>

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-09-29  9:00   ` Ville Syrjälä
@ 2025-10-01 10:41     ` Nautiyal, Ankit K
  2025-10-01 12:12       ` Ville Syrjälä
  0 siblings, 1 reply; 27+ messages in thread
From: Nautiyal, Ankit K @ 2025-10-01 10:41 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, intel-xe


On 9/29/2025 2:30 PM, Ville Syrjälä wrote:
> On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
>> As we move towards using a shorter, optimized guardband, we need to adjust
>> how the delayed vblank start is computed.
>>
>> Use the helper intel_vrr_compute_guardband() to calculate the optimized
>> guardband. Since this is measured from the vblank end, we shift the
>> vblank-start accordingly.
>>
>> Calculate the minimum delay required based on the guardband and apply it in
>> intel_crtc_vblank_delay() to update crtc_vblank_start.
>>
>> Additionally, introduce a new allow_vblank_delay_fastset() helper that
>> combines the existing LRR-based logic with an additional check for the
>> optimized guardband usage.
>>
>> v2:
>> - Check if optimized guardband is more than vblank length and add debug
>>    print.
>> - Extend vblank delay fastset logic to cover optimized guardband.
>>
>> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_display.c | 79 +++++++++++++++++++-
>>   1 file changed, 76 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>> index 4135f9be53fd..97a3121a204f 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -2361,6 +2361,67 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
>>   	return 0;
>>   }
>>   
>> +static
>> +int intel_crtc_min_guardband_delay(struct intel_atomic_state *state,
>> +				   struct intel_crtc *crtc)
>> +{
>> +	struct intel_display *display = to_intel_display(state);
>> +	struct intel_crtc_state *crtc_state =
>> +		intel_atomic_get_new_crtc_state(state, crtc);
>> +	const struct drm_display_mode *adjusted_mode =
>> +		&crtc_state->hw.adjusted_mode;
>> +	struct drm_connector_state *conn_state;
>> +	struct drm_connector *drm_connector;
>> +	int vblank_length;
>> +	int i;
>> +
>> +	if (!intel_vrr_use_optimized_guardband(crtc_state))
>> +		return 0;
>> +
>> +	vblank_length = crtc_state->vrr.vmin -
>> +			adjusted_mode->crtc_vdisplay;
>> +
>> +	for_each_new_connector_in_state(&state->base,
>> +					drm_connector,
>> +					conn_state, i) {
>> +		int guardband;
>> +		struct intel_connector *connector;
>> +
>> +		if (conn_state->crtc != &crtc->base)
>> +			continue;
>> +
>> +		connector = to_intel_connector(drm_connector);
>> +		guardband = intel_vrr_compute_guardband(crtc_state,
>> +							connector);
>> +		if (guardband > vblank_length) {
>> +			drm_dbg_kms(display->drm,
>> +				    "[CRTC:%d:%s] Cannot optimize guardband (%d) exceeds max (%d)\n",
>> +				    crtc->base.base.id, crtc->base.name,
>> +				    guardband,
>> +				    vblank_length);
>> +			return 0;
>> +		}
>> +
>> +		return vblank_length - guardband;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
>> +				    struct intel_crtc *crtc)
>> +{
>> +	struct intel_crtc_state *crtc_state =
>> +		intel_atomic_get_new_crtc_state(state, crtc);
>> +	struct drm_display_mode *adjusted_mode =
>> +		&crtc_state->hw.adjusted_mode;
>> +	int vblank_delay = 0;
>> +
>> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
>> +
>> +	adjusted_mode->crtc_vblank_start += vblank_delay;
>> +}
>> +
>>   static int intel_crtc_set_context_latency(struct intel_crtc_state *crtc_state)
>>   {
>>   	struct intel_display *display = to_intel_display(crtc_state);
>> @@ -2413,6 +2474,7 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
>>   	ret = intel_crtc_compute_set_context_latency(state, crtc);
>>   	if (ret)
>>   		return ret;
>> +	intel_crtc_vblank_delay(state, crtc);
> IMO we should get rid of all this vblank_delay terminology here.
> This one I think should just be our current
> intel_vrr_compute_config_late() (renamed to eg.
> intel_vrr_compute_guardband()).

Hmm ok so will rename this and call from intel_modeset_pipe_config_late().

Regards,

Ankit

>
> After which we just have to solve all the chicken vs. egg problems
> to really compute the approriate optimized guardband value.
>    
>>   	ret = intel_dpll_crtc_compute_clock(state, crtc);
>>   	if (ret)
>> @@ -5101,13 +5163,24 @@ static bool allow_vblank_delay_fastset_lrr(const struct intel_crtc_state *old_cr
>>   {
>>   	struct intel_display *display = to_intel_display(old_crtc_state);
>>   
>> +	return HAS_LRR(display) && old_crtc_state->inherited &&
>> +		!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
>> +}
>> +
>> +static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_state,
>> +				       const struct intel_crtc_state *new_crtc_state)
>> +{
>>   	/*
>>   	 * Allow fastboot to fix up vblank delay (handled via LRR
>>   	 * codepaths), a bit dodgy as the registers aren't
>>   	 * double buffered but seems to be working more or less...
>> +	 *
>> +	 * Additionally, with the optimized guardband the vblank start
>> +	 * is moved further away from the undelayed vblank. Allow this
>> +	 * vblank delay when optimized guardband is used.
>>   	 */
>> -	return HAS_LRR(display) && old_crtc_state->inherited &&
>> -		!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
>> +	return allow_vblank_delay_fastset_lrr(old_crtc_state) ||
>> +	       intel_vrr_use_optimized_guardband(new_crtc_state);
>>   }
>>   
>>   bool
>> @@ -5242,7 +5315,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>   	PIPE_CONF_CHECK_I(name.crtc_hsync_start); \
>>   	PIPE_CONF_CHECK_I(name.crtc_hsync_end); \
>>   	PIPE_CONF_CHECK_I(name.crtc_vdisplay); \
>> -	if (!fastset || !allow_vblank_delay_fastset_lrr(current_config)) \
>> +	if (!fastset || !allow_vblank_delay_fastset(current_config, pipe_config)) \
>>   		PIPE_CONF_CHECK_I(name.crtc_vblank_start); \
>>   	PIPE_CONF_CHECK_I(name.crtc_vsync_start); \
>>   	PIPE_CONF_CHECK_I(name.crtc_vsync_end); \
>> -- 
>> 2.45.2

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-10-01 10:34     ` Nautiyal, Ankit K
@ 2025-10-01 12:10       ` Ville Syrjälä
  2025-10-01 13:16         ` Nautiyal, Ankit K
  0 siblings, 1 reply; 27+ messages in thread
From: Ville Syrjälä @ 2025-10-01 12:10 UTC (permalink / raw)
  To: Nautiyal, Ankit K; +Cc: intel-gfx, intel-xe

On Wed, Oct 01, 2025 at 04:04:37PM +0530, Nautiyal, Ankit K wrote:
> 
> On 9/29/2025 2:15 PM, Ville Syrjälä wrote:
> > On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
> >> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
> >> +				    struct intel_crtc *crtc)
> >> +{
> >> +	struct intel_crtc_state *crtc_state =
> >> +		intel_atomic_get_new_crtc_state(state, crtc);
> >> +	struct drm_display_mode *adjusted_mode =
> >> +		&crtc_state->hw.adjusted_mode;
> >> +	int vblank_delay = 0;
> >> +
> >> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
> >> +
> >> +	adjusted_mode->crtc_vblank_start += vblank_delay;
> > The situation with crtc_vblank_start is already kinda broken,
> > and I think we need to fix that first somehow.
> >
> > Currently crtc_vblank_start is assumed to be the vblank_start
> > for the fixed refresh rate case. That value can be different
> > from the variable refresh rate case whenever
> > always_use_vrr_tg()==false. On icl/tgl it's always different
> > due to the extra vblank delay, and also on adl+ it could be
> > different if we were to use an optimized guardband.
> >
> > I think there are a few options how we might solve this:
> > 1. keep crtc_vblank_start as is, and make sure every user of it
> >     gets adjusted to also deal with the vrr case correctly
> 
> 
> Alright, so we avoid changing the vblank_start.
> It means for platforms with always_use_vrr_tg()==true we directly set 
> the value for guardband. (Currently I was getting it from vmin_vtotal - 
> vblank_start)
> For platforms ADL+ with always always_use_vrr_tg()== false for the fixed 
> refresh rate case, guardband is full vblank_length for variable refresh 
> rate set the guardband directly.

I think we could just use something like this:

something_something_vblank_len()
{
	if (crtc_state->vrr.enable)
		return crtc_state->vrr.guardband;
	else
		return adjuste_mode.crtc_vtotal -
			adjusted_mode.crtc_vblank_start;
}

That should work fine for for both values of always_use_vrr_tg().

> 
> As you have mentioned need to check which all places we need vblank_start.
> 
> For ICL/TGL we do not use optimization for now, right?

Effectively we do, because of intel_vrr_extra_vblank_delay().
The VRR guardband is always one line less than the fixed refresh
rate guardband. And if we run into the max pipeline full limit
then the difference would be even larger.

> The extra_vblank_delay quirk is already handled while filling the 
> registers.
> 
> 
> > 2. enable always_use_vrr_tg() whenever there might be switch
> >     between vrr and fixed refresh rate, which I think would mean
> >     crtc_state->vrr.in_range==true.
> I think I didnt get this part:
> Do you mean later at some point we move to option 2: 
> always_use_vrr_tg()==true for all platforms.(Need to check if we can do 
> it for ICL, TGL).

I'm pretty sure I tested always_use_vrr_tg()==true briefly on
TGL and ADL and it seemed to be working fine.

But I'm a bit concerned becase we originally enabled the VRR timing
generator earlier during the modeset (but not from the very start IIRC),
and that wasn't working all that well on some systems. So later I
changed things to keep running with the legacy TG for the modeset and
only switch to the VRR TG at the very end. It might have been some MTL
system where we had these problems actually...

It's of course possible that we've since fixed whatever was the
underlying cause there. Or maybe the problem really was that we
started to use the VRR timings already during the modeset. With the
current always_use_vrr_tg()==true code we will still use the fixed
refresh rate timings for the modeset, and switch to the VRR timings
only at the very end.

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-10-01 10:41     ` Nautiyal, Ankit K
@ 2025-10-01 12:12       ` Ville Syrjälä
  2025-10-01 13:17         ` Nautiyal, Ankit K
  0 siblings, 1 reply; 27+ messages in thread
From: Ville Syrjälä @ 2025-10-01 12:12 UTC (permalink / raw)
  To: Nautiyal, Ankit K; +Cc: intel-gfx, intel-xe

On Wed, Oct 01, 2025 at 04:11:13PM +0530, Nautiyal, Ankit K wrote:
> 
> On 9/29/2025 2:30 PM, Ville Syrjälä wrote:
> > On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
> >> As we move towards using a shorter, optimized guardband, we need to adjust
> >> how the delayed vblank start is computed.
> >>
> >> Use the helper intel_vrr_compute_guardband() to calculate the optimized
> >> guardband. Since this is measured from the vblank end, we shift the
> >> vblank-start accordingly.
> >>
> >> Calculate the minimum delay required based on the guardband and apply it in
> >> intel_crtc_vblank_delay() to update crtc_vblank_start.
> >>
> >> Additionally, introduce a new allow_vblank_delay_fastset() helper that
> >> combines the existing LRR-based logic with an additional check for the
> >> optimized guardband usage.
> >>
> >> v2:
> >> - Check if optimized guardband is more than vblank length and add debug
> >>    print.
> >> - Extend vblank delay fastset logic to cover optimized guardband.
> >>
> >> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> >> ---
> >>   drivers/gpu/drm/i915/display/intel_display.c | 79 +++++++++++++++++++-
> >>   1 file changed, 76 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> >> index 4135f9be53fd..97a3121a204f 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> >> @@ -2361,6 +2361,67 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
> >>   	return 0;
> >>   }
> >>   
> >> +static
> >> +int intel_crtc_min_guardband_delay(struct intel_atomic_state *state,
> >> +				   struct intel_crtc *crtc)
> >> +{
> >> +	struct intel_display *display = to_intel_display(state);
> >> +	struct intel_crtc_state *crtc_state =
> >> +		intel_atomic_get_new_crtc_state(state, crtc);
> >> +	const struct drm_display_mode *adjusted_mode =
> >> +		&crtc_state->hw.adjusted_mode;
> >> +	struct drm_connector_state *conn_state;
> >> +	struct drm_connector *drm_connector;
> >> +	int vblank_length;
> >> +	int i;
> >> +
> >> +	if (!intel_vrr_use_optimized_guardband(crtc_state))
> >> +		return 0;
> >> +
> >> +	vblank_length = crtc_state->vrr.vmin -
> >> +			adjusted_mode->crtc_vdisplay;
> >> +
> >> +	for_each_new_connector_in_state(&state->base,
> >> +					drm_connector,
> >> +					conn_state, i) {
> >> +		int guardband;
> >> +		struct intel_connector *connector;
> >> +
> >> +		if (conn_state->crtc != &crtc->base)
> >> +			continue;
> >> +
> >> +		connector = to_intel_connector(drm_connector);
> >> +		guardband = intel_vrr_compute_guardband(crtc_state,
> >> +							connector);
> >> +		if (guardband > vblank_length) {
> >> +			drm_dbg_kms(display->drm,
> >> +				    "[CRTC:%d:%s] Cannot optimize guardband (%d) exceeds max (%d)\n",
> >> +				    crtc->base.base.id, crtc->base.name,
> >> +				    guardband,
> >> +				    vblank_length);
> >> +			return 0;
> >> +		}
> >> +
> >> +		return vblank_length - guardband;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
> >> +				    struct intel_crtc *crtc)
> >> +{
> >> +	struct intel_crtc_state *crtc_state =
> >> +		intel_atomic_get_new_crtc_state(state, crtc);
> >> +	struct drm_display_mode *adjusted_mode =
> >> +		&crtc_state->hw.adjusted_mode;
> >> +	int vblank_delay = 0;
> >> +
> >> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
> >> +
> >> +	adjusted_mode->crtc_vblank_start += vblank_delay;
> >> +}
> >> +
> >>   static int intel_crtc_set_context_latency(struct intel_crtc_state *crtc_state)
> >>   {
> >>   	struct intel_display *display = to_intel_display(crtc_state);
> >> @@ -2413,6 +2474,7 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
> >>   	ret = intel_crtc_compute_set_context_latency(state, crtc);
> >>   	if (ret)
> >>   		return ret;
> >> +	intel_crtc_vblank_delay(state, crtc);
> > IMO we should get rid of all this vblank_delay terminology here.
> > This one I think should just be our current
> > intel_vrr_compute_config_late() (renamed to eg.
> > intel_vrr_compute_guardband()).
> 
> Hmm ok so will rename this and call from intel_modeset_pipe_config_late().

I meant you should move the intel_vrr_compute_config_late() call
from intel_modeset_pipe_config_late() to here, and rename it to
eg. intel_vrr_compute_guardband().

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-10-01 12:10       ` Ville Syrjälä
@ 2025-10-01 13:16         ` Nautiyal, Ankit K
  0 siblings, 0 replies; 27+ messages in thread
From: Nautiyal, Ankit K @ 2025-10-01 13:16 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, intel-xe


On 10/1/2025 5:40 PM, Ville Syrjälä wrote:
> On Wed, Oct 01, 2025 at 04:04:37PM +0530, Nautiyal, Ankit K wrote:
>> On 9/29/2025 2:15 PM, Ville Syrjälä wrote:
>>> On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
>>>> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
>>>> +				    struct intel_crtc *crtc)
>>>> +{
>>>> +	struct intel_crtc_state *crtc_state =
>>>> +		intel_atomic_get_new_crtc_state(state, crtc);
>>>> +	struct drm_display_mode *adjusted_mode =
>>>> +		&crtc_state->hw.adjusted_mode;
>>>> +	int vblank_delay = 0;
>>>> +
>>>> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
>>>> +
>>>> +	adjusted_mode->crtc_vblank_start += vblank_delay;
>>> The situation with crtc_vblank_start is already kinda broken,
>>> and I think we need to fix that first somehow.
>>>
>>> Currently crtc_vblank_start is assumed to be the vblank_start
>>> for the fixed refresh rate case. That value can be different
>>> from the variable refresh rate case whenever
>>> always_use_vrr_tg()==false. On icl/tgl it's always different
>>> due to the extra vblank delay, and also on adl+ it could be
>>> different if we were to use an optimized guardband.
>>>
>>> I think there are a few options how we might solve this:
>>> 1. keep crtc_vblank_start as is, and make sure every user of it
>>>      gets adjusted to also deal with the vrr case correctly
>>
>> Alright, so we avoid changing the vblank_start.
>> It means for platforms with always_use_vrr_tg()==true we directly set
>> the value for guardband. (Currently I was getting it from vmin_vtotal -
>> vblank_start)
>> For platforms ADL+ with always always_use_vrr_tg()== false for the fixed
>> refresh rate case, guardband is full vblank_length for variable refresh
>> rate set the guardband directly.
> I think we could just use something like this:
>
> something_something_vblank_len()
> {
> 	if (crtc_state->vrr.enable)
> 		return crtc_state->vrr.guardband;
> 	else
> 		return adjuste_mode.crtc_vtotal -
> 			adjusted_mode.crtc_vblank_start;
> }
>
> That should work fine for for both values of always_use_vrr_tg().

Yep I had something similar in mind.


>
>> As you have mentioned need to check which all places we need vblank_start.
>>
>> For ICL/TGL we do not use optimization for now, right?
> Effectively we do, because of intel_vrr_extra_vblank_delay().
> The VRR guardband is always one line less than the fixed refresh
> rate guardband. And if we run into the max pipeline full limit
> then the difference would be even larger.

Oh ok, got it.


>
>> The extra_vblank_delay quirk is already handled while filling the
>> registers.
>>
>>
>>> 2. enable always_use_vrr_tg() whenever there might be switch
>>>      between vrr and fixed refresh rate, which I think would mean
>>>      crtc_state->vrr.in_range==true.
>> I think I didnt get this part:
>> Do you mean later at some point we move to option 2:
>> always_use_vrr_tg()==true for all platforms.(Need to check if we can do
>> it for ICL, TGL).
> I'm pretty sure I tested always_use_vrr_tg()==true briefly on
> TGL and ADL and it seemed to be working fine.
>
> But I'm a bit concerned becase we originally enabled the VRR timing
> generator earlier during the modeset (but not from the very start IIRC),
> and that wasn't working all that well on some systems. So later I
> changed things to keep running with the legacy TG for the modeset and
> only switch to the VRR TG at the very end. It might have been some MTL
> system where we had these problems actually...
>
> It's of course possible that we've since fixed whatever was the
> underlying cause there. Or maybe the problem really was that we
> started to use the VRR timings already during the modeset. With the
> current always_use_vrr_tg()==true code we will still use the fixed
> refresh rate timings for the modeset, and switch to the VRR timings
> only at the very end.

Hmm I think PSR was giving problem with fixed refresh rate mode for TGL 
when I had tried that, but it was long back.

Need to recheck that.

Thanks for clearing things up.

Regards,

Ankit

>

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

* Re: [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start
  2025-10-01 12:12       ` Ville Syrjälä
@ 2025-10-01 13:17         ` Nautiyal, Ankit K
  0 siblings, 0 replies; 27+ messages in thread
From: Nautiyal, Ankit K @ 2025-10-01 13:17 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, intel-xe


On 10/1/2025 5:42 PM, Ville Syrjälä wrote:
> On Wed, Oct 01, 2025 at 04:11:13PM +0530, Nautiyal, Ankit K wrote:
>> On 9/29/2025 2:30 PM, Ville Syrjälä wrote:
>>> On Sun, Sep 28, 2025 at 12:35:40PM +0530, Ankit Nautiyal wrote:
>>>> As we move towards using a shorter, optimized guardband, we need to adjust
>>>> how the delayed vblank start is computed.
>>>>
>>>> Use the helper intel_vrr_compute_guardband() to calculate the optimized
>>>> guardband. Since this is measured from the vblank end, we shift the
>>>> vblank-start accordingly.
>>>>
>>>> Calculate the minimum delay required based on the guardband and apply it in
>>>> intel_crtc_vblank_delay() to update crtc_vblank_start.
>>>>
>>>> Additionally, introduce a new allow_vblank_delay_fastset() helper that
>>>> combines the existing LRR-based logic with an additional check for the
>>>> optimized guardband usage.
>>>>
>>>> v2:
>>>> - Check if optimized guardband is more than vblank length and add debug
>>>>     print.
>>>> - Extend vblank delay fastset logic to cover optimized guardband.
>>>>
>>>> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>>>> ---
>>>>    drivers/gpu/drm/i915/display/intel_display.c | 79 +++++++++++++++++++-
>>>>    1 file changed, 76 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>>>> index 4135f9be53fd..97a3121a204f 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>>>> @@ -2361,6 +2361,67 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
>>>>    	return 0;
>>>>    }
>>>>    
>>>> +static
>>>> +int intel_crtc_min_guardband_delay(struct intel_atomic_state *state,
>>>> +				   struct intel_crtc *crtc)
>>>> +{
>>>> +	struct intel_display *display = to_intel_display(state);
>>>> +	struct intel_crtc_state *crtc_state =
>>>> +		intel_atomic_get_new_crtc_state(state, crtc);
>>>> +	const struct drm_display_mode *adjusted_mode =
>>>> +		&crtc_state->hw.adjusted_mode;
>>>> +	struct drm_connector_state *conn_state;
>>>> +	struct drm_connector *drm_connector;
>>>> +	int vblank_length;
>>>> +	int i;
>>>> +
>>>> +	if (!intel_vrr_use_optimized_guardband(crtc_state))
>>>> +		return 0;
>>>> +
>>>> +	vblank_length = crtc_state->vrr.vmin -
>>>> +			adjusted_mode->crtc_vdisplay;
>>>> +
>>>> +	for_each_new_connector_in_state(&state->base,
>>>> +					drm_connector,
>>>> +					conn_state, i) {
>>>> +		int guardband;
>>>> +		struct intel_connector *connector;
>>>> +
>>>> +		if (conn_state->crtc != &crtc->base)
>>>> +			continue;
>>>> +
>>>> +		connector = to_intel_connector(drm_connector);
>>>> +		guardband = intel_vrr_compute_guardband(crtc_state,
>>>> +							connector);
>>>> +		if (guardband > vblank_length) {
>>>> +			drm_dbg_kms(display->drm,
>>>> +				    "[CRTC:%d:%s] Cannot optimize guardband (%d) exceeds max (%d)\n",
>>>> +				    crtc->base.base.id, crtc->base.name,
>>>> +				    guardband,
>>>> +				    vblank_length);
>>>> +			return 0;
>>>> +		}
>>>> +
>>>> +		return vblank_length - guardband;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static void intel_crtc_vblank_delay(struct intel_atomic_state *state,
>>>> +				    struct intel_crtc *crtc)
>>>> +{
>>>> +	struct intel_crtc_state *crtc_state =
>>>> +		intel_atomic_get_new_crtc_state(state, crtc);
>>>> +	struct drm_display_mode *adjusted_mode =
>>>> +		&crtc_state->hw.adjusted_mode;
>>>> +	int vblank_delay = 0;
>>>> +
>>>> +	vblank_delay = intel_crtc_min_guardband_delay(state, crtc);
>>>> +
>>>> +	adjusted_mode->crtc_vblank_start += vblank_delay;
>>>> +}
>>>> +
>>>>    static int intel_crtc_set_context_latency(struct intel_crtc_state *crtc_state)
>>>>    {
>>>>    	struct intel_display *display = to_intel_display(crtc_state);
>>>> @@ -2413,6 +2474,7 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
>>>>    	ret = intel_crtc_compute_set_context_latency(state, crtc);
>>>>    	if (ret)
>>>>    		return ret;
>>>> +	intel_crtc_vblank_delay(state, crtc);
>>> IMO we should get rid of all this vblank_delay terminology here.
>>> This one I think should just be our current
>>> intel_vrr_compute_config_late() (renamed to eg.
>>> intel_vrr_compute_guardband()).
>> Hmm ok so will rename this and call from intel_modeset_pipe_config_late().
> I meant you should move the intel_vrr_compute_config_late() call
> from intel_modeset_pipe_config_late() to here, and rename it to
> eg. intel_vrr_compute_guardband().

Oh ok sorry I got it other way round. Will do as suggested.

Regards,

Ankit

>

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

end of thread, other threads:[~2025-10-01 13:17 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-28  7:05 [PATCH 00/15] Optimize vrr.guardband and fix LRR Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 01/15] drm/i915/vrr: Use crtc_vsync_start/end for computing vrr.vsync_start/end Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 02/15] drm/i915/skl_watermark: Fix the scaling factor for chroma subsampling Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 03/15] drm/i915/skl_watermark: Pass linetime as argument to latency helpers Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 04/15] drm/i915/skl_scaler: Introduce helper for chroma downscale factor Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 05/15] drm/i915/display: Extract helpers to set dsc/scaler prefill latencies Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 06/15] drm/i915/dp: Add SDP latency computation helper Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 07/15] drm/i915/alpm: Add function to compute max link-wake latency Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 08/15] drm/i915/display: Add guardband check for feature latencies Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 09/15] drm/i915/skl_watermark: Remove redundant latency checks from vblank validation Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 10/15] drm/i915/vrr: Introduce helper to compute min static guardband Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 11/15] drm/i915/vrr: Use optimized guardband when VRR TG is active Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 12/15] drm/i915/vrr: Prepare for movement of vblank start for optimized guardband Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 13/15] drm/i915/display: Recompute crtc_vblank_start " Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 14/15] drm/i915/display: s/allow_vblank_delay_fastset/allow_vblank_delay_fastset_lrr Ankit Nautiyal
2025-09-28  7:05 ` [PATCH 15/15] drm/i915/display: Use optimized guardband to set vblank start Ankit Nautiyal
2025-09-29  8:45   ` Ville Syrjälä
2025-09-29  9:09     ` Ville Syrjälä
2025-09-29  9:21     ` Ville Syrjälä
2025-10-01 10:34     ` Nautiyal, Ankit K
2025-10-01 12:10       ` Ville Syrjälä
2025-10-01 13:16         ` Nautiyal, Ankit K
2025-09-29  9:00   ` Ville Syrjälä
2025-10-01 10:41     ` Nautiyal, Ankit K
2025-10-01 12:12       ` Ville Syrjälä
2025-10-01 13:17         ` Nautiyal, Ankit K
2025-09-28  8:07 ` ✗ i915.CI.BAT: failure for Optimize vrr.guardband and fix LRR (rev12) Patchwork

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