diff options
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 68 | ||||
| -rw-r--r-- | include/video/samsung_fimd.h | 9 |
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 | ||
| 231 | static const unsigned int capabilities[WINDOWS_NR] = { | 231 | static 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 | ||
| 239 | static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask, | 239 | 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) | |||
| 566 | writel(val, ctx->regs + VIDCON0); | 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 | static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win, | 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 | 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 | ||
| 667 | static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win) | 711 | static 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) |
