intel-gfx.lists.freedesktop.org archive mirror
 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, jani.nikula@linux.intel.com,
	mitulkumar.ajitkumar.golani@intel.com,
	Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Subject: [PATCH 10/12] drm/i915/vrr: Use static guardband to support seamless LRR switching
Date: Thu,  7 Aug 2025 16:45:46 +0530	[thread overview]
Message-ID: <20250807111548.1490624-11-ankit.k.nautiyal@intel.com> (raw)
In-Reply-To: <20250807111548.1490624-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.

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.

Bspec: 70151
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c |   2 +-
 drivers/gpu/drm/i915/display/intel_vrr.c     | 132 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_vrr.h     |   3 +-
 3 files changed, 133 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index c542a3110051..a80a220ffc0d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4898,7 +4898,6 @@ intel_modeset_pipe_config_late(struct intel_atomic_state *state,
 	struct drm_connector *connector;
 	int i;
 
-	intel_vrr_compute_config_late(crtc_state);
 
 	for_each_new_connector_in_state(&state->base, connector,
 					conn_state, i) {
@@ -4910,6 +4909,7 @@ intel_modeset_pipe_config_late(struct intel_atomic_state *state,
 		    !encoder->compute_config_late)
 			continue;
 
+		intel_vrr_compute_config_late(crtc_state, conn_state);
 		ret = encoder->compute_config_late(encoder, crtc_state,
 						   conn_state);
 		if (ret)
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 46a85720411f..170f7bcdb8a8 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -6,12 +6,15 @@
 
 #include <drm/drm_print.h>
 
+#include "intel_alpm.h"
 #include "intel_de.h"
 #include "intel_display_regs.h"
 #include "intel_display_types.h"
 #include "intel_dp.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
@@ -413,15 +416,140 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
 	}
 }
 
-void intel_vrr_compute_config_late(struct intel_crtc_state *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 intel_display_scaler_prefill_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_display_dsc_prefill_latency(num_scaler_users, hscale_k, vscale_k,
+						 chroma_downscaling_factor,
+						 cdclk_adjustment,
+						 linetime_us);
+}
+
+static
+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 = DIV_ROUND_UP(guardband_us, linetime_us);
+
+	/* guardband cannot be more than the Vmax vblank */
+	guardband = min(guardband, crtc_state->vrr.vmax - adjusted_mode->crtc_vblank_start);
+
+	return guardband;
+}
+
+void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state,
+				   struct drm_connector_state *conn_state)
 {
 	struct intel_display *display = to_intel_display(crtc_state);
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+	struct intel_connector *connector =
+		to_intel_connector(conn_state->connector);
 
 	if (!intel_vrr_possible(crtc_state))
 		return;
 
-	if (DISPLAY_VER(display) >= 13) {
+	if (intel_vrr_always_use_vrr_tg(display)) {
+		crtc_state->vrr.guardband = intel_vrr_compute_guardband(crtc_state, connector);
+		if (crtc_state->uapi.vrr_enabled) {
+			crtc_state->vrr.vmin = crtc_state->vrr.guardband +
+					       adjusted_mode->crtc_vblank_start;
+			crtc_state->vrr.flipline = crtc_state->vrr.vmin;
+		}
+	} else if (DISPLAY_VER(display) >= 13) {
 		crtc_state->vrr.guardband =
 			crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start;
 	} else {
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h
index 38bf9996b883..4b15c2838492 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.h
+++ b/drivers/gpu/drm/i915/display/intel_vrr.h
@@ -21,7 +21,8 @@ bool intel_vrr_possible(const struct intel_crtc_state *crtc_state);
 void intel_vrr_check_modeset(struct intel_atomic_state *state);
 void intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
 			      struct drm_connector_state *conn_state);
-void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state);
+void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state,
+				   struct drm_connector_state *conn_state);
 void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
 void intel_vrr_enable(const struct intel_crtc_state *crtc_state);
 void intel_vrr_send_push(struct intel_dsb *dsb,
-- 
2.45.2


  parent reply	other threads:[~2025-08-07 11:33 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-07 11:15 [PATCH 00/12] Optimize vrr.guardband and fix LRR Ankit Nautiyal
2025-08-07 11:15 ` [PATCH 01/12] drm/i915/skl_watermark: Fix the scaling factor for chroma subsampling Ankit Nautiyal
2025-08-07 15:26   ` Golani, Mitulkumar Ajitkumar
2025-08-07 11:15 ` [PATCH 02/12] drm/i915/skl_watermark: Pass linetime as argument to latency helpers Ankit Nautiyal
2025-08-07 16:19   ` Golani, Mitulkumar Ajitkumar
2025-08-07 11:15 ` [PATCH 03/12] drm/i915/skl_scaler: Introduce helper for chroma downscale factor Ankit Nautiyal
2025-08-07 16:29   ` Golani, Mitulkumar Ajitkumar
2025-08-07 11:15 ` [PATCH 04/12] drm/i915/display: Extract helpers to set dsc/scaler prefill latencies Ankit Nautiyal
2025-08-11  6:16   ` Golani, Mitulkumar Ajitkumar
2025-08-18  6:09     ` Nautiyal, Ankit K
2025-08-07 11:15 ` [PATCH 05/12] drm/i915/dp: Add SDP latency computation helper Ankit Nautiyal
2025-08-07 11:15 ` [PATCH 06/12] drm/i915/alpm: Add function to compute max link-wake latency Ankit Nautiyal
2025-08-07 11:15 ` [PATCH 07/12] drm/i915/vrr: Use vrr.sync_start for getting vtotal Ankit Nautiyal
2025-08-07 17:01   ` Golani, Mitulkumar Ajitkumar
2025-08-07 11:15 ` [PATCH 08/12] drm/i915/display: Add guardband check for feature latencies Ankit Nautiyal
2025-08-11  9:11   ` Golani, Mitulkumar Ajitkumar
2025-08-18  6:01     ` Nautiyal, Ankit K
2025-08-11  9:59   ` Golani, Mitulkumar Ajitkumar
2025-08-18  6:00     ` Nautiyal, Ankit K
2025-08-11 15:14   ` Jani Nikula
2025-08-18  6:02     ` Nautiyal, Ankit K
2025-08-07 11:15 ` [PATCH 09/12] drm/i915/skl_watermark: Remove redundant latency checks from vblank validation Ankit Nautiyal
2025-08-07 17:03   ` Golani, Mitulkumar Ajitkumar
2025-08-07 11:15 ` Ankit Nautiyal [this message]
2025-08-07 11:15 ` [PATCH 11/12] drm/i915/panel: Add helper to get highest fixed mode Ankit Nautiyal
2025-08-11 15:22   ` Jani Nikula
2025-08-18  6:15     ` Nautiyal, Ankit K
2025-08-07 11:15 ` [PATCH 12/12] drm/i915/vrr: Fix seamless_mn drrs for PTL Ankit Nautiyal
2025-08-07 12:22 ` ✓ i915.CI.BAT: success for Optimize vrr.guardband and fix LRR (rev4) Patchwork
2025-08-07 16:31 ` ✓ i915.CI.Full: " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2025-08-18  7:31 [PATCH 00/12] Optimize vrr.guardband and fix LRR Ankit Nautiyal
2025-08-18  7:31 ` [PATCH 10/12] drm/i915/vrr: Use static guardband to support seamless LRR switching Ankit Nautiyal
2025-08-19  9:23   ` Golani, Mitulkumar Ajitkumar
2025-08-20  8:04 [PATCH 00/12] Optimize vrr.guardband and fix LRR Ankit Nautiyal
2025-08-20  8:04 ` [PATCH 10/12] drm/i915/vrr: Use static guardband to support seamless LRR switching Ankit Nautiyal
2025-08-25 12:35 [PATCH 00/12] Optimize vrr.guardband and fix LRR Ankit Nautiyal
2025-08-25 12:35 ` [PATCH 10/12] drm/i915/vrr: Use static guardband to support seamless LRR switching Ankit Nautiyal

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=20250807111548.1490624-11-ankit.k.nautiyal@intel.com \
    --to=ankit.k.nautiyal@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=mitulkumar.ajitkumar.golani@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;
as well as URLs for NNTP newsgroup(s).