Intel-GFX 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
Subject: [PATCH 14/16] drm/i915/vrr: Introduce helper to compute min static guardband
Date: Mon,  6 Oct 2025 09:58:50 +0530	[thread overview]
Message-ID: <20251006042852.263249-15-ankit.k.nautiyal@intel.com> (raw)
In-Reply-To: <20251006042852.263249-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.

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)

v7: Rename helper to intel_vrr_compute_optimized_guardband.

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 221b25832e56..2dca4be28a9c 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
@@ -433,6 +439,117 @@ intel_vrr_max_guardband(struct intel_crtc_state *crtc_state)
 		   intel_vrr_max_vblank_guardband(crtc_state));
 }
 
+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_optimized_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;
+}
+
 void intel_vrr_compute_guardband(struct intel_crtc_state *crtc_state)
 {
 	struct intel_display *display = to_intel_display(crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h
index bc9044621635..8d1f31ae92df 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_optimized_guardband(struct intel_crtc_state *crtc_state,
+					  struct intel_connector *connector);
 
 #endif /* __INTEL_VRR_H__ */
-- 
2.45.2


  parent reply	other threads:[~2025-10-06  4:42 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-06  4:28 [PATCH 00/16] Optimize vrr.guardband and fix LRR Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 01/16] drm/i915/vrr: Use crtc_vsync_start/end for computing vrr.vsync_start/end Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 02/16] drm/i915/skl_watermark: Fix the scaling factor for chroma subsampling Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 03/16] drm/i915/skl_watermark: Pass linetime as argument to latency helpers Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 04/16] drm/i915/skl_scaler: Introduce helper for chroma downscale factor Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 05/16] drm/i915/display: Extract helpers to set dsc/scaler prefill latencies Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 06/16] drm/i915/dp: Add SDP latency computation helper Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 07/16] drm/i915/alpm: Add function to compute max link-wake latency Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 08/16] drm/i915/display: Add guardband check for feature latencies Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 09/16] drm/i915/skl_watermark: Remove redundant latency checks from vblank validation Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 10/16] drm/i915/vrr: s/intel_vrr_compute_config_late/intel_vrr_compute_guardband Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 11/16] drm/i915/vblank: Add helper to get correct vblank length Ankit Nautiyal
2025-10-06 19:56   ` Ville Syrjälä
2025-10-07  5:52     ` Nautiyal, Ankit K
2025-10-07 15:16       ` Ville Syrjälä
2025-10-07 17:30         ` Ville Syrjälä
2025-10-08  6:34           ` Nautiyal, Ankit K
2025-10-06  4:28 ` [PATCH 12/16] drm/i915/vrr: Recompute vblank_start for platforms with always-on VRR TG Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 13/16] drm/i915/display: Add vblank_start adjustment logic for " Ankit Nautiyal
2025-10-06 19:56   ` Ville Syrjälä
2025-10-07  6:30     ` Nautiyal, Ankit K
2025-10-07 15:19       ` Ville Syrjälä
2025-10-06  4:28 ` Ankit Nautiyal [this message]
2025-10-06  4:28 ` [PATCH 15/16] drm/i915/display: Use optimized guardband " Ankit Nautiyal
2025-10-06  4:28 ` [PATCH 16/16] drm/i915/vrr: Use optimized guardband when VRR TG is active Ankit Nautiyal
2025-10-06  9:56 ` ✓ i915.CI.BAT: success for Optimize vrr.guardband and fix LRR (rev13) Patchwork
2025-10-06 11:54 ` ✗ i915.CI.Full: failure " Patchwork
2025-10-06 22:50 ` [PATCH 00/16] Optimize vrr.guardband and fix LRR Ville Syrjälä
2025-10-07  6:33   ` Nautiyal, Ankit K
2025-10-07 15:22     ` 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=20251006042852.263249-15-ankit.k.nautiyal@intel.com \
    --to=ankit.k.nautiyal@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --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