i9xx_cursor_update_arm() caches the last CURCNTR/CURPOS/CURBASE values
it wrote in plane->cursor.{base,cntl,size} to skip redundant writes.
That cache is updated as soon as a plane's DSB program is built, even
though the program's actual execution may be deferred (use_dsb) or
queued into a pipe DMC flip queue (use_flipq) for later, asynchronous
execution.

intel_flipq_reset() discards a flip queue's ring buffer contents
without waiting for or checking whether whatever was queued actually
executed. If a cursor update was still queued when this happens, the
real registers never get written, but the cache already reflects the
value as if they had, so a later update computing the same target value
will wrongly skip rewriting the hardware.

Invalidate the cursor's register cache (mirroring the ~0 sentinel used
at plane creation) whenever intel_flipq_reset() discards a queue, so
the next update is guaranteed to rewrite the real registers rather than
trust a value that may never have reached hardware.

Assisted-by: Copilot:claude-sonnet-5
Signed-off-by: Mika Kahola <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_flipq.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_flipq.c 
b/drivers/gpu/drm/i915/display/intel_flipq.c
index cd2cd8eda447..8d5166ad5f9d 100644
--- a/drivers/gpu/drm/i915/display/intel_flipq.c
+++ b/drivers/gpu/drm/i915/display/intel_flipq.c
@@ -272,6 +272,21 @@ void intel_flipq_reset(struct intel_display *display, enum 
pipe pipe)
        }
 
        intel_de_write(display, PIPEDMC_FPQ_ATOMIC_TP(pipe), 0);
+
+       /*
+        * Entries dropped here may never have reached the hardware, even
+        * though the cursor's software mirror of its last-written registers
+        * was already updated when the DSB program queuing them was built.
+        * Invalidate it so a later update can't skip rewriting the cursor
+        * registers believing HW already matches.
+        */
+       if (crtc->base.cursor) {
+               struct intel_plane *plane = to_intel_plane(crtc->base.cursor);
+
+               plane->cursor.base = ~0;
+               plane->cursor.cntl = ~0;
+               plane->cursor.size = ~0;
+       }
 }
 
 static enum pipedmc_event_id flipq_event_id(struct intel_display *display)
-- 
2.43.0

Reply via email to