Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Cc: ville.syrjala@linux.intel.com, uma.shankar@intel.com,
	Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Subject: [PATCH 6/6] drm/i915/vrr: Use the min static optimized guardband
Date: Wed, 15 Oct 2025 15:52:41 +0530	[thread overview]
Message-ID: <20251015102241.1797828-7-ankit.k.nautiyal@intel.com> (raw)
In-Reply-To: <20251015102241.1797828-1-ankit.k.nautiyal@intel.com>

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.
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.

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

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 1cfcc31bd899..4d96aad93dba 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -6,12 +6,16 @@
 
 #include <drm/drm_print.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_psr.h"
 #include "intel_vrr.h"
 #include "intel_vrr_regs.h"
+#include "skl_prefill.h"
+#include "skl_watermark.h"
 
 #define FIXED_POINT_PRECISION		100
 #define CMRR_PRECISION_TOLERANCE	10
@@ -433,17 +437,70 @@ intel_vrr_max_guardband(struct intel_crtc_state *crtc_state)
 		   intel_vrr_max_vblank_guardband(crtc_state));
 }
 
+static
+int intel_vrr_compute_optimized_guardband(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;
+	struct skl_prefill_ctx prefill_ctx;
+	int prefill_framestart_delay = 1;
+	int prefill_min_guardband;
+	int prefill_latency_us;
+	int prefill_wm0_lines;
+	int prefill_sagv_us;
+	int psr_latency = 0;
+	int sdp_latency = 0;
+	int guardband;
+
+	skl_prefill_init_worst(&prefill_ctx, crtc_state);
+	prefill_wm0_lines = skl_wm0_prefill_lines_worst(crtc_state);
+	prefill_sagv_us = display->sagv.block_time_us;
+
+	prefill_latency_us = prefill_sagv_us +
+			     intel_scanlines_to_usecs(adjusted_mode,
+						      prefill_framestart_delay +
+						      prefill_wm0_lines);
+	prefill_min_guardband =
+		skl_prefill_min_guardband(&prefill_ctx,
+					  crtc_state,
+					  prefill_latency_us);
+
+	if (intel_crtc_has_dp_encoder(crtc_state)) {
+		psr_latency = intel_psr_max_link_wake_latency(crtc_state);
+		sdp_latency = intel_dp_compute_sdp_latency(crtc_state);
+	}
+
+	guardband = max(sdp_latency, psr_latency);
+
+	guardband = max(guardband, prefill_min_guardband);
+
+	return guardband;
+}
+
+static 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;
+}
+
 void intel_vrr_compute_guardband(struct intel_crtc_state *crtc_state)
 {
 	struct intel_display *display = to_intel_display(crtc_state);
 	struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_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 = intel_vrr_compute_optimized_guardband(crtc_state);
+	else
+		guardband = crtc_state->vrr.vmin - adjusted_mode->crtc_vdisplay;
+
+	crtc_state->vrr.guardband = min(guardband, intel_vrr_max_guardband(crtc_state));
 
 	if (intel_vrr_always_use_vrr_tg(display)) {
 		adjusted_mode->crtc_vblank_start  =
-- 
2.45.2


  parent reply	other threads:[~2025-10-15 10:36 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-15 10:22 [PATCH 0/6] Optimize vrr.guardband Ankit Nautiyal
2025-10-15 10:22 ` [PATCH 1/6] [NOT FOR REVIEW] drm/i915/vrr: prep patches for guardband optimization squashed Ankit Nautiyal
2025-10-15 10:22 ` [PATCH 2/6] [NOT FOR REVIEW] drm/i915/prefill: Prefill latency calculations series squashed Ankit Nautiyal
2025-10-15 10:22 ` [PATCH 3/6] drm/i915/dp: Add SDP latency computation helper Ankit Nautiyal
2025-10-15 10:22 ` [PATCH 4/6] drm/i915/psr: Add function to compute max link-wake latency Ankit Nautiyal
2025-10-15 10:22 ` [PATCH 5/6] drm/i915/display: Add guardband check for feature latencies Ankit Nautiyal
2025-10-15 16:36   ` Ville Syrjälä
2025-10-16  4:06     ` Nautiyal, Ankit K
2025-10-15 10:22 ` Ankit Nautiyal [this message]
2025-10-15 17:00 ` ✗ CI.checkpatch: warning for Optimize vrr.guardband Patchwork
2025-10-15 17:02 ` ✓ CI.KUnit: success " Patchwork
2025-10-15 17:17 ` ✗ CI.checksparse: warning " Patchwork
2025-10-15 18:11 ` ✗ Xe.CI.BAT: failure " Patchwork
2025-10-16  4:15 ` ✗ Xe.CI.Full: " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2025-10-16  9:30 [PATCH 0/6] " Ankit Nautiyal
2025-10-16  9:30 ` [PATCH 6/6] drm/i915/vrr: Use the min static optimized guardband Ankit Nautiyal
2025-10-16 17:29   ` Ville Syrjälä

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251015102241.1797828-7-ankit.k.nautiyal@intel.com \
    --to=ankit.k.nautiyal@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=uma.shankar@intel.com \
    --cc=ville.syrjala@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox