Skip to content

Commit 63b41d2

Browse files
committed
drm/i915/dsb: Introduce intel_dsb_vblank_evade()
Add a helper for performing vblank evasion on the DSB. DSB based plane updates will need this to guarantee all the double buffered arming registers will get programmed atomically within the same frame. With VRR we more or less have two vblanks to worry about: - vmax vblank start in case no push was sent - vmin vblank start in case a push was already sent during the vertical active. Only a concern for mailbox updates, which I suppose could happen if the legacy cursor updates take the non-fastpath without setting state->legacy_cursor_update to false. Since we don't know which case is relevant we'll just evade both. We must also make sure to evade both the delayed vblank (for pipe/plane registers) and the undelayed vblank (for transcoder registers and chained DSBs w/ DSB_WAIT_FOR_VBLANK). TODO: come up with a sensible usec number for the evasion... Reviewed-by: Animesh Manna <animesh.manna@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-6-ville.syrjala@linux.intel.com
1 parent 9e99537 commit 63b41d2

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

drivers/gpu/drm/i915/display/intel_dsb.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ pre_commit_crtc_state(struct intel_atomic_state *state,
128128
return old_crtc_state;
129129
}
130130

131+
static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state)
132+
{
133+
return intel_mode_vblank_start(&crtc_state->hw.adjusted_mode) -
134+
intel_mode_vdisplay(&crtc_state->hw.adjusted_mode);
135+
}
136+
131137
static int dsb_vtotal(struct intel_atomic_state *state,
132138
struct intel_crtc *crtc)
133139
{
@@ -527,6 +533,31 @@ static u32 dsb_error_int_en(struct intel_display *display)
527533
return errors;
528534
}
529535

536+
void intel_dsb_vblank_evade(struct intel_atomic_state *state,
537+
struct intel_dsb *dsb)
538+
{
539+
struct intel_crtc *crtc = dsb->crtc;
540+
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
541+
/* FIXME calibrate sensibly */
542+
int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20);
543+
int vblank_delay = dsb_vblank_delay(crtc_state);
544+
int start, end;
545+
546+
if (pre_commit_is_vrr_active(state, crtc)) {
547+
end = intel_vrr_vmin_vblank_start(crtc_state);
548+
start = end - vblank_delay - latency;
549+
intel_dsb_wait_scanline_out(state, dsb, start, end);
550+
551+
end = intel_vrr_vmax_vblank_start(crtc_state);
552+
start = end - vblank_delay - latency;
553+
intel_dsb_wait_scanline_out(state, dsb, start, end);
554+
} else {
555+
end = intel_mode_vblank_start(&crtc_state->hw.adjusted_mode);
556+
start = end - vblank_delay - latency;
557+
intel_dsb_wait_scanline_out(state, dsb, start, end);
558+
}
559+
}
560+
530561
static void _intel_dsb_chain(struct intel_atomic_state *state,
531562
struct intel_dsb *dsb,
532563
struct intel_dsb *chained_dsb,

drivers/gpu/drm/i915/display/intel_dsb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ void intel_dsb_wait_scanline_in(struct intel_atomic_state *state,
4646
void intel_dsb_wait_scanline_out(struct intel_atomic_state *state,
4747
struct intel_dsb *dsb,
4848
int lower, int upper);
49+
void intel_dsb_vblank_evade(struct intel_atomic_state *state,
50+
struct intel_dsb *dsb);
4951
void intel_dsb_chain(struct intel_atomic_state *state,
5052
struct intel_dsb *dsb,
5153
struct intel_dsb *chained_dsb,

0 commit comments

Comments
 (0)