Blob Blame History Raw
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Mon, 30 Jul 2018 11:53:06 +0100
Subject: drm/armada: switch primary plane to atomic modeset
Git-commit: 13c94d5349c9c0756131e7bf2e703ab36ea55c73
Patch-mainline: v4.19-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Switch the primary plane away from the transitional helpers, and
use the atomic helpers instead to implement the legacy set_plane
ioctl call for this plane.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/armada/armada_crtc.c  |  116 ----------------------------------
 drivers/gpu/drm/armada/armada_plane.c |    4 -
 2 files changed, 3 insertions(+), 117 deletions(-)

--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -191,34 +191,6 @@ void armada_drm_plane_work_cancel(struct
 		armada_drm_plane_work_call(dcrtc, work, work->cancel);
 }
 
-static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
-	struct armada_plane_work *work)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	armada_drm_crtc_update_regs(dcrtc, work->regs);
-	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
-static struct armada_plane_work *
-armada_drm_crtc_alloc_plane_work(struct drm_plane *plane)
-{
-	struct armada_plane_work *work;
-	int i = 0;
-
-	work = kzalloc(sizeof(*work), GFP_KERNEL);
-	if (!work)
-		return NULL;
-
-	work->plane = plane;
-	work->fn = armada_drm_crtc_complete_frame_work;
-	work->need_kfree = true;
-	armada_reg_queue_end(work->regs, i);
-
-	return work;
-}
-
 static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
@@ -318,9 +290,6 @@ static void armada_drm_crtc_irq(struct a
 
 	spin_unlock(&dcrtc->irq_lock);
 
-	if (stat & GRA_FRAME_IRQ)
-		armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
-
 	if (stat & VSYNC_IRQ) {
 		event = xchg(&dcrtc->event, NULL);
 		if (event) {
@@ -459,15 +428,9 @@ static void armada_drm_crtc_atomic_begin
 					 struct drm_crtc_state *old_crtc_state)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct armada_plane *dplane;
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
 
-	/* Wait 100ms for any plane works to complete */
-	dplane = drm_to_armada_plane(crtc->primary);
-	if (WARN_ON(armada_drm_plane_work_wait(dplane, HZ / 10) == 0))
-		armada_drm_plane_work_cancel(dcrtc, dplane);
-
 	dcrtc->regs_idx = 0;
 	dcrtc->regs = dcrtc->atomic_regs;
 }
@@ -511,8 +474,6 @@ static void armada_drm_crtc_atomic_disab
 	if (plane)
 		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane),
 						    HZ));
-	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
-				   MAX_SCHEDULE_TIMEOUT);
 
 	drm_crtc_vblank_off(crtc);
 	armada_drm_crtc_update(dcrtc, false);
@@ -802,81 +763,6 @@ static void armada_drm_crtc_destroy(stru
 	kfree(dcrtc);
 }
 
-/*
- * The mode_config lock is held here, to prevent races between this
- * and a mode_set.
- */
-static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
-	struct drm_framebuffer *fb, struct drm_pending_vblank_event *event,
-	uint32_t page_flip_flags, struct drm_modeset_acquire_ctx *ctx)
-{
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct drm_plane *plane = crtc->primary;
-	const struct drm_plane_helper_funcs *plane_funcs;
-	struct drm_plane_state *state;
-	struct armada_plane_work *work;
-	int ret;
-
-	/* Construct new state for the primary plane */
-	state = drm_atomic_helper_plane_duplicate_state(plane);
-	if (!state)
-		return -ENOMEM;
-
-	drm_atomic_set_fb_for_plane(state, fb);
-
-	work = armada_drm_crtc_alloc_plane_work(plane);
-	if (!work) {
-		ret = -ENOMEM;
-		goto put_state;
-	}
-
-	/* Make sure we can get vblank interrupts */
-	ret = drm_crtc_vblank_get(crtc);
-	if (ret)
-		goto put_work;
-
-	/*
-	 * If we have another work pending, we can't process this flip.
-	 * The modeset locks protect us from another user queuing a work
-	 * while we're setting up.
-	 */
-	if (drm_to_armada_plane(plane)->work) {
-		ret = -EBUSY;
-		goto put_vblank;
-	}
-
-	work->event = event;
-	work->old_fb = plane->state->fb;
-
-	/*
-	 * Hold a ref on the new fb while it's being displayed by the
-	 * hardware. The old fb refcount will be released in the worker.
-	 */
-	drm_framebuffer_get(state->fb);
-
-	/* Point of no return */
-	swap(plane->state, state);
-
-	dcrtc->regs_idx = 0;
-	dcrtc->regs = work->regs;
-
-	plane_funcs = plane->helper_private;
-	plane_funcs->atomic_update(plane, state);
-	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
-
-	/* Queue the work - this should never fail */
-	WARN_ON(armada_drm_plane_work_queue(dcrtc, work));
-	work = NULL;
-
-put_vblank:
-	drm_crtc_vblank_put(crtc);
-put_work:
-	kfree(work);
-put_state:
-	drm_atomic_helper_plane_destroy_state(plane, state);
-	return ret;
-}
-
 /* These are called under the vbl_lock. */
 static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
@@ -905,7 +791,7 @@ static const struct drm_crtc_funcs armad
 	.cursor_move	= armada_drm_crtc_cursor_move,
 	.destroy	= armada_drm_crtc_destroy,
 	.set_config	= drm_atomic_helper_set_config,
-	.page_flip	= armada_drm_crtc_page_flip,
+	.page_flip	= drm_atomic_helper_page_flip,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 	.enable_vblank	= armada_drm_crtc_enable_vblank,
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -261,8 +261,8 @@ static const struct drm_plane_helper_fun
 };
 
 static const struct drm_plane_funcs armada_primary_plane_funcs = {
-	.update_plane	= drm_plane_helper_update,
-	.disable_plane	= drm_plane_helper_disable,
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
 	.destroy	= drm_primary_helper_destroy,
 	.reset		= drm_atomic_helper_plane_reset,
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,