[PATCH 2/3] v2: wait for cursor unpins before turning off the vblank irq

Ville Syrjala ville.syrjala at linux.intel.com
Fri Sep 1 09:18:58 UTC 2023


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

---
 drivers/gpu/drm/i915/display/intel_cursor.c        | 13 ++++++++++++-
 drivers/gpu/drm/i915/display/intel_cursor.h        |  2 ++
 drivers/gpu/drm/i915/display/intel_display.c       |  3 +++
 drivers/gpu/drm/i915/display/intel_display_types.h |  1 +
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 2bd1a79c6955..625540fd1dab 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -608,9 +608,19 @@ static void intel_cursor_unpin_work(struct kthread_work *base)
 	struct drm_vblank_work *work = to_drm_vblank_work(base);
 	struct intel_plane_state *plane_state =
 		container_of(work, typeof(*plane_state), unpin_work);
+	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 
 	intel_plane_unpin_fb(plane_state);
-	intel_plane_destroy_state(plane_state->uapi.plane, &plane_state->uapi);
+	intel_plane_destroy_state(&plane->base, &plane_state->uapi);
+
+	if (atomic_dec_and_test(&plane->cursor.pending_unpins))
+		wake_up_var(&plane->cursor.pending_unpins);
+}
+
+void intel_cursor_wait_unpin_works(struct intel_plane *plane)
+{
+	wait_var_event(&plane->cursor.pending_unpins,
+		       !atomic_read(&plane->cursor.pending_unpins));
 }
 
 static int
@@ -744,6 +754,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
 		drm_vblank_work_init(&old_plane_state->unpin_work, &crtc->base,
 				     intel_cursor_unpin_work);
 
+		atomic_inc(&plane->cursor.pending_unpins);
 		drm_vblank_work_schedule(&old_plane_state->unpin_work,
 					 drm_crtc_accurate_vblank_count(&crtc->base) + 1,
 					 false);
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.h b/drivers/gpu/drm/i915/display/intel_cursor.h
index ce333bf4c2d5..e778aff77129 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.h
+++ b/drivers/gpu/drm/i915/display/intel_cursor.h
@@ -14,4 +14,6 @@ struct intel_plane *
 intel_cursor_plane_create(struct drm_i915_private *dev_priv,
 			  enum pipe pipe);
 
+void intel_cursor_wait_unpin_works(struct intel_plane *plane);
+
 #endif
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index f6397462e4c2..90c1ed61ba0e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -63,6 +63,7 @@
 #include "intel_crt.h"
 #include "intel_crtc.h"
 #include "intel_crtc_state_dump.h"
+#include "intel_cursor.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
 #include "intel_display_driver.h"
@@ -6618,6 +6619,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 
 		intel_pre_plane_update(state, crtc);
 		intel_crtc_disable_planes(state, crtc);
+
+		intel_cursor_wait_unpin_works(to_intel_plane(crtc->base.cursor));
 	}
 
 	/* Only disable port sync and MST slaves */
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 07394a33e747..1c3b889b8223 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1518,6 +1518,7 @@ struct intel_plane {
 
 	struct {
 		u32 base, cntl, size;
+		atomic_t pending_unpins;
 	} cursor;
 
 	struct intel_fbc *fbc;
-- 
2.41.0



More information about the Intel-gfx-trybot mailing list