diff mbox series

[1/3] drm/exynos/decon5433: add dynamic zpos support

Message ID 20181206093857.22324-2-a.hajda@samsung.com (mailing list archive)
State Not Applicable
Headers show
Series drm/exynos: add support for dynamic zpos in DECON and FIMD | expand

Commit Message

Andrzej Hajda Dec. 6, 2018, 9:38 a.m. UTC
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@samsung.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 23 +++++++++----------
 1 file changed, 11 insertions(+), 12 deletions(-)
diff mbox series

Patch

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]);