On 7/3/2026 8:56 AM, Suraj Kandpal wrote:
On Nova Lake A/B steppings the GOP breaks DP-Alt / native DP output
when TRANS_VTOTAL.Vtotal is programmed with a non-zero value, and the
initial hardware readout of that field on such systems ends up in
adjusted_mode.crtc_vtotal = 1 -- tripping the DSB scanline WARN in
assert_dsl_ok() during intel_initial_commit.

Keep TRANS_VTOTAL.Vtotal at 0 on Nova Lake pre-C0 (A0..B3) in both
transcoder timing paths, and restore adjusted_mode.crtc_vtotal from
TRANS_VRR_VMIN in intel_vrr_get_config() so downstream state stays
consistent.


This matches the GOP fix.

I'm not sure whether this is required for all A0-B0 steppings or only A0.

However, since this has been observed to fix the issue on both A0 and B0, I'm fine with the change.

Reviewed-by: Ankit Nautiyal <[email protected]>



Fixes: f26a8df8dff9 ("drm/i915/display: Program TRANS_VTOTAL from mode vtotal")
Signed-off-by: Suraj Kandpal <[email protected]>
---
  drivers/gpu/drm/i915/display/intel_display.c | 9 +++++++++
  drivers/gpu/drm/i915/display/intel_vrr.c     | 6 ++++++
  2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 90c05ad08f86..214454f419e9 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -45,6 +45,7 @@
  #include <drm/drm_probe_helper.h>
  #include <drm/drm_rect.h>
  #include <drm/drm_vblank.h>
+#include <drm/intel/step.h>
#include "g4x_dp.h"
  #include "g4x_hdmi.h"
@@ -2737,6 +2738,10 @@ void intel_set_transcoder_timings(const struct 
intel_crtc_state *crtc_state,
                       HSYNC_START(adjusted_mode->crtc_hsync_start - 1) |
                       HSYNC_END(adjusted_mode->crtc_hsync_end - 1));
+ if (display->platform.novalake &&
+           IS_DISPLAY_STEP(display, STEP_A0, STEP_C0))
+               crtc_vtotal = 1;
+
        intel_de_write(display, TRANS_VTOTAL(display, transcoder),
                       VACTIVE(crtc_vdisplay - 1) |
                       VTOTAL(crtc_vtotal - 1));
@@ -2830,6 +2835,10 @@ void intel_set_transcoder_timings_lrr(const struct 
intel_crtc_state *crtc_state,
         * The double buffer latch point for TRANS_VTOTAL
         * is the transcoder's undelayed vblank.
         */
+       if (display->platform.novalake &&
+           IS_DISPLAY_STEP(display, STEP_A0, STEP_C0))
+               crtc_vtotal = 1;
+
        intel_de_write(display, TRANS_VTOTAL(display, transcoder),
                       VACTIVE(crtc_vdisplay - 1) |
                       VTOTAL(crtc_vtotal - 1));
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index bffbdee76ee1..51e4f3309b8b 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -5,6 +5,7 @@
   */
#include <drm/drm_print.h>
+#include <drm/intel/step.h>
#include "intel_alpm.h"
  #include "intel_cmtg.h"
@@ -1106,6 +1107,11 @@ void intel_vrr_get_config(struct intel_crtc_state 
*crtc_state)
                        crtc_state->vrr.vmin += 
intel_vrr_vmin_flipline_offset(display);
                }
+ if (display->platform.novalake &&
+                   IS_DISPLAY_STEP(display, STEP_A0, STEP_C0))
+                       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,

Reply via email to