Commit cc5a7b35 authored by Hyungwon Hwang's avatar Hyungwon Hwang Committed by Inki Dae

drm/exynos: implement atomic_{begin/flush} of DECON

Each CRTC's atomic_{begin/flush} 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.

v2: rebased to the branch exynos-drm-next
Signed-off-by: default avatarHyungwon Hwang <human.hwang@samsung.com>
Reviewed-by: default avatarDaniel Stone <daniels@collabora.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent e7fefb1d
...@@ -219,6 +219,17 @@ static void decon_shadow_protect_win(struct decon_context *ctx, int win, ...@@ -219,6 +219,17 @@ static void decon_shadow_protect_win(struct decon_context *ctx, int win,
writel(val, ctx->addr + DECON_SHADOWCON); writel(val, ctx->addr + DECON_SHADOWCON);
} }
static void decon_atomic_begin(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, static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
...@@ -232,8 +243,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -232,8 +243,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
if (ctx->suspended) if (ctx->suspended)
return; return;
decon_shadow_protect_win(ctx, win, true);
val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y); val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
writel(val, ctx->addr + DECON_VIDOSDxA(win)); writel(val, ctx->addr + DECON_VIDOSDxA(win));
...@@ -265,15 +274,10 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -265,15 +274,10 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
val |= WINCONx_ENWIN_F; val |= WINCONx_ENWIN_F;
writel(val, ctx->addr + DECON_WINCONx(win)); writel(val, ctx->addr + DECON_WINCONx(win));
decon_shadow_protect_win(ctx, win, false);
/* standalone update */ /* standalone update */
val = readl(ctx->addr + DECON_UPDATE); val = readl(ctx->addr + DECON_UPDATE);
val |= STANDALONE_UPDATE_F; val |= STANDALONE_UPDATE_F;
writel(val, ctx->addr + DECON_UPDATE); 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, static void decon_disable_plane(struct exynos_drm_crtc *crtc,
...@@ -301,6 +305,20 @@ 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); writel(val, ctx->addr + DECON_UPDATE);
} }
static void decon_atomic_flush(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) static void decon_swreset(struct decon_context *ctx)
{ {
unsigned int tries; unsigned int tries;
...@@ -455,8 +473,10 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = { ...@@ -455,8 +473,10 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable_vblank = decon_enable_vblank, .enable_vblank = decon_enable_vblank,
.disable_vblank = decon_disable_vblank, .disable_vblank = decon_disable_vblank,
.commit = decon_commit, .commit = decon_commit,
.atomic_begin = decon_atomic_begin,
.update_plane = decon_update_plane, .update_plane = decon_update_plane,
.disable_plane = decon_disable_plane, .disable_plane = decon_disable_plane,
.atomic_flush = decon_atomic_flush,
.te_handler = decon_te_irq_handler, .te_handler = decon_te_irq_handler,
}; };
......
...@@ -383,6 +383,17 @@ static void decon_shadow_protect_win(struct decon_context *ctx, ...@@ -383,6 +383,17 @@ static void decon_shadow_protect_win(struct decon_context *ctx,
writel(val, ctx->regs + SHADOWCON); writel(val, ctx->regs + SHADOWCON);
} }
static void decon_atomic_begin(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, static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
...@@ -410,9 +421,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -410,9 +421,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
* is set. * is set.
*/ */
/* protect windows */
decon_shadow_protect_win(ctx, win, true);
/* buffer start address */ /* buffer start address */
val = (unsigned long)plane->dma_addr[0]; val = (unsigned long)plane->dma_addr[0];
writel(val, ctx->regs + VIDW_BUF_START(win)); writel(val, ctx->regs + VIDW_BUF_START(win));
...@@ -510,14 +518,22 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, ...@@ -510,14 +518,22 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
val &= ~WINCONx_ENWIN; val &= ~WINCONx_ENWIN;
writel(val, ctx->regs + WINCON(win)); writel(val, ctx->regs + WINCON(win));
/* unprotect windows */
decon_shadow_protect_win(ctx, win, false);
val = readl(ctx->regs + DECON_UPDATE); val = readl(ctx->regs + DECON_UPDATE);
val |= DECON_UPDATE_STANDALONE_F; val |= DECON_UPDATE_STANDALONE_F;
writel(val, ctx->regs + DECON_UPDATE); writel(val, ctx->regs + DECON_UPDATE);
} }
static void decon_atomic_flush(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) static void decon_init(struct decon_context *ctx)
{ {
u32 val; u32 val;
...@@ -614,8 +630,10 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = { ...@@ -614,8 +630,10 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable_vblank = decon_enable_vblank, .enable_vblank = decon_enable_vblank,
.disable_vblank = decon_disable_vblank, .disable_vblank = decon_disable_vblank,
.wait_for_vblank = decon_wait_for_vblank, .wait_for_vblank = decon_wait_for_vblank,
.atomic_begin = decon_atomic_begin,
.update_plane = decon_update_plane, .update_plane = decon_update_plane,
.disable_plane = decon_disable_plane, .disable_plane = decon_disable_plane,
.atomic_flush = decon_atomic_flush,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment