Commit 272c1a9b authored by Daniel Vetter's avatar Daniel Vetter

Merge tag 'exynos-drm-next-for-v4.21-v2' of...

Merge tag 'exynos-drm-next-for-v4.21-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

Add configurable plane alpha and pixel blend mode support
- This patch series adds configurable plane alpha and pixel blend mode
  support for FIMD device driver.
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Inki Dae <inki.dae@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1544772430-8295-1-git-send-email-inki.dae@samsung.com
parents 2a3c83f5 3b5129b3
......@@ -228,6 +228,21 @@ static const uint32_t fimd_formats[] = {
DRM_FORMAT_ARGB8888,
};
static const unsigned int capabilities[WINDOWS_NR] = {
0,
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,
u32 val)
{
val = (val & mask) | (readl(ctx->regs + reg) & ~mask);
writel(val, ctx->regs + reg);
}
static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
{
struct fimd_context *ctx = crtc->ctx;
......@@ -551,13 +566,88 @@ 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_pixfmt(struct fimd_context *ctx, unsigned int win,
uint32_t pixel_format, int width)
static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win,
unsigned int alpha, unsigned int pixel_alpha)
{
unsigned long val;
u32 win_alpha_l = (alpha >> 8) & 0xf;
u32 win_alpha_h = alpha >> 12;
u32 val = 0;
val = WINCONx_ENWIN;
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) |
VIDISD14C_ALPHA0_B(win_alpha_h) |
VIDISD14C_ALPHA1_R(0x0) |
VIDISD14C_ALPHA1_G(0x0) |
VIDISD14C_ALPHA1_B(0x0);
writel(val, ctx->regs + VIDOSD_C(win));
val = VIDW_ALPHA_R(win_alpha_l) | VIDW_ALPHA_G(win_alpha_l) |
VIDW_ALPHA_B(win_alpha_l);
writel(val, ctx->regs + VIDWnALPHA0(win));
val = VIDW_ALPHA_R(0x0) | VIDW_ALPHA_G(0x0) |
VIDW_ALPHA_B(0x0);
writel(val, ctx->regs + VIDWnALPHA1(win));
fimd_set_bits(ctx, BLENDCON, BLENDCON_NEW_MASK,
BLENDCON_NEW_8BIT_ALPHA_VALUE);
}
static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
struct drm_framebuffer *fb, int width)
{
struct exynos_drm_plane plane = ctx->planes[win];
struct exynos_drm_plane_state *state =
to_exynos_plane_state(plane.base.state);
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.
......@@ -591,8 +681,7 @@ 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;
break;
......@@ -610,25 +699,12 @@ 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) {
/* OSD alpha */
val = VIDISD14C_ALPHA0_R(0xf) |
VIDISD14C_ALPHA0_G(0xf) |
VIDISD14C_ALPHA0_B(0xf) |
VIDISD14C_ALPHA1_R(0xf) |
VIDISD14C_ALPHA1_G(0xf) |
VIDISD14C_ALPHA1_B(0xf);
writel(val, ctx->regs + VIDOSD_C(win));
val = VIDW_ALPHA_R(0xf) | VIDW_ALPHA_G(0xf) |
VIDW_ALPHA_G(0xf);
writel(val, ctx->regs + VIDWnALPHA0(win));
writel(val, ctx->regs + VIDWnALPHA1(win));
fimd_win_set_bldmod(ctx, win, alpha, pixel_alpha);
fimd_win_set_bldeq(ctx, win, alpha, pixel_alpha);
}
}
......@@ -785,7 +861,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
}
fimd_win_set_pixfmt(ctx, win, fb->format->format, state->src.w);
fimd_win_set_pixfmt(ctx, win, fb, state->src.w);
/* hardware window 0 doesn't support color key. */
if (win != 0)
......@@ -987,6 +1063,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
ctx->configs[i].zpos = i;
ctx->configs[i].type = fimd_win_types[i];
ctx->configs[i].capabilities = capabilities[i];
ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
&ctx->configs[i]);
if (ret)
......
......@@ -198,6 +198,7 @@
#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
#define WINCONx_ENWIN (1 << 0)
#define WINCONx_BLEND_MODE_MASK (0xc2)
#define WINCON0_BPPMODE_MASK (0xf << 2)
#define WINCON0_BPPMODE_SHIFT 2
......@@ -211,6 +212,7 @@
#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
#define WINCON1_LOCALSEL_CAMIF (1 << 23)
#define WINCON1_ALPHA_MUL (1 << 7)
#define WINCON1_BLD_PIX (1 << 6)
#define WINCON1_BPPMODE_MASK (0xf << 2)
#define WINCON1_BPPMODE_SHIFT 2
......@@ -437,6 +439,14 @@
#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
/* Blending equation control */
#define BLENDEQx(_win) (0x244 + ((_win - 1) * 4))
#define BLENDEQ_ZERO 0x0
#define BLENDEQ_ONE 0x1
#define BLENDEQ_ALPHA_A 0x2
#define BLENDEQ_ONE_MINUS_ALPHA_A 0x3
#define BLENDEQ_ALPHA0 0x6
#define BLENDEQ_B_FUNC_F(_x) (_x << 6)
#define BLENDEQ_A_FUNC_F(_x) (_x << 0)
#define BLENDCON 0x260
#define BLENDCON_NEW_MASK (1 << 0)
#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 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