DECON has fixed hardware window order. To implement dynamic zpos normalized_zpos of active plane has to be connected to window number, and remaining windows have to be disabled. Signed-off-by: Andrzej Hajda <a.hajda@xxxxxxxxxxx> --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index aef487dd8731..6e3e6e970690 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -326,7 +326,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, to_exynos_plane_state(plane->base.state); struct decon_context *ctx = crtc->ctx; struct drm_framebuffer *fb = state->base.fb; - unsigned int win = plane->index; + unsigned int win = state->base.normalized_zpos + ctx->first_win; unsigned int cpp = fb->format->cpp[0]; unsigned int pitch = fb->pitches[0]; dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0); @@ -376,19 +376,18 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0); } -static void decon_disable_plane(struct exynos_drm_crtc *crtc, - struct exynos_drm_plane *plane) -{ - struct decon_context *ctx = crtc->ctx; - unsigned int win = plane->index; - - decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); -} - static void decon_atomic_flush(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx; unsigned long flags; + int win = hweight32(crtc->base.state->plane_mask) + ctx->first_win; + + /* disable windows corresponding to disabled planes */ + for (; win < WINDOWS_NR; ++win) { + if (!readl(ctx->addr + DECON_WINCONx(win)) & WINCONx_ENWIN_F) + break; + decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); + } spin_lock_irqsave(&ctx->vblank_lock, flags); @@ -462,7 +461,7 @@ static void decon_disable(struct exynos_drm_crtc *crtc) * a destroyed buffer later. */ for (i = ctx->first_win; i < WINDOWS_NR; i++) - decon_disable_plane(crtc, &ctx->planes[i]); + decon_set_bits(ctx, DECON_WINCONx(i), WINCONx_ENWIN_F, 0); decon_swreset(ctx); @@ -531,7 +530,6 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = { .disable_vblank = decon_disable_vblank, .atomic_begin = decon_atomic_begin, .update_plane = decon_update_plane, - .disable_plane = decon_disable_plane, .mode_valid = decon_mode_valid, .atomic_flush = decon_atomic_flush, }; @@ -552,6 +550,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); ctx->configs[win].zpos = win - ctx->first_win; ctx->configs[win].type = decon_win_types[win]; + ctx->configs[win].capabilities = EXYNOS_DRM_PLANE_CAP_ZPOS; ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, &ctx->configs[win]); -- 2.17.1