Commit 6ac99a32 authored by Christoph Manszewski's avatar Christoph Manszewski Committed by Inki Dae

drm/exynos: mixer: Make plane alpha configurable

The mixer hardware supports variable plane alpha. Currently planes are
opaque, make this configurable.

Tested on Odroid-U3 with Exynos 4412 CPU, kernel next-20180913
using modetest.
Signed-off-by: default avatarChristoph Manszewski <c.manszewski@samsung.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 482582c0
...@@ -93,6 +93,7 @@ struct exynos_drm_plane { ...@@ -93,6 +93,7 @@ struct exynos_drm_plane {
#define EXYNOS_DRM_PLANE_CAP_ZPOS (1 << 2) #define EXYNOS_DRM_PLANE_CAP_ZPOS (1 << 2)
#define EXYNOS_DRM_PLANE_CAP_TILE (1 << 3) #define EXYNOS_DRM_PLANE_CAP_TILE (1 << 3)
#define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4) #define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4)
#define EXYNOS_DRM_PLANE_CAP_WIN_BLEND (1 << 5)
/* /*
* Exynos DRM plane configuration structure. * Exynos DRM plane configuration structure.
......
...@@ -325,5 +325,8 @@ int exynos_plane_init(struct drm_device *dev, ...@@ -325,5 +325,8 @@ int exynos_plane_init(struct drm_device *dev,
if (config->capabilities & EXYNOS_DRM_PLANE_CAP_PIX_BLEND) if (config->capabilities & EXYNOS_DRM_PLANE_CAP_PIX_BLEND)
drm_plane_create_blend_mode_property(plane, supported_modes); drm_plane_create_blend_mode_property(plane, supported_modes);
if (config->capabilities & EXYNOS_DRM_PLANE_CAP_WIN_BLEND)
drm_plane_create_alpha_property(plane);
return 0; return 0;
} }
...@@ -132,7 +132,8 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = { ...@@ -132,7 +132,8 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
.num_pixel_formats = ARRAY_SIZE(mixer_formats), .num_pixel_formats = ARRAY_SIZE(mixer_formats),
.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE |
EXYNOS_DRM_PLANE_CAP_ZPOS | EXYNOS_DRM_PLANE_CAP_ZPOS |
EXYNOS_DRM_PLANE_CAP_PIX_BLEND, EXYNOS_DRM_PLANE_CAP_PIX_BLEND |
EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
}, { }, {
.zpos = 1, .zpos = 1,
.type = DRM_PLANE_TYPE_CURSOR, .type = DRM_PLANE_TYPE_CURSOR,
...@@ -140,7 +141,8 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = { ...@@ -140,7 +141,8 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
.num_pixel_formats = ARRAY_SIZE(mixer_formats), .num_pixel_formats = ARRAY_SIZE(mixer_formats),
.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE |
EXYNOS_DRM_PLANE_CAP_ZPOS | EXYNOS_DRM_PLANE_CAP_ZPOS |
EXYNOS_DRM_PLANE_CAP_PIX_BLEND, EXYNOS_DRM_PLANE_CAP_PIX_BLEND |
EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
}, { }, {
.zpos = 2, .zpos = 2,
.type = DRM_PLANE_TYPE_OVERLAY, .type = DRM_PLANE_TYPE_OVERLAY,
...@@ -148,7 +150,8 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = { ...@@ -148,7 +150,8 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
.num_pixel_formats = ARRAY_SIZE(vp_formats), .num_pixel_formats = ARRAY_SIZE(vp_formats),
.capabilities = EXYNOS_DRM_PLANE_CAP_SCALE | .capabilities = EXYNOS_DRM_PLANE_CAP_SCALE |
EXYNOS_DRM_PLANE_CAP_ZPOS | EXYNOS_DRM_PLANE_CAP_ZPOS |
EXYNOS_DRM_PLANE_CAP_TILE, EXYNOS_DRM_PLANE_CAP_TILE |
EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
}, },
}; };
...@@ -311,8 +314,9 @@ static void vp_default_filter(struct mixer_context *ctx) ...@@ -311,8 +314,9 @@ static void vp_default_filter(struct mixer_context *ctx)
} }
static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win, static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
unsigned int pixel_alpha) unsigned int pixel_alpha, unsigned int alpha)
{ {
u32 win_alpha = alpha >> 8;
u32 val; u32 val;
val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
...@@ -328,21 +332,24 @@ static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win, ...@@ -328,21 +332,24 @@ static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
val |= MXR_GRP_CFG_PIXEL_BLEND_EN; val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
break; break;
} }
if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
val |= MXR_GRP_CFG_WIN_BLEND_EN;
val |= win_alpha;
}
mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win), mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win),
val, MXR_GRP_CFG_MISC_MASK); val, MXR_GRP_CFG_MISC_MASK);
} }
static void mixer_cfg_vp_blend(struct mixer_context *ctx) static void mixer_cfg_vp_blend(struct mixer_context *ctx, unsigned int alpha)
{ {
u32 val; u32 win_alpha = alpha >> 8;
u32 val = 0;
/* if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
* No blending at the moment since the NV12/NV21 pixelformats don't val |= MXR_VID_CFG_BLEND_EN;
* have an alpha channel. However the mixer supports a global alpha val |= win_alpha;
* value for a layer. Once this functionality is exposed, we can }
* support blending of the video layer through this.
*/
val = 0;
mixer_reg_write(ctx, MXR_VIDEO_CFG, val); mixer_reg_write(ctx, MXR_VIDEO_CFG, val);
} }
...@@ -538,7 +545,7 @@ static void vp_video_buffer(struct mixer_context *ctx, ...@@ -538,7 +545,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
vp_reg_write(ctx, VP_BOT_C_PTR, chroma_addr[1]); vp_reg_write(ctx, VP_BOT_C_PTR, chroma_addr[1]);
mixer_cfg_layer(ctx, plane->index, priority, true); mixer_cfg_layer(ctx, plane->index, priority, true);
mixer_cfg_vp_blend(ctx); mixer_cfg_vp_blend(ctx, state->base.alpha);
spin_unlock_irqrestore(&ctx->reg_slock, flags); spin_unlock_irqrestore(&ctx->reg_slock, flags);
...@@ -631,7 +638,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx, ...@@ -631,7 +638,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr); mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr);
mixer_cfg_layer(ctx, win, priority, true); mixer_cfg_layer(ctx, win, priority, true);
mixer_cfg_gfx_blend(ctx, win, pixel_alpha); mixer_cfg_gfx_blend(ctx, win, pixel_alpha, state->base.alpha);
/* layer update mandatory for mixer 16.0.33.0 */ /* layer update mandatory for mixer 16.0.33.0 */
if (ctx->mxr_ver == MXR_VER_16_0_33_0 || if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
......
...@@ -109,12 +109,15 @@ ...@@ -109,12 +109,15 @@
#define MXR_CFG_SCAN_HD (1 << 0) #define MXR_CFG_SCAN_HD (1 << 0)
#define MXR_CFG_SCAN_MASK 0x47 #define MXR_CFG_SCAN_MASK 0x47
/* bits for MXR_VIDEO_CFG */
#define MXR_VID_CFG_BLEND_EN (1 << 16)
/* bits for MXR_GRAPHICn_CFG */ /* bits for MXR_GRAPHICn_CFG */
#define MXR_GRP_CFG_COLOR_KEY_DISABLE (1 << 21) #define MXR_GRP_CFG_COLOR_KEY_DISABLE (1 << 21)
#define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20) #define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20)
#define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17) #define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17)
#define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16) #define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16)
#define MXR_GRP_CFG_MISC_MASK ((3 << 16) | (3 << 20)) #define MXR_GRP_CFG_MISC_MASK ((3 << 16) | (3 << 20) | 0xff)
#define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8) #define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8)
#define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0) #define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0)
#define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0) #define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment