From: Gustavo Padovan <gustavo.pado...@collabora.co.uk>

Only set/clear the update bit in the CRTC's .atomic_begin()/flush()
so all planes are really committed at the same time.

Signed-off-by: Gustavo Padovan <gustavo.padovan at collabora.co.uk>

---
v2: rename prepare_plane/cleanup_plane to atomic_begin/atomic_flush
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 57 +++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 30c1409..005a996 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -591,6 +591,16 @@ static void fimd_shadow_protect_win(struct fimd_context 
*ctx,
 {
        u32 reg, bits, val;

+       /*
+        * SHADOWCON/PRTCON register is used for enabling timing.
+        *
+        * for example, once only width value of a register is set,
+        * if the dma is started then fimd hardware could malfunction so
+        * with protect window setting, the register fields with prefix '_F'
+        * wouldn't be updated at vsync also but updated once unprotect window
+        * is set.
+        */
+
        if (ctx->driver_data->has_shadowcon) {
                reg = SHADOWCON;
                bits = SHADOWCON_WINx_PROTECT(win);
@@ -607,6 +617,28 @@ static void fimd_shadow_protect_win(struct fimd_context 
*ctx,
        writel(val, ctx->regs + reg);
 }

+static void fimd_atomic_begin(struct exynos_drm_crtc *crtc,
+                              struct exynos_drm_plane *plane)
+{
+       struct fimd_context *ctx = crtc->ctx;
+
+       if (ctx->suspended)
+               return;
+
+       fimd_shadow_protect_win(ctx, plane->zpos, true);
+}
+
+static void fimd_atomic_flush(struct exynos_drm_crtc *crtc,
+                              struct exynos_drm_plane *plane)
+{
+       struct fimd_context *ctx = crtc->ctx;
+
+       if (ctx->suspended)
+               return;
+
+       fimd_shadow_protect_win(ctx, plane->zpos, false);
+}
+
 static void fimd_update_plane(struct exynos_drm_crtc *crtc,
                              struct exynos_drm_plane *plane)
 {
@@ -622,20 +654,6 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
        if (ctx->suspended)
                return;

-       /*
-        * SHADOWCON/PRTCON register is used for enabling timing.
-        *
-        * for example, once only width value of a register is set,
-        * if the dma is started then fimd hardware could malfunction so
-        * with protect window setting, the register fields with prefix '_F'
-        * wouldn't be updated at vsync also but updated once unprotect window
-        * is set.
-        */
-
-       /* protect windows */
-       fimd_shadow_protect_win(ctx, win, true);
-
-
        offset = plane->src_x * bpp;
        offset += plane->src_y * pitch;

@@ -707,9 +725,6 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
        if (ctx->driver_data->has_shadowcon)
                fimd_enable_shadow_channel_path(ctx, win, true);

-       /* Enable DMA channel and unprotect windows */
-       fimd_shadow_protect_win(ctx, win, false);
-
        if (ctx->i80_if)
                atomic_set(&ctx->win_updated, 1);
 }
@@ -723,16 +738,10 @@ static void fimd_disable_plane(struct exynos_drm_crtc 
*crtc,
        if (ctx->suspended)
                return;

-       /* protect windows */
-       fimd_shadow_protect_win(ctx, win, true);
-
        fimd_enable_video_output(ctx, win, false);

        if (ctx->driver_data->has_shadowcon)
                fimd_enable_shadow_channel_path(ctx, win, false);
-
-       /* unprotect windows */
-       fimd_shadow_protect_win(ctx, win, false);
 }

 static void fimd_enable(struct exynos_drm_crtc *crtc)
@@ -875,8 +884,10 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
        .enable_vblank = fimd_enable_vblank,
        .disable_vblank = fimd_disable_vblank,
        .wait_for_vblank = fimd_wait_for_vblank,
+       .atomic_begin = fimd_atomic_begin,
        .update_plane = fimd_update_plane,
        .disable_plane = fimd_disable_plane,
+       .atomic_flush = fimd_atomic_flush,
        .te_handler = fimd_te_handler,
        .clock_enable = fimd_dp_clock_enable,
 };
-- 
2.1.0

Reply via email to