drm/exynos: check for pending fb before finish update
authorGustavo Padovan <gustavo.padovan@collabora.co.uk>
Sat, 15 Aug 2015 16:26:14 +0000 (13:26 -0300)
committerInki Dae <daeinki@gmail.com>
Sun, 30 Aug 2015 15:27:37 +0000 (00:27 +0900)
The current code was ignoring the end of update for all overlay planes,
caring only for the primary plane update in case of pageflip.

This change adds a change to start to check for pending updates for all
planes through exynos_plane->pending_fb. At the start of plane update the
pending_fb is set with the fb to be shown on the screen. Then only when to
fb is already presented in the screen we set pending_fb to NULL to
signal that the update was finished.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
fixup! drm/exynos: check for pending fb before finish update

drivers/gpu/drm/exynos/exynos5433_drm_decon.c
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_crtc.h
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_mixer.c

index 484e312..8d65e45 100644 (file)
@@ -542,13 +542,21 @@ static irqreturn_t decon_lcd_sys_irq_handler(int irq, void *dev_id)
 {
        struct decon_context *ctx = dev_id;
        u32 val;
+       int win;
 
        if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
                goto out;
 
        val = readl(ctx->addr + DECON_VIDINTCON1);
        if (val & VIDINTCON1_INTFRMDONEPEND) {
-               exynos_drm_crtc_finish_pageflip(ctx->crtc);
+               for (win = 0 ; win < WINDOWS_NR ; win++) {
+                       struct exynos_drm_plane *plane = &ctx->planes[win];
+
+                       if (!plane->pending_fb)
+                               continue;
+
+                       exynos_drm_crtc_finish_update(ctx->crtc, plane);
+               }
 
                /* clear */
                writel(VIDINTCON1_INTFRMDONEPEND,
index 0792654..7651499 100644 (file)
@@ -623,6 +623,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 {
        struct decon_context *ctx = (struct decon_context *)dev_id;
        u32 val, clear_bit;
+       int win;
 
        val = readl(ctx->regs + VIDINTCON1);
 
@@ -636,7 +637,14 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 
        if (!ctx->i80_if) {
                drm_crtc_handle_vblank(&ctx->crtc->base);
-               exynos_drm_crtc_finish_pageflip(ctx->crtc);
+               for (win = 0 ; win < WINDOWS_NR ; win++) {
+                       struct exynos_drm_plane *plane = &ctx->planes[win];
+
+                       if (!plane->pending_fb)
+                               continue;
+
+                       exynos_drm_crtc_finish_update(ctx->crtc, plane);
+               }
 
                /* set wait vsync event to zero and wake up queue. */
                if (atomic_read(&ctx->wait_vsync_event)) {
index 54485b7..582e041 100644 (file)
@@ -197,18 +197,19 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe)
                exynos_crtc->ops->disable_vblank(exynos_crtc);
 }
 
-void exynos_drm_crtc_finish_pageflip(struct exynos_drm_crtc *exynos_crtc)
+void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
+                               struct exynos_drm_plane *exynos_plane)
 {
        struct drm_crtc *crtc = &exynos_crtc->base;
        unsigned long flags;
 
+       exynos_plane->pending_fb = NULL;
+
        spin_lock_irqsave(&crtc->dev->event_lock, flags);
        if (exynos_crtc->event) {
-
                drm_crtc_send_vblank_event(crtc, exynos_crtc->event);
                drm_crtc_vblank_put(crtc);
                wake_up(&exynos_crtc->pending_flip_queue);
-
        }
 
        exynos_crtc->event = NULL;
index 9e7027d..8bedfde 100644 (file)
@@ -25,7 +25,8 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
                                        void *context);
 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
 void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
-void exynos_drm_crtc_finish_pageflip(struct exynos_drm_crtc *exynos_crtc);
+void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
+                                  struct exynos_drm_plane *exynos_plane);
 void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
 
 /* This function gets pipe value to crtc device matched with out_type. */
Simple merge