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,