[PATCH 1/2] drm/i915/flipq: Drain the flip queue before disabling pipe planes
Mika Kahola <[email protected]> Tue, 4 Aug 2026 06:30:56 +0000
| Newsgroups | org.freedesktop.lists.intel-xe,org.freedesktop.lists.intel-gfx |
|---|---|
| Message-ID | <[email protected]> |
A plane update queued into a pipe's flip queue is executed by the pipe DMC asynchronously, potentially several vblanks later. If a later, unrelated commit disables the pipe before that queued update has run, intel_crtc_disable_planes() can end up racing a write that is still only queued, not yet applied to hardware: cursor D assertion failure (expected off, current on) WARNING: .../intel_display.c:406 at assert_plane+0x11e/0x140 [xe] Add intel_flipq_drain() and call it before intel_crtc_disable_planes() for pipes being disabled, so any queued-but-not-yet-executed entry is neutralized before we synchronously write the real plane-disabled state and before assert_planes_disabled() checks it. Assisted-by: Copilot:claude-sonnet-5 Signed-off-by: Mika Kahola <[email protected]> --- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ drivers/gpu/drm/i915/display/intel_flipq.c | 13 +++++++++++++ drivers/gpu/drm/i915/display/intel_flipq.h | 1 + 3 files changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9dfd095f325f..3656b9be5b5c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7003,6 +7003,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) if ((disable_pipes & BIT(crtc->pipe)) == 0) continue; + intel_flipq_drain(crtc); + intel_crtc_disable_planes(state, crtc); drm_vblank_work_flush_all(&crtc->base); diff --git a/drivers/gpu/drm/i915/display/intel_flipq.c b/drivers/gpu/drm/i915/display/intel_flipq.c index bf278f60bba7..cd2cd8eda447 100644 --- a/drivers/gpu/drm/i915/display/intel_flipq.c +++ b/drivers/gpu/drm/i915/display/intel_flipq.c @@ -326,6 +326,19 @@ void intel_flipq_disable(const struct intel_crtc_state *crtc_state) intel_de_write(display, PIPEDMC_SCANLINECMPUPPER(crtc->pipe), 0); } +/* Empty a pipe's flip queue, discarding any entries still queued. */ +void intel_flipq_drain(struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc); + + if (!intel_flipq_supported(display)) + return; + + intel_flipq_preempt(crtc, true); + + intel_flipq_reset(display, crtc->pipe); +} + static bool assert_flipq_has_room(struct intel_crtc *crtc, enum intel_flipq_id flipq_id) { diff --git a/drivers/gpu/drm/i915/display/intel_flipq.h b/drivers/gpu/drm/i915/display/intel_flipq.h index 012e3e9a6bcb..c39ee0aa2ce7 100644 --- a/drivers/gpu/drm/i915/display/intel_flipq.h +++ b/drivers/gpu/drm/i915/display/intel_flipq.h @@ -22,6 +22,7 @@ void intel_flipq_reset(struct intel_display *display, enum pipe pipe); void intel_flipq_enable(const struct intel_crtc_state *crtc_state); void intel_flipq_disable(const struct intel_crtc_state *old_crtc_state); +void intel_flipq_drain(struct intel_crtc *crtc); void intel_flipq_add(struct intel_crtc *crtc, enum intel_flipq_id flip_queue_id, -- 2.43.0