Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Christoph Manszewski and committed by
Inki Dae
3b5129b3 6f8ee5c2

+65 -12
+56 -12
drivers/gpu/drm/exynos/exynos_drm_fimd.c
··· 230 230 231 231 static const unsigned int capabilities[WINDOWS_NR] = { 232 232 0, 233 - EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 234 - EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 235 - EXYNOS_DRM_PLANE_CAP_WIN_BLEND, 236 - 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 | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, 235 + EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, 236 + EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, 237 237 }; 238 238 239 239 static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask, ··· 566 566 writel(val, ctx->regs + VIDCON0); 567 567 } 568 568 569 + static 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 + 569 595 static 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 598 u32 win_alpha_l = (alpha >> 8) & 0xf; 573 599 u32 win_alpha_h = alpha >> 12; 574 600 u32 val = 0; 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); 575 614 576 615 /* OSD alpha */ 577 616 val = VIDISD14C_ALPHA0_R(win_alpha_h) | ··· 642 603 uint32_t pixel_format = fb->format->format; 643 604 unsigned int alpha = state->base.alpha; 644 605 u32 val = WINCONx_ENWIN; 606 + unsigned int pixel_alpha; 607 + 608 + if (fb->format->has_alpha) 609 + pixel_alpha = state->base.pixel_blend_mode; 610 + else 611 + pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE; 645 612 646 613 /* 647 614 * In case of s3c64xx, window 0 doesn't support alpha channel. ··· 681 636 break; 682 637 case DRM_FORMAT_ARGB8888: 683 638 default: 684 - val |= WINCON1_BPPMODE_25BPP_A1888 685 - | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; 639 + val |= WINCON1_BPPMODE_25BPP_A1888; 686 640 val |= WINCONx_WSWP; 687 641 val |= WINCONx_BURSTLEN_16WORD; 688 - val |= WINCON1_ALPHA_MUL; 689 642 break; 690 643 } 691 644 ··· 699 656 val &= ~WINCONx_BURSTLEN_MASK; 700 657 val |= WINCONx_BURSTLEN_4WORD; 701 658 } 702 - 703 - writel(val, ctx->regs + WINCON(win)); 659 + fimd_set_bits(ctx, WINCON(win), ~WINCONx_BLEND_MODE_MASK, val); 704 660 705 661 /* hardware window 0 doesn't support alpha channel. */ 706 - if (win != 0) 707 - fimd_win_set_bldmod(ctx, win, alpha); 662 + if (win != 0) { 663 + fimd_win_set_bldmod(ctx, win, alpha, pixel_alpha); 664 + fimd_win_set_bldeq(ctx, win, alpha, pixel_alpha); 665 + } 708 666 } 709 667 710 668 static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win)
+9
include/video/samsung_fimd.h
··· 198 198 #define WINCONx_BURSTLEN_8WORD (0x1 << 9) 199 199 #define WINCONx_BURSTLEN_4WORD (0x2 << 9) 200 200 #define WINCONx_ENWIN (1 << 0) 201 + #define WINCONx_BLEND_MODE_MASK (0xc2) 201 202 202 203 #define WINCON0_BPPMODE_MASK (0xf << 2) 203 204 #define WINCON0_BPPMODE_SHIFT 2 ··· 439 438 #define WPALCON_W0PAL_16BPP_565 (0x6 << 0) 440 439 441 440 /* Blending equation control */ 441 + #define BLENDEQx(_win) (0x244 + ((_win - 1) * 4)) 442 + #define BLENDEQ_ZERO 0x0 443 + #define BLENDEQ_ONE 0x1 444 + #define BLENDEQ_ALPHA_A 0x2 445 + #define BLENDEQ_ONE_MINUS_ALPHA_A 0x3 446 + #define BLENDEQ_ALPHA0 0x6 447 + #define BLENDEQ_B_FUNC_F(_x) (_x << 6) 448 + #define BLENDEQ_A_FUNC_F(_x) (_x << 0) 442 449 #define BLENDCON 0x260 443 450 #define BLENDCON_NEW_MASK (1 << 0) 444 451 #define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)