aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Manszewski <c.manszewski@samsung.com>2018-10-25 11:23:50 -0400
committerInki Dae <inki.dae@samsung.com>2018-12-14 01:46:15 -0500
commit3b5129b3a7c62fdec9cc69b1b3f20917c36ab5d4 (patch)
tree8ac5e2d5abe20f662083306408f45874e890cf44
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>
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c68
-rw-r--r--include/video/samsung_fimd.h9
2 files changed, 65 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[] = {
230 230
231static const unsigned int capabilities[WINDOWS_NR] = { 231static const unsigned int capabilities[WINDOWS_NR] = {
232 0, 232 0,
233 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 233 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
234 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 234 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
235 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 235 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
236 EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 236 EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
237}; 237};
238 238
239static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask, 239static 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)
566 writel(val, ctx->regs + VIDCON0); 566 writel(val, ctx->regs + VIDCON0);
567} 567}
568 568
569static void fimd_win_set_bldeq(struct fimd_context *ctx, unsigned int win,
570 unsigned int alpha, unsigned int pixel_alpha)
571{
572 u32 mask = BLENDEQ_A_FUNC_F(0xf) | BLENDEQ_B_FUNC_F(0xf);
573 u32 val = 0;
574
575 switch (pixel_alpha) {
576 case DRM_MODE_BLEND_PIXEL_NONE:
577 case DRM_MODE_BLEND_COVERAGE:
578 val |= BLENDEQ_A_FUNC_F(BLENDEQ_ALPHA_A);
579 val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
580 break;
581 case DRM_MODE_BLEND_PREMULTI:
582 default:
583 if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
584 val |= BLENDEQ_A_FUNC_F(BLENDEQ_ALPHA0);
585 val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
586 } else {
587 val |= BLENDEQ_A_FUNC_F(BLENDEQ_ONE);
588 val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
589 }
590 break;
591 }
592 fimd_set_bits(ctx, BLENDEQx(win), mask, val);
593}
594
569static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win, 595static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win,
570 unsigned int alpha) 596 unsigned int alpha, unsigned int pixel_alpha)
571{ 597{
572 u32 win_alpha_l = (alpha >> 8) & 0xf; 598 u32 win_alpha_l = (alpha >> 8) & 0xf;
573 u32 win_alpha_h = alpha >> 12; 599 u32 win_alpha_h = alpha >> 12;
574 u32 val = 0; 600 u32 val = 0;
575 601
602 switch (pixel_alpha) {
603 case DRM_MODE_BLEND_PIXEL_NONE:
604 break;
605 case DRM_MODE_BLEND_COVERAGE:
606 case DRM_MODE_BLEND_PREMULTI:
607 default:
608 val |= WINCON1_ALPHA_SEL;
609 val |= WINCON1_BLD_PIX;
610 val |= WINCON1_ALPHA_MUL;
611 break;
612 }
613 fimd_set_bits(ctx, WINCON(win), WINCONx_BLEND_MODE_MASK, val);
614
576 /* OSD alpha */ 615 /* OSD alpha */
577 val = VIDISD14C_ALPHA0_R(win_alpha_h) | 616 val = VIDISD14C_ALPHA0_R(win_alpha_h) |
578 VIDISD14C_ALPHA0_G(win_alpha_h) | 617 VIDISD14C_ALPHA0_G(win_alpha_h) |
@@ -603,6 +642,12 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
603 uint32_t pixel_format = fb->format->format; 642 uint32_t pixel_format = fb->format->format;
604 unsigned int alpha = state->base.alpha; 643 unsigned int alpha = state->base.alpha;
605 u32 val = WINCONx_ENWIN; 644 u32 val = WINCONx_ENWIN;
645 unsigned int pixel_alpha;
646
647 if (fb->format->has_alpha)
648 pixel_alpha = state->base.pixel_blend_mode;
649 else
650 pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE;
606 651
607 /* 652 /*
608 * In case of s3c64xx, window 0 doesn't support alpha channel. 653 * 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,
636 break; 681 break;
637 case DRM_FORMAT_ARGB8888: 682 case DRM_FORMAT_ARGB8888:
638 default: 683 default:
639 val |= WINCON1_BPPMODE_25BPP_A1888 684 val |= WINCON1_BPPMODE_25BPP_A1888;
640 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
641 val |= WINCONx_WSWP; 685 val |= WINCONx_WSWP;
642 val |= WINCONx_BURSTLEN_16WORD; 686 val |= WINCONx_BURSTLEN_16WORD;
643 val |= WINCON1_ALPHA_MUL;
644 break; 687 break;
645 } 688 }
646 689
@@ -656,12 +699,13 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
656 val &= ~WINCONx_BURSTLEN_MASK; 699 val &= ~WINCONx_BURSTLEN_MASK;
657 val |= WINCONx_BURSTLEN_4WORD; 700 val |= WINCONx_BURSTLEN_4WORD;
658 } 701 }
659 702 fimd_set_bits(ctx, WINCON(win), ~WINCONx_BLEND_MODE_MASK, val);
660 writel(val, ctx->regs + WINCON(win));
661 703
662 /* hardware window 0 doesn't support alpha channel. */ 704 /* hardware window 0 doesn't support alpha channel. */
663 if (win != 0) 705 if (win != 0) {
664 fimd_win_set_bldmod(ctx, win, alpha); 706 fimd_win_set_bldmod(ctx, win, alpha, pixel_alpha);
707 fimd_win_set_bldeq(ctx, win, alpha, pixel_alpha);
708 }
665} 709}
666 710
667static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win) 711static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win)
diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
index f070b7c0d2cf..4ba5efe8d086 100644
--- a/include/video/samsung_fimd.h
+++ b/include/video/samsung_fimd.h
@@ -198,6 +198,7 @@
198#define WINCONx_BURSTLEN_8WORD (0x1 << 9) 198#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
199#define WINCONx_BURSTLEN_4WORD (0x2 << 9) 199#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
200#define WINCONx_ENWIN (1 << 0) 200#define WINCONx_ENWIN (1 << 0)
201#define WINCONx_BLEND_MODE_MASK (0xc2)
201 202
202#define WINCON0_BPPMODE_MASK (0xf << 2) 203#define WINCON0_BPPMODE_MASK (0xf << 2)
203#define WINCON0_BPPMODE_SHIFT 2 204#define WINCON0_BPPMODE_SHIFT 2
@@ -438,6 +439,14 @@
438#define WPALCON_W0PAL_16BPP_565 (0x6 << 0) 439#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
439 440
440/* Blending equation control */ 441/* Blending equation control */
442#define BLENDEQx(_win) (0x244 + ((_win - 1) * 4))
443#define BLENDEQ_ZERO 0x0
444#define BLENDEQ_ONE 0x1
445#define BLENDEQ_ALPHA_A 0x2
446#define BLENDEQ_ONE_MINUS_ALPHA_A 0x3
447#define BLENDEQ_ALPHA0 0x6
448#define BLENDEQ_B_FUNC_F(_x) (_x << 6)
449#define BLENDEQ_A_FUNC_F(_x) (_x << 0)
441#define BLENDCON 0x260 450#define BLENDCON 0x260
442#define BLENDCON_NEW_MASK (1 << 0) 451#define BLENDCON_NEW_MASK (1 << 0)
443#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0) 452#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)