summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChristoph Manszewski <c.manszewski@samsung.com>2018-10-25 17:23:50 +0200
committerInki Dae <inki.dae@samsung.com>2018-12-14 15:46:15 +0900
commit3b5129b3a7c62fdec9cc69b1b3f20917c36ab5d4 (patch)
tree8ac5e2d5abe20f662083306408f45874e890cf44 /drivers/gpu/drm
parent6f8ee5c21722f93d486b2ff041c28580c9511349 (diff)
drm/exynos: fimd: Make pixel blend mode configurable
The fimd hardware supports different blend modes. Add pixel blend mode property and make it configurable, by modifying the blend equation. Tested on TRATS2 with Exynos 4412 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')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 8df6a18fd50b..786a8ee6f10f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -230,10 +230,10 @@ static const uint32_t fimd_formats[] = {
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,
+ EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
+ EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
+ EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
+ EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
};
static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask,
@@ -566,13 +566,52 @@ static void fimd_commit(struct exynos_drm_crtc *crtc)
writel(val, ctx->regs + VIDCON0);
}
+static void fimd_win_set_bldeq(struct fimd_context *ctx, unsigned int win,
+ unsigned int alpha, unsigned int pixel_alpha)
+{
+ u32 mask = BLENDEQ_A_FUNC_F(0xf) | BLENDEQ_B_FUNC_F(0xf);
+ u32 val = 0;
+
+ switch (pixel_alpha) {
+ case DRM_MODE_BLEND_PIXEL_NONE:
+ case DRM_MODE_BLEND_COVERAGE:
+ val |= BLENDEQ_A_FUNC_F(BLENDEQ_ALPHA_A);
+ val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
+ break;
+ case DRM_MODE_BLEND_PREMULTI:
+ default:
+ if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
+ val |= BLENDEQ_A_FUNC_F(BLENDEQ_ALPHA0);
+ val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
+ } else {
+ val |= BLENDEQ_A_FUNC_F(BLENDEQ_ONE);
+ val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
+ }
+ break;
+ }
+ fimd_set_bits(ctx, BLENDEQx(win), mask, val);
+}
+
static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win,
- unsigned int alpha)
+ unsigned int alpha, unsigned int pixel_alpha)
{
u32 win_alpha_l = (alpha >> 8) & 0xf;
u32 win_alpha_h = alpha >> 12;
u32 val = 0;
+ switch (pixel_alpha) {
+ case DRM_MODE_BLEND_PIXEL_NONE:
+ break;
+ case DRM_MODE_BLEND_COVERAGE:
+ case DRM_MODE_BLEND_PREMULTI:
+ default:
+ val |= WINCON1_ALPHA_SEL;
+ val |= WINCON1_BLD_PIX;
+ val |= WINCON1_ALPHA_MUL;
+ break;
+ }
+ fimd_set_bits(ctx, WINCON(win), WINCONx_BLEND_MODE_MASK, val);
+
/* OSD alpha */
val = VIDISD14C_ALPHA0_R(win_alpha_h) |
VIDISD14C_ALPHA0_G(win_alpha_h) |
@@ -603,6 +642,12 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
uint32_t pixel_format = fb->format->format;
unsigned int alpha = state->base.alpha;
u32 val = WINCONx_ENWIN;
+ unsigned int pixel_alpha;
+
+ if (fb->format->has_alpha)
+ pixel_alpha = state->base.pixel_blend_mode;
+ else
+ pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE;
/*
* In case of s3c64xx, window 0 doesn't support alpha channel.
@@ -636,11 +681,9 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
break;
case DRM_FORMAT_ARGB8888:
default:
- val |= WINCON1_BPPMODE_25BPP_A1888
- | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
+ val |= WINCON1_BPPMODE_25BPP_A1888;
val |= WINCONx_WSWP;
val |= WINCONx_BURSTLEN_16WORD;
- val |= WINCON1_ALPHA_MUL;
break;
}
@@ -656,12 +699,13 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
val &= ~WINCONx_BURSTLEN_MASK;
val |= WINCONx_BURSTLEN_4WORD;
}
-
- writel(val, ctx->regs + WINCON(win));
+ fimd_set_bits(ctx, WINCON(win), ~WINCONx_BLEND_MODE_MASK, val);
/* hardware window 0 doesn't support alpha channel. */
- if (win != 0)
- fimd_win_set_bldmod(ctx, win, alpha);
+ if (win != 0) {
+ fimd_win_set_bldmod(ctx, win, alpha, pixel_alpha);
+ fimd_win_set_bldeq(ctx, win, alpha, pixel_alpha);
+ }
}
static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win)