diff options
author | Christoph Manszewski <c.manszewski@samsung.com> | 2018-10-25 12:21:52 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2018-12-05 03:26:00 -0500 |
commit | 54947290ef62880936ce5bd91489d41e8b1cbc2a (patch) | |
tree | b8aa8072fd92e6ba3329d2cf819c1ec8ee4e14ad | |
parent | 67fbf3a3ef84436c58b5ead53b4b866125ad7ce9 (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/regs-decon5433.h | 7 |
2 files changed, 40 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] = { | |||
83 | [CURSON_WIN] = DRM_PLANE_TYPE_CURSOR, | 83 | [CURSON_WIN] = DRM_PLANE_TYPE_CURSOR, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static const unsigned int capabilities[WINDOWS_NR] = { | ||
87 | 0, | ||
88 | EXYNOS_DRM_PLANE_CAP_WIN_BLEND, | ||
89 | EXYNOS_DRM_PLANE_CAP_WIN_BLEND, | ||
90 | EXYNOS_DRM_PLANE_CAP_WIN_BLEND, | ||
91 | EXYNOS_DRM_PLANE_CAP_WIN_BLEND, | ||
92 | }; | ||
93 | |||
86 | static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, | 94 | static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, |
87 | u32 val) | 95 | u32 val) |
88 | { | 96 | { |
@@ -251,9 +259,30 @@ static void decon_commit(struct exynos_drm_crtc *crtc) | |||
251 | decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); | 259 | decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); |
252 | } | 260 | } |
253 | 261 | ||
262 | |||
263 | static void decon_win_set_bldmod(struct decon_context *ctx, unsigned int win, | ||
264 | unsigned int alpha) | ||
265 | { | ||
266 | u32 win_alpha = alpha >> 8; | ||
267 | u32 val = 0; | ||
268 | |||
269 | if (alpha != DRM_BLEND_ALPHA_OPAQUE) { | ||
270 | val = VIDOSD_Wx_ALPHA_R_F(win_alpha) | | ||
271 | VIDOSD_Wx_ALPHA_G_F(win_alpha) | | ||
272 | VIDOSD_Wx_ALPHA_B_F(win_alpha); | ||
273 | decon_set_bits(ctx, DECON_VIDOSDxC(win), | ||
274 | VIDOSDxC_ALPHA0_RGB_MASK, val); | ||
275 | decon_set_bits(ctx, DECON_BLENDCON, BLEND_NEW, BLEND_NEW); | ||
276 | } | ||
277 | } | ||
278 | |||
254 | static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, | 279 | static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, |
255 | struct drm_framebuffer *fb) | 280 | struct drm_framebuffer *fb) |
256 | { | 281 | { |
282 | struct exynos_drm_plane plane = ctx->planes[win]; | ||
283 | struct exynos_drm_plane_state *state = | ||
284 | to_exynos_plane_state(plane.base.state); | ||
285 | unsigned int alpha = state->base.alpha; | ||
257 | unsigned long val; | 286 | unsigned long val; |
258 | 287 | ||
259 | val = readl(ctx->addr + DECON_WINCONx(win)); | 288 | val = readl(ctx->addr + DECON_WINCONx(win)); |
@@ -280,6 +309,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, | |||
280 | val |= WINCONx_BPPMODE_32BPP_A8888; | 309 | val |= WINCONx_BPPMODE_32BPP_A8888; |
281 | val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F; | 310 | val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F; |
282 | val |= WINCONx_BURSTLEN_16WORD; | 311 | val |= WINCONx_BURSTLEN_16WORD; |
312 | val |= WINCONx_ALPHA_MUL_F; | ||
283 | break; | 313 | break; |
284 | } | 314 | } |
285 | 315 | ||
@@ -299,6 +329,8 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, | |||
299 | } | 329 | } |
300 | 330 | ||
301 | writel(val, ctx->addr + DECON_WINCONx(win)); | 331 | writel(val, ctx->addr + DECON_WINCONx(win)); |
332 | if (win > 0) | ||
333 | decon_win_set_bldmod(ctx, win, alpha); | ||
302 | } | 334 | } |
303 | 335 | ||
304 | static void decon_shadow_protect(struct decon_context *ctx, bool protect) | 336 | 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) | |||
551 | ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); | 583 | ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); |
552 | ctx->configs[win].zpos = win - ctx->first_win; | 584 | ctx->configs[win].zpos = win - ctx->first_win; |
553 | ctx->configs[win].type = decon_win_types[win]; | 585 | ctx->configs[win].type = decon_win_types[win]; |
586 | ctx->configs[win].capabilities = capabilities[win]; | ||
554 | 587 | ||
555 | ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, | 588 | ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, |
556 | &ctx->configs[win]); | 589 | &ctx->configs[win]); |
diff --git a/drivers/gpu/drm/exynos/regs-decon5433.h b/drivers/gpu/drm/exynos/regs-decon5433.h index 19ad9e47945e..72648bda3142 100644 --- a/drivers/gpu/drm/exynos/regs-decon5433.h +++ b/drivers/gpu/drm/exynos/regs-decon5433.h | |||
@@ -104,6 +104,7 @@ | |||
104 | #define WINCONx_BURSTLEN_16WORD (0x0 << 10) | 104 | #define WINCONx_BURSTLEN_16WORD (0x0 << 10) |
105 | #define WINCONx_BURSTLEN_8WORD (0x1 << 10) | 105 | #define WINCONx_BURSTLEN_8WORD (0x1 << 10) |
106 | #define WINCONx_BURSTLEN_4WORD (0x2 << 10) | 106 | #define WINCONx_BURSTLEN_4WORD (0x2 << 10) |
107 | #define WINCONx_ALPHA_MUL_F (1 << 7) | ||
107 | #define WINCONx_BLD_PIX_F (1 << 6) | 108 | #define WINCONx_BLD_PIX_F (1 << 6) |
108 | #define WINCONx_BPPMODE_MASK (0xf << 2) | 109 | #define WINCONx_BPPMODE_MASK (0xf << 2) |
109 | #define WINCONx_BPPMODE_16BPP_565 (0x5 << 2) | 110 | #define WINCONx_BPPMODE_16BPP_565 (0x5 << 2) |
@@ -121,6 +122,9 @@ | |||
121 | #define SHADOWCON_PROTECT_MASK GENMASK(14, 10) | 122 | #define SHADOWCON_PROTECT_MASK GENMASK(14, 10) |
122 | #define SHADOWCON_Wx_PROTECT(n) (1 << (10 + (n))) | 123 | #define SHADOWCON_Wx_PROTECT(n) (1 << (10 + (n))) |
123 | 124 | ||
125 | /* VIDOSDxC */ | ||
126 | #define VIDOSDxC_ALPHA0_RGB_MASK (0xffffff) | ||
127 | |||
124 | /* VIDOSDxD */ | 128 | /* VIDOSDxD */ |
125 | #define VIDOSD_Wx_ALPHA_R_F(n) (((n) & 0xff) << 16) | 129 | #define VIDOSD_Wx_ALPHA_R_F(n) (((n) & 0xff) << 16) |
126 | #define VIDOSD_Wx_ALPHA_G_F(n) (((n) & 0xff) << 8) | 130 | #define VIDOSD_Wx_ALPHA_G_F(n) (((n) & 0xff) << 8) |
@@ -206,4 +210,7 @@ | |||
206 | #define CRCCTRL_CRCEN (0x1 << 0) | 210 | #define CRCCTRL_CRCEN (0x1 << 0) |
207 | #define CRCCTRL_MASK (0x7) | 211 | #define CRCCTRL_MASK (0x7) |
208 | 212 | ||
213 | /* BLENDCON */ | ||
214 | #define BLEND_NEW (1 << 0) | ||
215 | |||
209 | #endif /* EXYNOS_REGS_DECON5433_H */ | 216 | #endif /* EXYNOS_REGS_DECON5433_H */ |