diff options
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 123 | ||||
| -rw-r--r-- | include/video/samsung_fimd.h | 10 |
2 files changed, 110 insertions, 23 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index e3d6a8584715..786a8ee6f10f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
| @@ -228,6 +228,21 @@ static const uint32_t fimd_formats[] = { | |||
| 228 | DRM_FORMAT_ARGB8888, | 228 | DRM_FORMAT_ARGB8888, |
| 229 | }; | 229 | }; |
| 230 | 230 | ||
| 231 | static const unsigned int capabilities[WINDOWS_NR] = { | ||
| 232 | 0, | ||
| 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 | }; | ||
| 238 | |||
| 239 | static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask, | ||
| 240 | u32 val) | ||
| 241 | { | ||
| 242 | val = (val & mask) | (readl(ctx->regs + reg) & ~mask); | ||
| 243 | writel(val, ctx->regs + reg); | ||
| 244 | } | ||
| 245 | |||
| 231 | static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) | 246 | static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) |
| 232 | { | 247 | { |
| 233 | struct fimd_context *ctx = crtc->ctx; | 248 | struct fimd_context *ctx = crtc->ctx; |
| @@ -551,13 +566,88 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) | |||
| 551 | writel(val, ctx->regs + VIDCON0); | 566 | writel(val, ctx->regs + VIDCON0); |
| 552 | } | 567 | } |
| 553 | 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 | } | ||
| 554 | 594 | ||
| 555 | static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, | 595 | static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win, |
| 556 | uint32_t pixel_format, int width) | 596 | unsigned int alpha, unsigned int pixel_alpha) |
| 557 | { | 597 | { |
| 558 | unsigned long val; | 598 | u32 win_alpha_l = (alpha >> 8) & 0xf; |
| 599 | u32 win_alpha_h = alpha >> 12; | ||
| 600 | u32 val = 0; | ||
| 559 | 601 | ||
| 560 | val = WINCONx_ENWIN; | 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 | |||
| 615 | /* OSD alpha */ | ||
| 616 | val = VIDISD14C_ALPHA0_R(win_alpha_h) | | ||
| 617 | VIDISD14C_ALPHA0_G(win_alpha_h) | | ||
| 618 | VIDISD14C_ALPHA0_B(win_alpha_h) | | ||
| 619 | VIDISD14C_ALPHA1_R(0x0) | | ||
| 620 | VIDISD14C_ALPHA1_G(0x0) | | ||
| 621 | VIDISD14C_ALPHA1_B(0x0); | ||
| 622 | writel(val, ctx->regs + VIDOSD_C(win)); | ||
| 623 | |||
| 624 | val = VIDW_ALPHA_R(win_alpha_l) | VIDW_ALPHA_G(win_alpha_l) | | ||
| 625 | VIDW_ALPHA_B(win_alpha_l); | ||
| 626 | writel(val, ctx->regs + VIDWnALPHA0(win)); | ||
| 627 | |||
| 628 | val = VIDW_ALPHA_R(0x0) | VIDW_ALPHA_G(0x0) | | ||
| 629 | VIDW_ALPHA_B(0x0); | ||
| 630 | writel(val, ctx->regs + VIDWnALPHA1(win)); | ||
| 631 | |||
| 632 | fimd_set_bits(ctx, BLENDCON, BLENDCON_NEW_MASK, | ||
| 633 | BLENDCON_NEW_8BIT_ALPHA_VALUE); | ||
| 634 | } | ||
| 635 | |||
| 636 | static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, | ||
| 637 | struct drm_framebuffer *fb, int width) | ||
| 638 | { | ||
| 639 | struct exynos_drm_plane plane = ctx->planes[win]; | ||
| 640 | struct exynos_drm_plane_state *state = | ||
| 641 | to_exynos_plane_state(plane.base.state); | ||
| 642 | uint32_t pixel_format = fb->format->format; | ||
| 643 | unsigned int alpha = state->base.alpha; | ||
| 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; | ||
| 561 | 651 | ||
| 562 | /* | 652 | /* |
| 563 | * In case of s3c64xx, window 0 doesn't support alpha channel. | 653 | * 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, | |||
| 591 | break; | 681 | break; |
| 592 | case DRM_FORMAT_ARGB8888: | 682 | case DRM_FORMAT_ARGB8888: |
| 593 | default: | 683 | default: |
| 594 | val |= WINCON1_BPPMODE_25BPP_A1888 | 684 | val |= WINCON1_BPPMODE_25BPP_A1888; |
| 595 | | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; | ||
| 596 | val |= WINCONx_WSWP; | 685 | val |= WINCONx_WSWP; |
| 597 | val |= WINCONx_BURSTLEN_16WORD; | 686 | val |= WINCONx_BURSTLEN_16WORD; |
| 598 | break; | 687 | break; |
| @@ -610,25 +699,12 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, | |||
| 610 | val &= ~WINCONx_BURSTLEN_MASK; | 699 | val &= ~WINCONx_BURSTLEN_MASK; |
| 611 | val |= WINCONx_BURSTLEN_4WORD; | 700 | val |= WINCONx_BURSTLEN_4WORD; |
| 612 | } | 701 | } |
| 613 | 702 | fimd_set_bits(ctx, WINCON(win), ~WINCONx_BLEND_MODE_MASK, val); | |
| 614 | writel(val, ctx->regs + WINCON(win)); | ||
| 615 | 703 | ||
| 616 | /* hardware window 0 doesn't support alpha channel. */ | 704 | /* hardware window 0 doesn't support alpha channel. */ |
| 617 | if (win != 0) { | 705 | if (win != 0) { |
| 618 | /* OSD alpha */ | 706 | fimd_win_set_bldmod(ctx, win, alpha, pixel_alpha); |
| 619 | val = VIDISD14C_ALPHA0_R(0xf) | | 707 | fimd_win_set_bldeq(ctx, win, alpha, pixel_alpha); |
| 620 | VIDISD14C_ALPHA0_G(0xf) | | ||
| 621 | VIDISD14C_ALPHA0_B(0xf) | | ||
| 622 | VIDISD14C_ALPHA1_R(0xf) | | ||
| 623 | VIDISD14C_ALPHA1_G(0xf) | | ||
| 624 | VIDISD14C_ALPHA1_B(0xf); | ||
| 625 | |||
| 626 | writel(val, ctx->regs + VIDOSD_C(win)); | ||
| 627 | |||
| 628 | val = VIDW_ALPHA_R(0xf) | VIDW_ALPHA_G(0xf) | | ||
| 629 | VIDW_ALPHA_G(0xf); | ||
| 630 | writel(val, ctx->regs + VIDWnALPHA0(win)); | ||
| 631 | writel(val, ctx->regs + VIDWnALPHA1(win)); | ||
| 632 | } | 708 | } |
| 633 | } | 709 | } |
| 634 | 710 | ||
| @@ -785,7 +861,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, | |||
| 785 | DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); | 861 | DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); |
| 786 | } | 862 | } |
| 787 | 863 | ||
| 788 | fimd_win_set_pixfmt(ctx, win, fb->format->format, state->src.w); | 864 | fimd_win_set_pixfmt(ctx, win, fb, state->src.w); |
| 789 | 865 | ||
| 790 | /* hardware window 0 doesn't support color key. */ | 866 | /* hardware window 0 doesn't support color key. */ |
| 791 | if (win != 0) | 867 | if (win != 0) |
| @@ -987,6 +1063,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) | |||
| 987 | ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); | 1063 | ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); |
| 988 | ctx->configs[i].zpos = i; | 1064 | ctx->configs[i].zpos = i; |
| 989 | ctx->configs[i].type = fimd_win_types[i]; | 1065 | ctx->configs[i].type = fimd_win_types[i]; |
| 1066 | ctx->configs[i].capabilities = capabilities[i]; | ||
| 990 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], i, | 1067 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], i, |
| 991 | &ctx->configs[i]); | 1068 | &ctx->configs[i]); |
| 992 | if (ret) | 1069 | if (ret) |
diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h index d8fc96ed11e9..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 |
| @@ -211,6 +212,7 @@ | |||
| 211 | #define WINCON0_BPPMODE_24BPP_888 (0xb << 2) | 212 | #define WINCON0_BPPMODE_24BPP_888 (0xb << 2) |
| 212 | 213 | ||
| 213 | #define WINCON1_LOCALSEL_CAMIF (1 << 23) | 214 | #define WINCON1_LOCALSEL_CAMIF (1 << 23) |
| 215 | #define WINCON1_ALPHA_MUL (1 << 7) | ||
| 214 | #define WINCON1_BLD_PIX (1 << 6) | 216 | #define WINCON1_BLD_PIX (1 << 6) |
| 215 | #define WINCON1_BPPMODE_MASK (0xf << 2) | 217 | #define WINCON1_BPPMODE_MASK (0xf << 2) |
| 216 | #define WINCON1_BPPMODE_SHIFT 2 | 218 | #define WINCON1_BPPMODE_SHIFT 2 |
| @@ -437,6 +439,14 @@ | |||
| 437 | #define WPALCON_W0PAL_16BPP_565 (0x6 << 0) | 439 | #define WPALCON_W0PAL_16BPP_565 (0x6 << 0) |
| 438 | 440 | ||
| 439 | /* 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) | ||
| 440 | #define BLENDCON 0x260 | 450 | #define BLENDCON 0x260 |
| 441 | #define BLENDCON_NEW_MASK (1 << 0) | 451 | #define BLENDCON_NEW_MASK (1 << 0) |
| 442 | #define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0) | 452 | #define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0) |
