]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/vrr: Move the TGL SCL mangling of vmin/vmax/flipline deeper
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 17 Sep 2025 20:34:46 +0000 (23:34 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 18 Sep 2025 20:43:07 +0000 (23:43 +0300)
Currently our crtc_state->vrr.{vmin.vmax,flipline} are mangled on
TGL to account for the SCL delay (the hardware requires this mangling
or the actual vtotals will become incorrect). Unfortunately this
means that one can't simply use these values directly in many places,
and instead we always have to go through functions that undo the
damage first. This is all rather fragile.

Simplify our lives a bit by hiding this mangling deeper inside
the low level VRR code, leaving the number stored in the crtc
state actually something that humans can use.

This does introduce a dependdency as intel_vrr_get_config()
will now need to know the SCL value, which is read out in
intel_get_transcoder_timings(). I suppose we could simply
duplicate the SCL readout in both places should this become
a real hinderance. For now just leave a note around the
intel_get_transcoder_timings() call to remind us.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250917203446.14374-6-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_vrr.c

index f4124c79bc83fad2767ce5b91a2c9d851c731ab8..18b9baa962415681a2fc74d9ea170efee040e54c 100644 (file)
@@ -3901,6 +3901,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
                pipe_config->framestart_delay = 1;
        }
 
+       /*
+        * intel_vrr_get_config() depends on TRANS_SET_CONTEXT_LATENCY
+        * readout done by intel_get_transcoder_timings().
+        */
        if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
            DISPLAY_VER(display) >= 11)
                intel_get_transcoder_timings(crtc, pipe_config);
index 71fb64c9216577f87b51b0a8ad7ad3e30050ef96..71a985d00604fdc04779f02fe38ae1e1650d20bd 100644 (file)
@@ -156,25 +156,13 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat
 
 int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state)
 {
-       struct intel_display *display = to_intel_display(crtc_state);
-
        /* Min vblank actually determined by flipline */
-       if (DISPLAY_VER(display) >= 13)
-               return intel_vrr_vmin_flipline(crtc_state);
-       else
-               return intel_vrr_vmin_flipline(crtc_state) +
-                       intel_vrr_real_vblank_delay(crtc_state);
+       return intel_vrr_vmin_flipline(crtc_state);
 }
 
 int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state)
 {
-       struct intel_display *display = to_intel_display(crtc_state);
-
-       if (DISPLAY_VER(display) >= 13)
-               return crtc_state->vrr.vmax;
-       else
-               return crtc_state->vrr.vmax +
-                       intel_vrr_real_vblank_delay(crtc_state);
+       return crtc_state->vrr.vmax;
 }
 
 int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state)
@@ -258,6 +246,21 @@ void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state)
        crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
 }
 
+static int intel_vrr_hw_value(const struct intel_crtc_state *crtc_state,
+                             int value)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+
+       /*
+        * On TGL vmin/vmax/flipline also need to be
+        * adjusted by the SCL to maintain correct vtotals.
+        */
+       if (DISPLAY_VER(display) >= 13)
+               return value;
+       else
+               return value - intel_vrr_real_vblank_delay(crtc_state);
+}
+
 /*
  * For fixed refresh rate mode Vmin, Vmax and Flipline all are set to
  * Vtotal value.
@@ -265,14 +268,7 @@ void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state)
 static
 int intel_vrr_fixed_rr_hw_vtotal(const struct intel_crtc_state *crtc_state)
 {
-       struct intel_display *display = to_intel_display(crtc_state);
-       int crtc_vtotal = crtc_state->hw.adjusted_mode.crtc_vtotal;
-
-       if (DISPLAY_VER(display) >= 13)
-               return crtc_vtotal;
-       else
-               return crtc_vtotal -
-                       intel_vrr_real_vblank_delay(crtc_state);
+       return intel_vrr_hw_value(crtc_state, crtc_state->hw.adjusted_mode.crtc_vtotal);
 }
 
 static
@@ -441,14 +437,6 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state)
                crtc_state->vrr.pipeline_full =
                        intel_vrr_guardband_to_pipeline_full(crtc_state,
                                                             crtc_state->vrr.guardband);
-
-               /*
-                * vmin/vmax/flipline also need to be adjusted by
-                * the vblank delay to maintain correct vtotals.
-                */
-               crtc_state->vrr.vmin -= intel_vrr_real_vblank_delay(crtc_state);
-               crtc_state->vrr.vmax -= intel_vrr_real_vblank_delay(crtc_state);
-               crtc_state->vrr.flipline -= intel_vrr_real_vblank_delay(crtc_state);
        }
 }
 
@@ -607,6 +595,21 @@ void intel_vrr_set_db_point_and_transmission_line(const struct intel_crtc_state
                               EMP_AS_SDP_DB_TL(crtc_state->vrr.vsync_start));
 }
 
+static int intel_vrr_hw_vmin(const struct intel_crtc_state *crtc_state)
+{
+       return intel_vrr_hw_value(crtc_state, crtc_state->vrr.vmin);
+}
+
+static int intel_vrr_hw_vmax(const struct intel_crtc_state *crtc_state)
+{
+       return intel_vrr_hw_value(crtc_state, crtc_state->vrr.vmax);
+}
+
+static int intel_vrr_hw_flipline(const struct intel_crtc_state *crtc_state)
+{
+       return intel_vrr_hw_value(crtc_state, crtc_state->vrr.flipline);
+}
+
 void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
 {
        struct intel_display *display = to_intel_display(crtc_state);
@@ -616,11 +619,11 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
                return;
 
        intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder),
-                      crtc_state->vrr.vmin - 1);
+                      intel_vrr_hw_vmin(crtc_state) - 1);
        intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder),
-                      crtc_state->vrr.vmax - 1);
+                      intel_vrr_hw_vmax(crtc_state) - 1);
        intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder),
-                      crtc_state->vrr.flipline - 1);
+                      intel_vrr_hw_flipline(crtc_state) - 1);
 
        intel_de_write(display, TRANS_PUSH(display, cpu_transcoder),
                       TRANS_PUSH_EN);
@@ -754,6 +757,13 @@ 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;
 
+               if (DISPLAY_VER(display) < 13) {
+                       /* undo what intel_vrr_hw_value() does when writing the values */
+                       crtc_state->vrr.flipline += intel_vrr_real_vblank_delay(crtc_state);
+                       crtc_state->vrr.vmax += intel_vrr_real_vblank_delay(crtc_state);
+                       crtc_state->vrr.vmin += intel_vrr_real_vblank_delay(crtc_state);
+               }
+
                /*
                 * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal
                 * bits are not filled. Since for these platforms TRAN_VMIN is always