diff options
author | Christoph Manszewski <c.manszewski@samsung.com> | 2018-09-21 08:24:37 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2018-09-30 22:49:57 -0400 |
commit | 482582c0217d352f0e344f0b25ea6ce12f964351 (patch) | |
tree | f59cd1d91f5eaa37f9513310310cda2e624dd0e2 | |
parent | a9777267e3e19e784723827a41cfb37da6e5bf66 (diff) |
drm/exynos: mixer: Make pixel blend mode configurable
The mixer hardware supports both premultiplied alpha and
non-premultiplied alpha. Currently premultiplied alpha is default, make
this configurable.
Tested on Odroid-U3 with Exynos 4412 CPU, kernel next-20180913
using modetest.
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/exynos_drm_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_mixer.c | 27 |
3 files changed, 29 insertions, 6 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 7349e7c00c8f..4f60e9126e8a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -92,6 +92,7 @@ struct exynos_drm_plane { | |||
92 | #define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1) | 92 | #define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1) |
93 | #define EXYNOS_DRM_PLANE_CAP_ZPOS (1 << 2) | 93 | #define EXYNOS_DRM_PLANE_CAP_ZPOS (1 << 2) |
94 | #define EXYNOS_DRM_PLANE_CAP_TILE (1 << 3) | 94 | #define EXYNOS_DRM_PLANE_CAP_TILE (1 << 3) |
95 | #define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4) | ||
95 | 96 | ||
96 | /* | 97 | /* |
97 | * Exynos DRM plane configuration structure. | 98 | * Exynos DRM plane configuration structure. |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 755ca0e9ead2..236408906f1f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -298,6 +298,10 @@ int exynos_plane_init(struct drm_device *dev, | |||
298 | const struct exynos_drm_plane_config *config) | 298 | const struct exynos_drm_plane_config *config) |
299 | { | 299 | { |
300 | int err; | 300 | int err; |
301 | unsigned int supported_modes = BIT(DRM_MODE_BLEND_PIXEL_NONE) | | ||
302 | BIT(DRM_MODE_BLEND_PREMULTI) | | ||
303 | BIT(DRM_MODE_BLEND_COVERAGE); | ||
304 | struct drm_plane *plane = &exynos_plane->base; | ||
301 | 305 | ||
302 | err = drm_universal_plane_init(dev, &exynos_plane->base, | 306 | err = drm_universal_plane_init(dev, &exynos_plane->base, |
303 | 1 << dev->mode_config.num_crtc, | 307 | 1 << dev->mode_config.num_crtc, |
@@ -318,5 +322,8 @@ int exynos_plane_init(struct drm_device *dev, | |||
318 | exynos_plane_attach_zpos_property(&exynos_plane->base, config->zpos, | 322 | exynos_plane_attach_zpos_property(&exynos_plane->base, config->zpos, |
319 | !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS)); | 323 | !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS)); |
320 | 324 | ||
325 | if (config->capabilities & EXYNOS_DRM_PLANE_CAP_PIX_BLEND) | ||
326 | drm_plane_create_blend_mode_property(plane, supported_modes); | ||
327 | |||
321 | return 0; | 328 | return 0; |
322 | } | 329 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index ffbf4a950f69..721b63e92b28 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -131,14 +131,16 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = { | |||
131 | .pixel_formats = mixer_formats, | 131 | .pixel_formats = mixer_formats, |
132 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), | 132 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), |
133 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | | 133 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | |
134 | EXYNOS_DRM_PLANE_CAP_ZPOS, | 134 | EXYNOS_DRM_PLANE_CAP_ZPOS | |
135 | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, | ||
135 | }, { | 136 | }, { |
136 | .zpos = 1, | 137 | .zpos = 1, |
137 | .type = DRM_PLANE_TYPE_CURSOR, | 138 | .type = DRM_PLANE_TYPE_CURSOR, |
138 | .pixel_formats = mixer_formats, | 139 | .pixel_formats = mixer_formats, |
139 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), | 140 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), |
140 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | | 141 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | |
141 | EXYNOS_DRM_PLANE_CAP_ZPOS, | 142 | EXYNOS_DRM_PLANE_CAP_ZPOS | |
143 | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, | ||
142 | }, { | 144 | }, { |
143 | .zpos = 2, | 145 | .zpos = 2, |
144 | .type = DRM_PLANE_TYPE_OVERLAY, | 146 | .type = DRM_PLANE_TYPE_OVERLAY, |
@@ -309,15 +311,22 @@ static void vp_default_filter(struct mixer_context *ctx) | |||
309 | } | 311 | } |
310 | 312 | ||
311 | static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win, | 313 | static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win, |
312 | bool alpha) | 314 | unsigned int pixel_alpha) |
313 | { | 315 | { |
314 | u32 val; | 316 | u32 val; |
315 | 317 | ||
316 | val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ | 318 | val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ |
317 | if (alpha) { | 319 | switch (pixel_alpha) { |
318 | /* blending based on pixel alpha */ | 320 | case DRM_MODE_BLEND_PIXEL_NONE: |
321 | break; | ||
322 | case DRM_MODE_BLEND_COVERAGE: | ||
323 | val |= MXR_GRP_CFG_PIXEL_BLEND_EN; | ||
324 | break; | ||
325 | case DRM_MODE_BLEND_PREMULTI: | ||
326 | default: | ||
319 | val |= MXR_GRP_CFG_BLEND_PRE_MUL; | 327 | val |= MXR_GRP_CFG_BLEND_PRE_MUL; |
320 | val |= MXR_GRP_CFG_PIXEL_BLEND_EN; | 328 | val |= MXR_GRP_CFG_PIXEL_BLEND_EN; |
329 | break; | ||
321 | } | 330 | } |
322 | mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win), | 331 | mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win), |
323 | val, MXR_GRP_CFG_MISC_MASK); | 332 | val, MXR_GRP_CFG_MISC_MASK); |
@@ -553,10 +562,16 @@ static void mixer_graph_buffer(struct mixer_context *ctx, | |||
553 | unsigned int win = plane->index; | 562 | unsigned int win = plane->index; |
554 | unsigned int x_ratio = 0, y_ratio = 0; | 563 | unsigned int x_ratio = 0, y_ratio = 0; |
555 | unsigned int dst_x_offset, dst_y_offset; | 564 | unsigned int dst_x_offset, dst_y_offset; |
565 | unsigned int pixel_alpha; | ||
556 | dma_addr_t dma_addr; | 566 | dma_addr_t dma_addr; |
557 | unsigned int fmt; | 567 | unsigned int fmt; |
558 | u32 val; | 568 | u32 val; |
559 | 569 | ||
570 | if (fb->format->has_alpha) | ||
571 | pixel_alpha = state->base.pixel_blend_mode; | ||
572 | else | ||
573 | pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE; | ||
574 | |||
560 | switch (fb->format->format) { | 575 | switch (fb->format->format) { |
561 | case DRM_FORMAT_XRGB4444: | 576 | case DRM_FORMAT_XRGB4444: |
562 | case DRM_FORMAT_ARGB4444: | 577 | case DRM_FORMAT_ARGB4444: |
@@ -616,7 +631,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx, | |||
616 | mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr); | 631 | mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr); |
617 | 632 | ||
618 | mixer_cfg_layer(ctx, win, priority, true); | 633 | mixer_cfg_layer(ctx, win, priority, true); |
619 | mixer_cfg_gfx_blend(ctx, win, fb->format->has_alpha); | 634 | mixer_cfg_gfx_blend(ctx, win, pixel_alpha); |
620 | 635 | ||
621 | /* layer update mandatory for mixer 16.0.33.0 */ | 636 | /* layer update mandatory for mixer 16.0.33.0 */ |
622 | if (ctx->mxr_ver == MXR_VER_16_0_33_0 || | 637 | if (ctx->mxr_ver == MXR_VER_16_0_33_0 || |