[PATCH 10/25] drm/armada: move fb retirement into armada_plane_work

Russell King rmk+kernel at armlinux.org.uk
Fri Dec 8 12:29:49 UTC 2017


Both the primary and overlay planes retire framebuffers in a similar
manner; this can be consolidated by moving the retirement up to the
armada_plane_work layer.

Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c    | 12 +++++++-----
 drivers/gpu/drm/armada/armada_crtc.h    |  1 +
 drivers/gpu/drm/armada/armada_overlay.c | 30 +++++-------------------------
 3 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index be3fd82ef516..d1f4171966cc 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -24,7 +24,6 @@ struct armada_frame_work {
 	struct armada_plane_work work;
 	struct drm_pending_vblank_event *event;
 	struct armada_regs regs[4];
-	struct drm_framebuffer *old_fb;
 };
 
 enum csc_mode {
@@ -221,11 +220,16 @@ static void armada_drm_plane_work_call(struct armada_crtc *dcrtc,
 	void (*fn)(struct armada_crtc *, struct armada_plane_work *))
 {
 	struct armada_plane *dplane = drm_to_armada_plane(work->plane);
+	struct drm_framebuffer *fb = work->old_fb;
 
 	if (fn)
 		fn(dcrtc, work);
 	drm_crtc_vblank_put(&dcrtc->crtc);
 
+	/* Finally, queue the process-half of the cleanup. */
+	if (fb)
+		armada_drm_queue_unref_work(dcrtc->crtc.dev, fb);
+
 	wake_up(&dplane->frame_wait);
 }
 
@@ -287,8 +291,6 @@ static void armada_drm_crtc_finish_frame_work(struct armada_crtc *dcrtc,
 		spin_unlock_irqrestore(&dev->event_lock, flags);
 	}
 
-	/* Finally, queue the process-half of the cleanup. */
-	__armada_drm_queue_unref_work(dcrtc->crtc.dev, fwork->old_fb);
 	kfree(fwork);
 }
 
@@ -339,7 +341,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
 
 	work = armada_drm_crtc_alloc_frame_work(dcrtc->crtc.primary);
 	if (work) {
-		work->old_fb = fb;
+		work->work.old_fb = fb;
 
 		if (armada_drm_plane_work_queue(dcrtc, &work->work) == 0)
 			return;
@@ -1031,7 +1033,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 		return -ENOMEM;
 
 	work->event = event;
-	work->old_fb = dcrtc->crtc.primary->fb;
+	work->work.old_fb = dcrtc->crtc.primary->fb;
 
 	i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs,
 				    dcrtc->interlaced);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 521ae5b6ad86..b40db72c61d8 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -39,6 +39,7 @@ struct armada_plane_work {
 	void (*fn)(struct armada_crtc *, struct armada_plane_work *);
 	void (*cancel)(struct armada_crtc *, struct armada_plane_work *);
 	struct drm_plane *plane;
+	struct drm_framebuffer *old_fb;
 };
 
 struct armada_plane_state {
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 04746ade74e6..01087c952916 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -32,7 +32,6 @@ struct armada_ovl_plane_properties {
 
 struct armada_ovl_plane {
 	struct armada_plane base;
-	struct drm_framebuffer *old_fb;
 	struct {
 		struct armada_plane_work work;
 		struct armada_regs regs[13];
@@ -67,17 +66,6 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
 	spin_unlock_irq(&dcrtc->irq_lock);
 }
 
-static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
-	struct drm_framebuffer *fb)
-{
-	struct drm_framebuffer *old_fb;
-
-	old_fb = xchg(&dplane->old_fb, fb);
-
-	if (old_fb)
-		armada_drm_queue_unref_work(dplane->base.base.dev, old_fb);
-}
-
 /* === Plane support === */
 static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 	struct armada_plane_work *work)
@@ -91,8 +79,6 @@ static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 	spin_lock_irqsave(&dcrtc->irq_lock, flags);
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-
-	armada_ovl_retire_fb(dplane, NULL);
 }
 
 static int
@@ -196,8 +182,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 		 */
 		drm_framebuffer_get(fb);
 
-		if (plane->fb)
-			armada_ovl_retire_fb(dplane, plane->fb);
+		dplane->vbl.work.old_fb = plane->fb;
 
 		dplane->base.state.src_y = src_y = src.y1 >> 16;
 		dplane->base.state.src_x = src_x = src.x1 >> 16;
@@ -223,6 +208,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 		val = fb->pitches[1] << 16 | fb->pitches[2];
 		armada_reg_queue_set(dplane->vbl.regs, idx, val,
 				     LCD_SPU_DMA_PITCH_UV);
+	} else {
+		dplane->vbl.work.old_fb = NULL;
 	}
 
 	val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16;
@@ -266,17 +253,10 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 static int armada_ovl_plane_disable(struct drm_plane *plane,
 				    struct drm_modeset_acquire_ctx *ctx)
 {
-	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
-	struct drm_framebuffer *fb;
-
 	armada_drm_plane_disable(plane, ctx);
 
-	if (dplane->base.base.crtc)
-		drm_to_armada_crtc(dplane->base.base.crtc)->plane = NULL;
-
-	fb = xchg(&dplane->old_fb, NULL);
-	if (fb)
-		drm_framebuffer_put(fb);
+	if (plane->crtc)
+		drm_to_armada_crtc(plane->crtc)->plane = NULL;
 
 	return 0;
 }
-- 
2.7.4



More information about the dri-devel mailing list