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. v2: fixed pixel format setting Signed-off-by: Andrzej Hajda <a.hajda@xxxxxxxxxxx> --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 45 ++++++++----------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 5b4e0e8b23bc..bdfec5f977e9 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -83,14 +83,6 @@ static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { [CURSON_WIN] = DRM_PLANE_TYPE_CURSOR, }; -static const unsigned int capabilities[WINDOWS_NR] = { - 0, - EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, - EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, - EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, - EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, -}; - static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, u32 val) { @@ -314,12 +306,13 @@ static void decon_win_set_bldmod(struct decon_context *ctx, unsigned int win, } } -static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, - struct drm_framebuffer *fb) +static void decon_win_set_pixfmt(struct decon_context *ctx, + struct exynos_drm_plane *plane) { - struct exynos_drm_plane plane = ctx->planes[win]; struct exynos_drm_plane_state *state = - to_exynos_plane_state(plane.base.state); + to_exynos_plane_state(plane->base.state); + unsigned int win = state->base.normalized_zpos + ctx->first_win; + struct drm_framebuffer *fb = state->base.fb; unsigned int alpha = state->base.alpha; unsigned int pixel_alpha; unsigned long val; @@ -402,7 +395,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); @@ -446,25 +439,24 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, | BIT_VAL(state->crtc.w * cpp, 14, 0); writel(val, ctx->addr + DECON_VIDW0xADD2(win)); - decon_win_set_pixfmt(ctx, win, fb); + decon_win_set_pixfmt(ctx, plane); /* window enable */ 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); @@ -538,7 +530,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); @@ -607,7 +599,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, }; @@ -628,7 +619,9 @@ 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 = capabilities[win]; + ctx->configs[win].capabilities = EXYNOS_DRM_PLANE_CAP_ZPOS + | EXYNOS_DRM_PLANE_CAP_WIN_BLEND + | EXYNOS_DRM_PLANE_CAP_PIX_BLEND; ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, &ctx->configs[win]); -- 2.17.1