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

Submitted by Andrzej Hajda on Dec. 10, 2018, 11:18 a.m.

Details

Message ID 20181210111834.17916-2-a.hajda@samsung.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in DRI devel

Not browsing as part of any series.

Commit Message

Andrzej Hajda Dec. 10, 2018, 11:18 a.m.
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@samsung.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 45 ++++++++-----------
 1 file changed, 19 insertions(+), 26 deletions(-)

Patch hide | download patch | download mbox

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