The last part of the vblank evasion is about updating bookkeeping,
not programming hardware registers.

The interrupts cannot stay disabled here on PREEMPT_RT since the
spinlocks get converted to mutexes.

There's still a small race in VRR that needs to be addressed, and
in the other worst case there is a delay of a vblank completion if
the vblank is fired and we schedule on the next vblank, this needs
to be addressed separately.

Signed-off-by: Maarten Lankhorst <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_crtc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c 
b/drivers/gpu/drm/i915/display/intel_crtc.c
index 778ebc5095c38..93e58c12ac994 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -703,6 +703,14 @@ void intel_pipe_update_end(struct intel_atomic_state 
*state,
            intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI))
                icl_dsi_frame_update(new_crtc_state);
 
+#if IS_ENABLED(CONFIG_PREEMPT_RT)
+       /*
+        * Timing sensitive register writing completed, non-deterministic
+        * locking from here on out.
+        */
+       local_irq_enable();
+#endif
+
        /* We're still in the vblank-evade critical section, this can't race.
         * Would be slightly nice to just grab the vblank count and arm the
         * event outside of the critical section - the spinlock might spin for a
@@ -750,7 +758,9 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
        if (!state->base.legacy_cursor_update)
                intel_vrr_send_push(NULL, new_crtc_state);
 
+#if !IS_ENABLED(CONFIG_PREEMPT_RT)
        local_irq_enable();
+#endif
 
        if (intel_parent_vgpu_active(display))
                goto out;
-- 
2.51.0

Reply via email to