aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
diff options
context:
space:
mode:
authorChristoph Manszewski <c.manszewski@samsung.com>2018-10-25 18:21:52 +0200
committerInki Dae <inki.dae@samsung.com>2018-12-05 17:26:00 +0900
commit54947290ef62880936ce5bd91489d41e8b1cbc2a (patch)
treeb8aa8072fd92e6ba3329d2cf819c1ec8ee4e14ad /drivers/gpu/drm/exynos/exynos5433_drm_decon.c
parentdrm/exynos/iommu: merge IOMMU and DMA code (diff)
downloadlinux-dev-54947290ef62880936ce5bd91489d41e8b1cbc2a.tar.xz
linux-dev-54947290ef62880936ce5bd91489d41e8b1cbc2a.zip
drm/exynos: decon: Make plane alpha configurable
The decon hardware supports variable plane alpha. Currently planes are opaque, make this configurable. Tested on TM2 with Exynos 5433 CPU, on top of linux-next-20181019. Signed-off-by: Christoph Manszewski <c.manszewski@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos5433_drm_decon.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 40723f395ecc..83a578c0dfa8 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -83,6 +83,14 @@ 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_WIN_BLEND,
+ EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
+ EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
+};
+
static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
u32 val)
{
@@ -251,9 +259,30 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
+
+static void decon_win_set_bldmod(struct decon_context *ctx, unsigned int win,
+ unsigned int alpha)
+{
+ u32 win_alpha = alpha >> 8;
+ u32 val = 0;
+
+ if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
+ val = VIDOSD_Wx_ALPHA_R_F(win_alpha) |
+ VIDOSD_Wx_ALPHA_G_F(win_alpha) |
+ VIDOSD_Wx_ALPHA_B_F(win_alpha);
+ decon_set_bits(ctx, DECON_VIDOSDxC(win),
+ VIDOSDxC_ALPHA0_RGB_MASK, val);
+ decon_set_bits(ctx, DECON_BLENDCON, BLEND_NEW, BLEND_NEW);
+ }
+}
+
static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
struct drm_framebuffer *fb)
{
+ struct exynos_drm_plane plane = ctx->planes[win];
+ struct exynos_drm_plane_state *state =
+ to_exynos_plane_state(plane.base.state);
+ unsigned int alpha = state->base.alpha;
unsigned long val;
val = readl(ctx->addr + DECON_WINCONx(win));
@@ -280,6 +309,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
val |= WINCONx_BPPMODE_32BPP_A8888;
val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
val |= WINCONx_BURSTLEN_16WORD;
+ val |= WINCONx_ALPHA_MUL_F;
break;
}
@@ -299,6 +329,8 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
}
writel(val, ctx->addr + DECON_WINCONx(win));
+ if (win > 0)
+ decon_win_set_bldmod(ctx, win, alpha);
}
static void decon_shadow_protect(struct decon_context *ctx, bool protect)
@@ -551,6 +583,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 = capabilities[win];
ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
&ctx->configs[win]);