To correctly disable hardware window during driver init, both enable bits
(WINCONx_ENWIN in WINCON and SHADOWCON_CHx_ENABLE in SHADOWCON) must be
cleared, otherwise hardware fails to re-enable such window later.

While touching this function, also temporarily disable ctx->suspended flag
to let fimd_wait_for_vblank function really to do its job.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 41904df..7a363d2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -165,27 +165,38 @@ static void fimd_wait_for_vblank(struct 
exynos_drm_manager *mgr)
                DRM_DEBUG_KMS("vblank wait timed out.\n");
 }
 
-
 static void fimd_clear_channel(struct exynos_drm_manager *mgr)
 {
        struct fimd_context *ctx = mgr->ctx;
-       int win, ch_enabled = 0;
+       int state, win, ch_enabled = 0;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
        /* Check if any channel is enabled. */
        for (win = 0; win < WINDOWS_NR; win++) {
-               u32 val = readl(ctx->regs + SHADOWCON);
-               if (val & SHADOWCON_CHx_ENABLE(win)) {
-                       val &= ~SHADOWCON_CHx_ENABLE(win);
-                       writel(val, ctx->regs + SHADOWCON);
+               u32 val = readl(ctx->regs + WINCON(win));
+               if (val & WINCONx_ENWIN) {
+                       /* wincon */
+                       val &= ~WINCONx_ENWIN;
+                       writel(val, ctx->regs + WINCON(win));
+
+                       /* unprotect windows */
+                       if (ctx->driver_data->has_shadowcon) {
+                               val = readl(ctx->regs + SHADOWCON);
+                               val &= ~SHADOWCON_CHx_ENABLE(win);
+                               writel(val, ctx->regs + SHADOWCON);
+                       }
                        ch_enabled = 1;
                }
        }
 
        /* Wait for vsync, as disable channel takes effect at next vsync */
-       if (ch_enabled)
+       if (ch_enabled) {
+               state = ctx->suspended;
+               ctx->suspended = 0;
                fimd_wait_for_vblank(mgr);
+               ctx->suspended = state;
+       }
 }
 
 static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
-- 
1.9.2

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to