Until LNL, intel_dsb_wait_vblanks() waits for the undelayed vblank start. However, from PTL onwards, it waits for the start of the safe window, defined by the number of lines programmed in TRANS_SET_CONTEXT_LATENCY. This change was introduced to move the SCL window out of the vblank region, supporting modes with higher refresh rates and smaller vblanks.
As a result, on PTL+ platforms, the DSB wait for vblank completes exactly SCL lines earlier than the undelayed vblank start. Since we use intel_dsb_wait_vblanks() to time the send push operation, this causes issues when SCL lines are non-zero. Instead of relying on the helper, instruct the DSB to wait from (undelayed vblank start - SCL) to (delayed vblank start - SCL) before sending the push. This approach works for both pre-PTL and PTL+ platforms. Signed-off-by: Ankit Nautiyal <ankit.k.nauti...@intel.com> --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_dsb.c | 16 ++++++++++++++++ drivers/gpu/drm/i915/display/intel_dsb.h | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bfeec3706f35..8d78037d5a2a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7265,7 +7265,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, new_crtc_state->dsb_color); if (new_crtc_state->use_dsb && !intel_color_uses_chained_dsb(new_crtc_state)) { - intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1); + intel_dsb_wait_for_scl_start(state, new_crtc_state->dsb_commit); intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state); intel_dsb_wait_for_scl_lines(state, new_crtc_state->dsb_commit); diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 400dcc87a992..e94a05cc8c82 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -826,6 +826,22 @@ void intel_dsb_wait_for_scl_lines(struct intel_atomic_state *state, intel_dsb_wait_usec(dsb, usecs); } +void intel_dsb_wait_for_scl_start(struct intel_atomic_state *state, + struct intel_dsb *dsb) +{ + struct intel_crtc *crtc = dsb->crtc; + const struct intel_crtc_state *crtc_state = + intel_pre_commit_crtc_state(state, crtc); + int undelayed_vblank_start = crtc_state->hw.adjusted_mode.crtc_vdisplay; + int delayed_vblank_start = crtc_state->hw.adjusted_mode.crtc_vblank_start; + int start, end; + + start = undelayed_vblank_start - crtc_state->set_context_latency; + end = delayed_vblank_start - crtc_state->set_context_latency; + + intel_dsb_wait_scanline_out(state, dsb, start, end); +} + /** * intel_dsb_commit() - Trigger workload execution of DSB. * @dsb: DSB context diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index 1cb5ba1a0534..5985d0024dae 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -73,5 +73,7 @@ void intel_dsb_wait(struct intel_dsb *dsb); void intel_dsb_irq_handler(struct intel_display *display, enum pipe pipe, enum intel_dsb_id dsb_id); +void intel_dsb_wait_for_scl_start(struct intel_atomic_state *state, + struct intel_dsb *dsb); #endif -- 2.45.2