Currently the guardband is same as vblank length and undelayed vblank and the vblank and the flipdone with dsb interrupt are already aligned for the fixed refresh rate case.
As we move towards a shorter optimized guardband we need to wait for the delayed vblank before the DSB interrupt to align the flipdone event with the delayed vblank. Introduce a helper intel_dsb_wait_for_delayed_vblank() to wait for the scanline range [delayed_vblank_start, vmin/vmax vtotal], depending on whether fixed refresh rate mode or variable refresh rate mode is active, before triggering the DSB interrupt. Signed-off-by: Ankit Nautiyal <ankit.k.nauti...@intel.com> --- drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/i915/display/intel_dsb.c | 16 ++++++++++++++++ drivers/gpu/drm/i915/display/intel_dsb.h | 3 +++ 3 files changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 787bb6ebdc75..fb072275b1c7 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7447,6 +7447,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state); intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit); + intel_dsb_wait_for_delayed_vblank(state, new_crtc_state->dsb_commit); intel_vrr_check_push_sent(new_crtc_state->dsb_commit, new_crtc_state); intel_dsb_interrupt(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 dee44d45b668..6b3a4d25a6c6 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -1026,3 +1026,19 @@ void intel_dsb_irq_handler(struct intel_display *display, drm_err(display->drm, "[CRTC:%d:%s] DSB %d GOSUB programming error\n", crtc->base.base.id, crtc->base.name, dsb_id); } + +void intel_dsb_wait_for_delayed_vblank(struct intel_atomic_state *state, + struct intel_dsb *dsb) +{ + const struct intel_crtc_state *crtc_state; + struct intel_crtc *crtc = dsb->crtc; + int start, end; + + crtc_state = intel_pre_commit_crtc_state(state, crtc); + start = intel_vrr_vmin_vblank_start(crtc_state); + end = crtc_state->vrr.enable ? + intel_vrr_vmax_vtotal(crtc_state) : + intel_vrr_vmin_vtotal(crtc_state); + + intel_dsb_wait_scanline_in(state, dsb, start, end); +} diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index c8f4499916eb..6eb810aad18f 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -74,4 +74,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_delayed_vblank(struct intel_atomic_state *state, + struct intel_dsb *dsb); + #endif -- 2.45.2