[PATCH 3/4] drm/i915/vrr: Avoid reading/writing VTOTAL/VBLANK/VSYNC when vrr is enabled

Ankit Nautiyal ankit.k.nautiyal at intel.com
Thu Apr 18 05:25:16 UTC 2024


With VRR timing generator only Vertical Active field of Vtotal register
is required to be programmed and vertical total field is not used.
Similarly VBLANK and VSYNC are also not used with VRR timing generator.
So avoid reading/writing VTOTAL field and VBLANK, VSYNC register when
VRR is enabled.
To fill adjusted_mode->crtc_vtotal use VRR MAX register, in
intel_vrr_get_config.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 62 ++++++++++++++------
 drivers/gpu/drm/i915/display/intel_vrr.c     |  2 +
 2 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 2e46efba3376..a4e87f471520 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2713,16 +2713,25 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
 	intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder),
 		       HSYNC_START(adjusted_mode->crtc_hsync_start - 1) |
 		       HSYNC_END(adjusted_mode->crtc_hsync_end - 1));
-
-	intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
-		       VACTIVE(crtc_vdisplay - 1) |
-		       VTOTAL(crtc_vtotal - 1));
-	intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
-		       VBLANK_START(crtc_vblank_start - 1) |
-		       VBLANK_END(crtc_vblank_end - 1));
-	intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder),
-		       VSYNC_START(adjusted_mode->crtc_vsync_start - 1) |
-		       VSYNC_END(adjusted_mode->crtc_vsync_end - 1));
+	/*
+	 * When VRR is enabled:
+	 * Only Vertical Active is filled in TRANS_VTOTAL register, and
+	 * Vertical Total field is not required.
+	 * Similarly TRANS_VBLANK and TRANS_VSYNC are also not required.
+	 */
+	if (crtc_state->vrr.enable) {
+		intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+			       VACTIVE(crtc_vdisplay - 1));
+	} else {
+		intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+			       VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1));
+		intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+			       VBLANK_START(crtc_vblank_start - 1) |
+			       VBLANK_END(crtc_vblank_end - 1));
+		intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder),
+			       VSYNC_START(adjusted_mode->crtc_vsync_start - 1) |
+			       VSYNC_END(adjusted_mode->crtc_vsync_end - 1));
+	}
 
 	/* Workaround: when the EDP input selection is B, the VTOTAL_B must be
 	 * programmed with the VTOTAL_EDP value. Same for VTOTAL_C. This is
@@ -2750,6 +2759,13 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc
 
 	drm_WARN_ON(&dev_priv->drm, adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE);
 
+	/*
+	 * FIXME: Check if there is a need to write VTOTAL vertical active or
+	 * VRR VMAX in case of VRR framework.
+	 */
+	if (crtc_state->vrr.enable)
+		return;
+
 	/*
 	 * The hardware actually ignores TRANS_VBLANK.VBLANK_END in DP mode.
 	 * But let's write it anyway to keep the state checker happy.
@@ -2757,6 +2773,7 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc
 	intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
 		       VBLANK_START(crtc_vblank_start - 1) |
 		       VBLANK_END(crtc_vblank_end - 1));
+
 	/*
 	 * The double buffer latch point for TRANS_VTOTAL
 	 * is the transcoder's undelayed vblank.
@@ -2821,17 +2838,24 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
 
 	tmp = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder));
 	adjusted_mode->crtc_vdisplay = REG_FIELD_GET(VACTIVE_MASK, tmp) + 1;
-	adjusted_mode->crtc_vtotal = REG_FIELD_GET(VTOTAL_MASK, tmp) + 1;
 
-	/* FIXME TGL+ DSI transcoders have this! */
-	if (!transcoder_is_dsi(cpu_transcoder)) {
-		tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder));
-		adjusted_mode->crtc_vblank_start = REG_FIELD_GET(VBLANK_START_MASK, tmp) + 1;
-		adjusted_mode->crtc_vblank_end = REG_FIELD_GET(VBLANK_END_MASK, tmp) + 1;
+	/*
+	 * When VRR is enabled:
+	 * crtc_vtotal is filled in vrr_get_config with VRR_VMAX
+	 * VBLANK and VSYNC are not required.
+	 */
+	if (!pipe_config->vrr.enable) {
+		adjusted_mode->crtc_vtotal = REG_FIELD_GET(VTOTAL_MASK, tmp) + 1;
+		/* FIXME TGL+ DSI transcoders have this! */
+		if (!transcoder_is_dsi(cpu_transcoder)) {
+			tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder));
+			adjusted_mode->crtc_vblank_start = REG_FIELD_GET(VBLANK_START_MASK, tmp) + 1;
+			adjusted_mode->crtc_vblank_end = REG_FIELD_GET(VBLANK_END_MASK, tmp) + 1;
+		}
+		tmp = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder));
+		adjusted_mode->crtc_vsync_start = REG_FIELD_GET(VSYNC_START_MASK, tmp) + 1;
+		adjusted_mode->crtc_vsync_end = REG_FIELD_GET(VSYNC_END_MASK, tmp) + 1;
 	}
-	tmp = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder));
-	adjusted_mode->crtc_vsync_start = REG_FIELD_GET(VSYNC_START_MASK, tmp) + 1;
-	adjusted_mode->crtc_vsync_end = REG_FIELD_GET(VSYNC_END_MASK, tmp) + 1;
 
 	if (intel_pipe_is_interlaced(pipe_config)) {
 		adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE;
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 894ee97b3e1b..bc2a6052c4ff 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -289,6 +289,7 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
 void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 trans_vrr_ctl, trans_vrr_vsync;
 
@@ -321,5 +322,6 @@ 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);
 		}
+		adjusted_mode->crtc_vtotal = crtc_state->vrr.vmax;
 	}
 }
-- 
2.40.1



More information about the Intel-gfx-trybot mailing list