aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Manszewski <c.manszewski@samsung.com>2018-10-25 12:21:53 -0400
committerInki Dae <inki.dae@samsung.com>2018-12-05 03:26:16 -0500
commitaf130280c613218a37675c6442650ca809f274c2 (patch)
tree6f113962aa4ae2ab4b8482916b9a31fd7c864ccf
parent54947290ef62880936ce5bd91489d41e8b1cbc2a (diff)
drm/exynos: decon: Make pixel blend mode configurable
The decon hardware supports different blend modes. Add pixel blend mode property and make it configurable, by modifying the blend equation. 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.c65
-rw-r--r--drivers/gpu/drm/exynos/regs-decon5433.h15
2 files changed, 70 insertions, 10 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 83a578c0dfa8..5b4e0e8b23bc 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -85,10 +85,10 @@ static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
85 85
86static const unsigned int capabilities[WINDOWS_NR] = { 86static const unsigned int capabilities[WINDOWS_NR] = {
87 0, 87 0,
88 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 88 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
89 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 89 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
90 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 90 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
91 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 91 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
92}; 92};
93 93
94static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, 94static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
@@ -259,13 +259,51 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
259 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 259 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
260} 260}
261 261
262static void decon_win_set_bldeq(struct decon_context *ctx, unsigned int win,
263 unsigned int alpha, unsigned int pixel_alpha)
264{
265 u32 mask = BLENDERQ_A_FUNC_F(0xf) | BLENDERQ_B_FUNC_F(0xf);
266 u32 val = 0;
267
268 switch (pixel_alpha) {
269 case DRM_MODE_BLEND_PIXEL_NONE:
270 case DRM_MODE_BLEND_COVERAGE:
271 val |= BLENDERQ_A_FUNC_F(BLENDERQ_ALPHA_A);
272 val |= BLENDERQ_B_FUNC_F(BLENDERQ_ONE_MINUS_ALPHA_A);
273 break;
274 case DRM_MODE_BLEND_PREMULTI:
275 default:
276 if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
277 val |= BLENDERQ_A_FUNC_F(BLENDERQ_ALPHA0);
278 val |= BLENDERQ_B_FUNC_F(BLENDERQ_ONE_MINUS_ALPHA_A);
279 } else {
280 val |= BLENDERQ_A_FUNC_F(BLENDERQ_ONE);
281 val |= BLENDERQ_B_FUNC_F(BLENDERQ_ONE_MINUS_ALPHA_A);
282 }
283 break;
284 }
285 decon_set_bits(ctx, DECON_BLENDERQx(win), mask, val);
286}
262 287
263static void decon_win_set_bldmod(struct decon_context *ctx, unsigned int win, 288static void decon_win_set_bldmod(struct decon_context *ctx, unsigned int win,
264 unsigned int alpha) 289 unsigned int alpha, unsigned int pixel_alpha)
265{ 290{
266 u32 win_alpha = alpha >> 8; 291 u32 win_alpha = alpha >> 8;
267 u32 val = 0; 292 u32 val = 0;
268 293
294 switch (pixel_alpha) {
295 case DRM_MODE_BLEND_PIXEL_NONE:
296 break;
297 case DRM_MODE_BLEND_COVERAGE:
298 case DRM_MODE_BLEND_PREMULTI:
299 default:
300 val |= WINCONx_ALPHA_SEL_F;
301 val |= WINCONx_BLD_PIX_F;
302 val |= WINCONx_ALPHA_MUL_F;
303 break;
304 }
305 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_BLEND_MODE_MASK, val);
306
269 if (alpha != DRM_BLEND_ALPHA_OPAQUE) { 307 if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
270 val = VIDOSD_Wx_ALPHA_R_F(win_alpha) | 308 val = VIDOSD_Wx_ALPHA_R_F(win_alpha) |
271 VIDOSD_Wx_ALPHA_G_F(win_alpha) | 309 VIDOSD_Wx_ALPHA_G_F(win_alpha) |
@@ -283,8 +321,14 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
283 struct exynos_drm_plane_state *state = 321 struct exynos_drm_plane_state *state =
284 to_exynos_plane_state(plane.base.state); 322 to_exynos_plane_state(plane.base.state);
285 unsigned int alpha = state->base.alpha; 323 unsigned int alpha = state->base.alpha;
324 unsigned int pixel_alpha;
286 unsigned long val; 325 unsigned long val;
287 326
327 if (fb->format->has_alpha)
328 pixel_alpha = state->base.pixel_blend_mode;
329 else
330 pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE;
331
288 val = readl(ctx->addr + DECON_WINCONx(win)); 332 val = readl(ctx->addr + DECON_WINCONx(win));
289 val &= WINCONx_ENWIN_F; 333 val &= WINCONx_ENWIN_F;
290 334
@@ -307,9 +351,8 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
307 case DRM_FORMAT_ARGB8888: 351 case DRM_FORMAT_ARGB8888:
308 default: 352 default:
309 val |= WINCONx_BPPMODE_32BPP_A8888; 353 val |= WINCONx_BPPMODE_32BPP_A8888;
310 val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F; 354 val |= WINCONx_WSWP_F;
311 val |= WINCONx_BURSTLEN_16WORD; 355 val |= WINCONx_BURSTLEN_16WORD;
312 val |= WINCONx_ALPHA_MUL_F;
313 break; 356 break;
314 } 357 }
315 358
@@ -327,10 +370,12 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
327 val &= ~WINCONx_BURSTLEN_MASK; 370 val &= ~WINCONx_BURSTLEN_MASK;
328 val |= WINCONx_BURSTLEN_8WORD; 371 val |= WINCONx_BURSTLEN_8WORD;
329 } 372 }
373 decon_set_bits(ctx, DECON_WINCONx(win), ~WINCONx_BLEND_MODE_MASK, val);
330 374
331 writel(val, ctx->addr + DECON_WINCONx(win)); 375 if (win > 0) {
332 if (win > 0) 376 decon_win_set_bldmod(ctx, win, alpha, pixel_alpha);
333 decon_win_set_bldmod(ctx, win, alpha); 377 decon_win_set_bldeq(ctx, win, alpha, pixel_alpha);
378 }
334} 379}
335 380
336static void decon_shadow_protect(struct decon_context *ctx, bool protect) 381static void decon_shadow_protect(struct decon_context *ctx, bool protect)
diff --git a/drivers/gpu/drm/exynos/regs-decon5433.h b/drivers/gpu/drm/exynos/regs-decon5433.h
index 72648bda3142..63db6974bf14 100644
--- a/drivers/gpu/drm/exynos/regs-decon5433.h
+++ b/drivers/gpu/drm/exynos/regs-decon5433.h
@@ -117,6 +117,7 @@
117#define WINCONx_BPPMODE_16BPP_A4444 (0xe << 2) 117#define WINCONx_BPPMODE_16BPP_A4444 (0xe << 2)
118#define WINCONx_ALPHA_SEL_F (1 << 1) 118#define WINCONx_ALPHA_SEL_F (1 << 1)
119#define WINCONx_ENWIN_F (1 << 0) 119#define WINCONx_ENWIN_F (1 << 0)
120#define WINCONx_BLEND_MODE_MASK (0xc2)
120 121
121/* SHADOWCON */ 122/* SHADOWCON */
122#define SHADOWCON_PROTECT_MASK GENMASK(14, 10) 123#define SHADOWCON_PROTECT_MASK GENMASK(14, 10)
@@ -213,4 +214,18 @@
213/* BLENDCON */ 214/* BLENDCON */
214#define BLEND_NEW (1 << 0) 215#define BLEND_NEW (1 << 0)
215 216
217/* BLENDERQx */
218#define BLENDERQ_ZERO 0x0
219#define BLENDERQ_ONE 0x1
220#define BLENDERQ_ALPHA_A 0x2
221#define BLENDERQ_ONE_MINUS_ALPHA_A 0x3
222#define BLENDERQ_ALPHA0 0x6
223#define BLENDERQ_Q_FUNC_F(n) (n << 18)
224#define BLENDERQ_P_FUNC_F(n) (n << 12)
225#define BLENDERQ_B_FUNC_F(n) (n << 6)
226#define BLENDERQ_A_FUNC_F(n) (n << 0)
227
228/* BLENDCON */
229#define BLEND_NEW (1 << 0)
230
216#endif /* EXYNOS_REGS_DECON5433_H */ 231#endif /* EXYNOS_REGS_DECON5433_H */