Convert the overlay plane to use the generic armada plane worker
infrastructure which is shared with the primary plane.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c    | 48 +++++++++------------------------
 drivers/gpu/drm/armada/armada_crtc.h    | 20 ++------------
 drivers/gpu/drm/armada/armada_overlay.c | 27 +++++++++----------
 3 files changed, 26 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 0c1a1524f5d5..418dbfad4271 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -226,44 +226,15 @@ int armada_drm_plane_work_wait(struct armada_plane 
*plane, long timeout)
        return wait_event_timeout(plane->frame_wait, !plane->work, timeout);
 }

-void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
-       struct armada_vbl_event *evt)
+struct armada_plane_work *armada_drm_plane_work_cancel(
+       struct armada_crtc *dcrtc, struct armada_plane *plane)
 {
-       unsigned long flags;
-       bool not_on_list;
-
-       WARN_ON(drm_vblank_get(dcrtc->crtc.dev, dcrtc->num));
-
-       spin_lock_irqsave(&dcrtc->irq_lock, flags);
-       not_on_list = list_empty(&evt->node);
-       if (not_on_list)
-               list_add_tail(&evt->node, &dcrtc->vbl_list);
-       spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
+       struct armada_plane_work *work = xchg(&plane->work, NULL);

-       if (!not_on_list)
+       if (work)
                drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-}

-void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
-       struct armada_vbl_event *evt)
-{
-       spin_lock_irq(&dcrtc->irq_lock);
-       if (!list_empty(&evt->node)) {
-               list_del_init(&evt->node);
-               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-       }
-       spin_unlock_irq(&dcrtc->irq_lock);
-}
-
-static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
-{
-       struct armada_vbl_event *e, *n;
-
-       list_for_each_entry_safe(e, n, &dcrtc->vbl_list, node) {
-               list_del_init(&e->node);
-               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-               e->fn(dcrtc, e->data);
-       }
+       return work;
 }

 static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
@@ -429,6 +400,7 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc 
*crtc,
 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
        void __iomem *base = dcrtc->base;
+       struct drm_plane *ovl_plane;

        if (stat & DMA_FF_UNDERFLOW)
                DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
@@ -439,7 +411,12 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, 
u32 stat)
                drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);

        spin_lock(&dcrtc->irq_lock);
-       armada_drm_vbl_event_run(dcrtc);
+       ovl_plane = dcrtc->plane;
+       if (ovl_plane) {
+               struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
+               armada_drm_plane_work_run(dcrtc, plane);
+               wake_up(&plane->frame_wait);
+       }

        if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
                int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
@@ -1188,7 +1165,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, 
struct device *dev,
        dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
        spin_lock_init(&dcrtc->irq_lock);
        dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
-       INIT_LIST_HEAD(&dcrtc->vbl_list);

        /* Initialize some registers which we don't otherwise set */
        writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h 
b/drivers/gpu/drm/armada/armada_crtc.h
index aaad5ab78673..04fdd22d483b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -52,6 +52,8 @@ int armada_drm_plane_init(struct armada_plane *plane);
 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
        struct armada_plane *plane, struct armada_plane_work *work);
 int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
+struct armada_plane_work *armada_drm_plane_work_cancel(
+       struct armada_crtc *dcrtc, struct armada_plane *plane);

 struct armada_crtc {
        struct drm_crtc         crtc;
@@ -87,27 +89,9 @@ struct armada_crtc {

        spinlock_t              irq_lock;
        uint32_t                irq_ena;
-       struct list_head        vbl_list;
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)

-struct armada_vbl_event {
-       struct list_head        node;
-       void                    *data;
-       void                    (*fn)(struct armada_crtc *, void *);
-};
-
-void armada_drm_vbl_event_add(struct armada_crtc *,
-       struct armada_vbl_event *);
-void armada_drm_vbl_event_remove(struct armada_crtc *,
-       struct armada_vbl_event *);
-#define armada_drm_vbl_event_init(_e, _f, _d) do {     \
-       struct armada_vbl_event *__e = _e;              \
-       INIT_LIST_HEAD(&__e->node);                     \
-       __e->data = _d;                                 \
-       __e->fn = _f;                                   \
-} while (0)
-
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
b/drivers/gpu/drm/armada/armada_overlay.c
index 9a5bab765085..5c22b380f8f3 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -37,7 +37,7 @@ struct armada_ovl_plane {
        uint32_t dst_yx;
        uint32_t ctrl0;
        struct {
-               struct armada_vbl_event update;
+               struct armada_plane_work work;
                struct armada_regs regs[13];
        } vbl;
        struct armada_ovl_plane_properties prop;
@@ -82,14 +82,13 @@ static void armada_ovl_retire_fb(struct armada_ovl_plane 
*dplane,
 }

 /* === Plane support === */
-static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data)
+static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
+       struct armada_plane *plane, struct armada_plane_work *work)
 {
-       struct armada_ovl_plane *dplane = data;
+       struct armada_ovl_plane *dplane = container_of(plane, struct 
armada_ovl_plane, base);

        armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
        armada_ovl_retire_fb(dplane, NULL);
-
-       wake_up(&dplane->base.frame_wait);
 }

 static int
@@ -162,9 +161,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
                               dcrtc->base + LCD_SPU_SRAM_PARA1);
        }

-       wait_event_timeout(dplane->base.frame_wait,
-                          list_empty(&dplane->vbl.update.node),
-                          HZ/25);
+       if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
+               armada_drm_plane_work_cancel(dcrtc, &dplane->base);

        if (plane->fb != fb) {
                struct armada_gem_object *obj = drm_fb_obj(fb);
@@ -255,7 +253,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
        }
        if (idx) {
                armada_reg_queue_end(dplane->vbl.regs, idx);
-               armada_drm_vbl_event_add(dcrtc, &dplane->vbl.update);
+               armada_drm_plane_work_queue(dcrtc, &dplane->base,
+                                           &dplane->vbl.work);
        }
        return 0;
 }
@@ -270,14 +269,13 @@ static int armada_ovl_plane_disable(struct drm_plane 
*plane)
                return 0;

        dcrtc = drm_to_armada_crtc(dplane->base.base.crtc);
-       dcrtc->plane = NULL;

-       armada_drm_vbl_event_remove(dcrtc, &dplane->vbl.update);
+       armada_drm_plane_work_cancel(dcrtc, &dplane->base);
+       armada_drm_crtc_plane_disable(dcrtc, plane);

+       dcrtc->plane = NULL;
        dplane->ctrl0 = 0;

-       armada_drm_crtc_plane_disable(dcrtc, plane);
-
        fb = xchg(&dplane->old_fb, NULL);
        if (fb)
                drm_framebuffer_unreference(fb);
@@ -456,8 +454,7 @@ int armada_overlay_plane_create(struct drm_device *dev, 
unsigned long crtcs)
                return ret;
        }

-       armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl,
-                                 dplane);
+       dplane->vbl.work.fn = armada_ovl_plane_work;

        ret = drm_universal_plane_init(dev, &dplane->base.base, crtcs,
                                       &armada_ovl_plane_funcs,
-- 
2.1.0

Reply via email to