intel-xe.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drm/i915/vrr: Set vrr.vmin to min Vtotal to re-enable LRR for PTL
@ 2025-05-09  3:11 Ankit Nautiyal
  2025-05-09  3:35 ` ✓ CI.Patch_applied: success for " Patchwork
                   ` (16 more replies)
  0 siblings, 17 replies; 19+ messages in thread
From: Ankit Nautiyal @ 2025-05-09  3:11 UTC (permalink / raw)
  To: intel-gfx, intel-xe; +Cc: ville.syrjala

Currently in intel_vrr_compute_config, we set vrr.vmin to crtc_vtotal for
all cases to avoid having vrr.vmin changed when we switch from
fixed refresh rate timings to variable refresh rate timings. This works for
all cases, except for LRR case where user can change the clock so as to
seamlessly switch to a lower refresh rate only for a VRR supporting panel.

In LRR case the crtc_vtotal changes for the mode, and due to which vrr.vmin
changes and therefore the guardband also changes. Since we cannot change
the guardband on the fly when VRR Timing Generator is on, this gets
rejected.

To overcome this, for panels that support VRR, instead of setting the
vrr.vmin to crtc_vtotal, we set that to the lowest Vtotal (for highest
Refresh rate supported by the panel). For non-vrr panels, the vrr.vmin
stays the same i.e. crtc_vtotal.

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

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index c6565baf815a..f0949a598f53 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -278,6 +278,9 @@ int intel_vrr_fixed_rr_vmin(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_display *display = to_intel_display(crtc_state);
 
+	if (crtc_state->vrr.in_range)
+		return crtc_state->vrr.vmin;
+
 	return intel_vrr_fixed_rr_vtotal(crtc_state) -
 		intel_vrr_flipline_offset(display);
 }
@@ -308,26 +311,37 @@ static
 void intel_vrr_compute_fixed_rr_timings(struct intel_crtc_state *crtc_state)
 {
 	/*
-	 * For fixed rr,  vmin = vmax = flipline.
-	 * vmin is already set to crtc_vtotal set vmax and flipline the same.
+	 * For fixed rr vmax = flipline.
+	 * set vmax and flipline same as vtotal.
 	 */
 	crtc_state->vrr.vmax = crtc_state->hw.adjusted_mode.crtc_vtotal;
 	crtc_state->vrr.flipline = crtc_state->hw.adjusted_mode.crtc_vtotal;
 }
 
 static
-int intel_vrr_compute_vmin(struct intel_crtc_state *crtc_state)
+int intel_vrr_compute_fixed_vmin(struct intel_crtc_state *crtc_state)
 {
 	/*
-	 * To make fixed rr and vrr work seamless the guardband/pipeline full
-	 * should be set such that it satisfies both the fixed and variable
-	 * timings.
-	 * For this set the vmin as crtc_vtotal. With this we never need to
-	 * change anything to do with the guardband.
+	 * For non VRR supporting panels/config, set the vmin to crtc_vtotal.
+	 * This will help the case where VRR TG is used even for non-vrr panels/config.
 	 */
 	return crtc_state->hw.adjusted_mode.crtc_vtotal;
 }
 
+static
+int intel_vrr_compute_vmin(struct intel_connector *connector,
+			   const struct drm_display_mode *adjusted_mode)
+{
+	const struct drm_display_info *info = &connector->base.display_info;
+	int vmin;
+
+	vmin = adjusted_mode->crtc_clock * 1000 /
+		(adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq);
+	vmin = min_t(int, vmin, adjusted_mode->crtc_vtotal);
+
+	return vmin;
+}
+
 static
 int intel_vrr_compute_vmax(struct intel_connector *connector,
 			   const struct drm_display_mode *adjusted_mode)
@@ -374,13 +388,13 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
 	if (crtc_state->joiner_pipes)
 		crtc_state->vrr.in_range = false;
 
-	vmin = intel_vrr_compute_vmin(crtc_state);
-
 	if (crtc_state->vrr.in_range) {
 		if (HAS_LRR(display))
 			crtc_state->update_lrr = true;
 		vmax = intel_vrr_compute_vmax(connector, adjusted_mode);
+		vmin = intel_vrr_compute_vmin(connector, adjusted_mode);
 	} else {
+		vmin = intel_vrr_compute_fixed_vmin(crtc_state);
 		vmax = vmin;
 	}
 
@@ -671,8 +685,7 @@ void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state)
 bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state)
 {
 	return crtc_state->vrr.flipline &&
-	       crtc_state->vrr.flipline == crtc_state->vrr.vmax &&
-	       crtc_state->vrr.flipline == intel_vrr_vmin_flipline(crtc_state);
+	       crtc_state->vrr.flipline == crtc_state->vrr.vmax;
 }
 
 void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
@@ -713,16 +726,6 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
 		crtc_state->vrr.vmin = intel_de_read(display,
 						     TRANS_VRR_VMIN(display, cpu_transcoder)) + 1;
 
-		/*
-		 * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal
-		 * bits are not filled. Since for these platforms TRAN_VMIN is always
-		 * filled with crtc_vtotal, use TRAN_VRR_VMIN to get the vtotal for
-		 * adjusted_mode.
-		 */
-		if (intel_vrr_always_use_vrr_tg(display))
-			crtc_state->hw.adjusted_mode.crtc_vtotal =
-				intel_vrr_vmin_vtotal(crtc_state);
-
 		if (HAS_AS_SDP(display)) {
 			trans_vrr_vsync =
 				intel_de_read(display,
@@ -732,6 +735,23 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
 			crtc_state->vrr.vsync_end =
 				REG_FIELD_GET(VRR_VSYNC_END_MASK, trans_vrr_vsync);
 		}
+		/*
+		 * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal
+		 * bits are not filled. For fixed timings the vmax vtotal can be used to
+		 * fill the VTOTAL. For variable timings, we need to compute the vtotal.
+		 */
+		if (intel_vrr_always_use_vrr_tg(display)) {
+			u32 crtc_vtotal;
+
+			if (intel_vrr_is_fixed_rr(crtc_state))
+				crtc_vtotal = intel_vrr_vmax_vtotal(crtc_state);
+			else
+				crtc_vtotal = intel_vrr_vmin_vtotal(crtc_state) +
+					      crtc_state->vrr.guardband +
+					      crtc_state->vrr.vsync_start +
+					      crtc_state->vrr.vsync_end + 1;
+			crtc_state->hw.adjusted_mode.crtc_vtotal = crtc_vtotal;
+		}
 	}
 
 	vrr_enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE;
-- 
2.45.2


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

end of thread, other threads:[~2025-05-29  9:09 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-09  3:11 [PATCH] drm/i915/vrr: Set vrr.vmin to min Vtotal to re-enable LRR for PTL Ankit Nautiyal
2025-05-09  3:35 ` ✓ CI.Patch_applied: success for " Patchwork
2025-05-09  3:35 ` ✓ CI.checkpatch: " Patchwork
2025-05-09  3:36 ` ✓ CI.KUnit: " Patchwork
2025-05-09  3:45 ` ✓ CI.Build: " Patchwork
2025-05-09  3:47 ` ✓ CI.Hooks: " Patchwork
2025-05-09  3:48 ` ✓ CI.checksparse: " Patchwork
2025-05-09  4:13 ` ✓ Xe.CI.BAT: " Patchwork
2025-05-09 16:30 ` ✗ Xe.CI.Full: failure " Patchwork
2025-05-22 10:28 ` ✓ CI.Patch_applied: success for drm/i915/vrr: Set vrr.vmin to min Vtotal to re-enable LRR for PTL (rev2) Patchwork
2025-05-22 10:29 ` ✓ CI.checkpatch: " Patchwork
2025-05-22 10:30 ` ✓ CI.KUnit: " Patchwork
2025-05-22 10:40 ` ✓ CI.Build: " Patchwork
2025-05-22 10:43 ` ✓ CI.Hooks: " Patchwork
2025-05-22 10:44 ` ✓ CI.checksparse: " Patchwork
2025-05-22 11:13 ` ✓ Xe.CI.BAT: " Patchwork
2025-05-22 20:46 ` ✗ Xe.CI.Full: failure " Patchwork
2025-05-28 11:47 ` [PATCH] drm/i915/vrr: Set vrr.vmin to min Vtotal to re-enable LRR for PTL Ville Syrjälä
2025-05-29  9:08   ` Nautiyal, Ankit K

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