diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_drm.h | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_drv.c | 23 |
4 files changed, 56 insertions, 46 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index c7374a3ec67a..418594b19d1d 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -173,6 +173,44 @@ static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, return i; } +void armada_drm_vbl_event_add(struct armada_crtc *dcrtc, + struct armada_vbl_event *evt) +{ + 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); + + if (!not_on_list) + drm_vblank_put(dcrtc->crtc.dev, dcrtc->num); +} + +void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc, + struct armada_vbl_event *evt) +{ + if (!list_empty(&evt->node)) { + list_del_init(&evt->node); + drm_vblank_put(dcrtc->crtc.dev, dcrtc->num); + } +} + +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); + } +} + static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc, struct armada_frame_work *work) { @@ -356,7 +394,6 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc, static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) { - struct armada_vbl_event *e, *n; void __iomem *base = dcrtc->base; if (stat & DMA_FF_UNDERFLOW) @@ -368,12 +405,7 @@ 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); - - 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); - } + armada_drm_vbl_event_run(dcrtc); if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) { int i = stat & GRA_FRAME_IRQ0 ? 0 : 1; diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h index a13469f5d72b..a86243ef4a51 100644 --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h @@ -75,6 +75,23 @@ struct armada_crtc { }; #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_drm.h b/drivers/gpu/drm/armada/armada_drm.h index 5f6aef0dca59..4df6f2af2b21 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h @@ -37,22 +37,6 @@ static inline uint32_t armada_pitch(uint32_t width, uint32_t bpp) return ALIGN(pitch, 128); } -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) - struct armada_private; diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index b373cf9b2f65..3f1396e673dd 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -148,29 +148,6 @@ static int armada_drm_unload(struct drm_device *dev) return 0; } -void armada_drm_vbl_event_add(struct armada_crtc *dcrtc, - struct armada_vbl_event *evt) -{ - unsigned long flags; - - spin_lock_irqsave(&dcrtc->irq_lock, flags); - if (list_empty(&evt->node)) { - list_add_tail(&evt->node, &dcrtc->vbl_list); - - drm_vblank_get(dcrtc->crtc.dev, dcrtc->num); - } - spin_unlock_irqrestore(&dcrtc->irq_lock, flags); -} - -void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc, - struct armada_vbl_event *evt) -{ - if (!list_empty(&evt->node)) { - list_del_init(&evt->node); - drm_vblank_put(dcrtc->crtc.dev, dcrtc->num); - } -} - /* These are called under the vbl_lock. */ static int armada_drm_enable_vblank(struct drm_device *dev, int crtc) { |