drm/exynos: fimd: only finish update if START == START_S
authorGustavo Padovan <gustavo.padovan@collabora.co.uk>
Sat, 15 Aug 2015 16:26:16 +0000 (13:26 -0300)
committerInki Dae <daeinki@gmail.com>
Sun, 30 Aug 2015 15:27:37 +0000 (00:27 +0900)
fimd_update_plane() programs BUF_START[win] and during the update
BUF_START[win] is copied to BUF_START_S[win] (its shadow register)
and starts scanning out, then it raises a irq.

The fimd_irq_handler, in the case we have a pending_fb, will check
the fb value was copied to START_S register and finish the update
in case of success.

Based on patch from Daniel Kurtz <djkurtz@chromium.org>

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_fimd.c

index fc26c3ef95bf643b8a6a2ac586471e9ee0989349..d96044f4c2287977ac07f821e25266a44f583cea 100644 (file)
@@ -59,6 +59,7 @@
 #define VIDWnALPHA1(win)       (VIDW_ALPHA + 0x04 + (win) * 8)
 
 #define VIDWx_BUF_START(win, buf)      (VIDW_BUF_START(buf) + (win) * 8)
+#define VIDWx_BUF_START_S(win, buf)    (VIDW_BUF_START_S(buf) + (win) * 8)
 #define VIDWx_BUF_END(win, buf)                (VIDW_BUF_END(buf) + (win) * 8)
 #define VIDWx_BUF_SIZE(win, buf)       (VIDW_BUF_SIZE(buf) + (win) * 4)
 
@@ -895,7 +896,7 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
 {
        struct fimd_context *ctx = (struct fimd_context *)dev_id;
-       u32 val, clear_bit;
+       u32 val, clear_bit, start, start_s;
        int win;
 
        val = readl(ctx->regs + VIDINTCON1);
@@ -917,7 +918,10 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
                if (!plane->pending_fb)
                        continue;
 
-               exynos_drm_crtc_finish_update(ctx->crtc, plane);
+               start = readl(ctx->regs + VIDWx_BUF_START(win, 0));
+               start_s = readl(ctx->regs + VIDWx_BUF_START_S(win, 0));
+               if (start == start_s)
+                       exynos_drm_crtc_finish_update(ctx->crtc, plane);
        }
 
        if (ctx->i80_if) {