@@ -219,6 +219,17 @@ static void decon_shadow_protect_win(struct decon_context *ctx, int win,
writel(val, ctx->addr + DECON_SHADOWCON);
}
+static void decon_prepare_plane(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
+{
+ struct decon_context *ctx = crtc->ctx;
+
+ if (ctx->suspended)
+ return;
+
+ decon_shadow_protect_win(ctx, plane->zpos, true);
+}
+
static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane)
{
@@ -232,8 +243,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
if (ctx->suspended)
return;
- decon_shadow_protect_win(ctx, win, true);
-
val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
writel(val, ctx->addr + DECON_VIDOSDxA(win));
@@ -265,15 +274,10 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
val |= WINCONx_ENWIN_F;
writel(val, ctx->addr + DECON_WINCONx(win));
- decon_shadow_protect_win(ctx, win, false);
-
/* standalone update */
val = readl(ctx->addr + DECON_UPDATE);
val |= STANDALONE_UPDATE_F;
writel(val, ctx->addr + DECON_UPDATE);
-
- if (ctx->i80_if)
- atomic_set(&ctx->win_updated, 1);
}
static void decon_disable_plane(struct exynos_drm_crtc *crtc,
@@ -301,6 +305,20 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
writel(val, ctx->addr + DECON_UPDATE);
}
+static void decon_cleanup_plane(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
+{
+ struct decon_context *ctx = crtc->ctx;
+
+ if (ctx->suspended)
+ return;
+
+ decon_shadow_protect_win(ctx, plane->zpos, false);
+
+ if (ctx->i80_if)
+ atomic_set(&ctx->win_updated, 1);
+}
+
static void decon_swreset(struct decon_context *ctx)
{
unsigned int tries;
@@ -455,8 +473,10 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable_vblank = decon_enable_vblank,
.disable_vblank = decon_disable_vblank,
.commit = decon_commit,
+ .prepare_plane = decon_prepare_plane,
.update_plane = decon_update_plane,
.disable_plane = decon_disable_plane,
+ .cleanup_plane = decon_cleanup_plane,
.te_handler = decon_te_irq_handler,
};
@@ -383,6 +383,17 @@ static void decon_shadow_protect_win(struct decon_context *ctx,
writel(val, ctx->regs + SHADOWCON);
}
+static void decon_prepare_plane(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
+{
+ struct decon_context *ctx = crtc->ctx;
+
+ if (ctx->suspended)
+ return;
+
+ decon_shadow_protect_win(ctx, plane->zpos, true);
+}
+
static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane)
{
@@ -410,9 +421,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
* is set.
*/
- /* protect windows */
- decon_shadow_protect_win(ctx, win, true);
-
/* buffer start address */
val = (unsigned long)plane->dma_addr[0];
writel(val, ctx->regs + VIDW_BUF_START(win));
@@ -510,14 +518,22 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
val &= ~WINCONx_ENWIN;
writel(val, ctx->regs + WINCON(win));
- /* unprotect windows */
- decon_shadow_protect_win(ctx, win, false);
-
val = readl(ctx->regs + DECON_UPDATE);
val |= DECON_UPDATE_STANDALONE_F;
writel(val, ctx->regs + DECON_UPDATE);
}
+static void decon_cleanup_plane(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
+{
+ struct decon_context *ctx = crtc->ctx;
+
+ if (ctx->suspended)
+ return;
+
+ decon_shadow_protect_win(ctx, plane->zpos, false);
+}
+
static void decon_init(struct decon_context *ctx)
{
u32 val;
@@ -614,8 +630,10 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable_vblank = decon_enable_vblank,
.disable_vblank = decon_disable_vblank,
.wait_for_vblank = decon_wait_for_vblank,
+ .prepare_plane = decon_prepare_plane,
.update_plane = decon_update_plane,
.disable_plane = decon_disable_plane,
+ .cleanup_plane = decon_cleanup_plane,
};
Each CRTC's {prepare/cleanup}_plane must stop/start the update of shadow registers to active register in the functions. This patch achieves these purpose by moving the setting of protection bits to those functions from decon_update_plane. Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com> --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 34 +++++++++++++++++++++------ drivers/gpu/drm/exynos/exynos7_drm_decon.c | 30 ++++++++++++++++++----- 2 files changed, 51 insertions(+), 13 deletions(-)