diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2015-01-09 05:03:13 -0500 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2017-03-15 10:42:31 -0400 |
commit | e72db3b1e50febff493bc5e3fb57da9cb8cc3d91 (patch) | |
tree | 3ad57c2c2fe02185979ab99f6584c32b06c2431d | |
parent | ba2b5277dc52cc96944d9765281bdf1e12681f66 (diff) |
gpu: ipu-v3: add support for separate alpha channels
The IPUv3 can read 8-bit alpha values from a separate IDMAC channel driven
by the Alpha Transparency Controller (ATC) for the graphics IDMAC channels.
This allows to reduce memory bandwidth via a conditional read mechanism or
to support planar YUV formats with alpha transparency.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-common.c | 6 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-cpmem.c | 57 | ||||
-rw-r--r-- | include/video/imx-ipu-v3.h | 22 |
3 files changed, 85 insertions, 0 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 8a32ed25a1c2..448043c051e9 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c | |||
@@ -83,6 +83,12 @@ enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc) | |||
83 | case DRM_FORMAT_ABGR8888: | 83 | case DRM_FORMAT_ABGR8888: |
84 | case DRM_FORMAT_RGBA8888: | 84 | case DRM_FORMAT_RGBA8888: |
85 | case DRM_FORMAT_BGRA8888: | 85 | case DRM_FORMAT_BGRA8888: |
86 | case DRM_FORMAT_RGB565_A8: | ||
87 | case DRM_FORMAT_BGR565_A8: | ||
88 | case DRM_FORMAT_RGB888_A8: | ||
89 | case DRM_FORMAT_BGR888_A8: | ||
90 | case DRM_FORMAT_RGBX8888_A8: | ||
91 | case DRM_FORMAT_BGRX8888_A8: | ||
86 | return IPUV3_COLORSPACE_RGB; | 92 | return IPUV3_COLORSPACE_RGB; |
87 | case DRM_FORMAT_YUYV: | 93 | case DRM_FORMAT_YUYV: |
88 | case DRM_FORMAT_UYVY: | 94 | case DRM_FORMAT_UYVY: |
diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c index b72f725e00b5..114160dfc3ad 100644 --- a/drivers/gpu/ipu-v3/ipu-cpmem.c +++ b/drivers/gpu/ipu-v3/ipu-cpmem.c | |||
@@ -537,6 +537,43 @@ static const struct ipu_rgb def_bgra_16 = { | |||
537 | #define UV2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ | 537 | #define UV2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ |
538 | (pix->width * y) + (x)) | 538 | (pix->width * y) + (x)) |
539 | 539 | ||
540 | #define NUM_ALPHA_CHANNELS 7 | ||
541 | |||
542 | /* See Table 37-12. Alpha channels mapping. */ | ||
543 | static int ipu_channel_albm(int ch_num) | ||
544 | { | ||
545 | switch (ch_num) { | ||
546 | case IPUV3_CHANNEL_G_MEM_IC_PRP_VF: return 0; | ||
547 | case IPUV3_CHANNEL_G_MEM_IC_PP: return 1; | ||
548 | case IPUV3_CHANNEL_MEM_FG_SYNC: return 2; | ||
549 | case IPUV3_CHANNEL_MEM_FG_ASYNC: return 3; | ||
550 | case IPUV3_CHANNEL_MEM_BG_SYNC: return 4; | ||
551 | case IPUV3_CHANNEL_MEM_BG_ASYNC: return 5; | ||
552 | case IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB: return 6; | ||
553 | default: | ||
554 | return -EINVAL; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | static void ipu_cpmem_set_separate_alpha(struct ipuv3_channel *ch) | ||
559 | { | ||
560 | struct ipu_soc *ipu = ch->ipu; | ||
561 | int albm; | ||
562 | u32 val; | ||
563 | |||
564 | albm = ipu_channel_albm(ch->num); | ||
565 | if (albm < 0) | ||
566 | return; | ||
567 | |||
568 | ipu_ch_param_write_field(ch, IPU_FIELD_ALU, 1); | ||
569 | ipu_ch_param_write_field(ch, IPU_FIELD_ALBM, albm); | ||
570 | ipu_ch_param_write_field(ch, IPU_FIELD_CRE, 1); | ||
571 | |||
572 | val = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA); | ||
573 | val |= BIT(ch->num); | ||
574 | ipu_idmac_write(ipu, val, IDMAC_SEP_ALPHA); | ||
575 | } | ||
576 | |||
540 | int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc) | 577 | int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc) |
541 | { | 578 | { |
542 | switch (drm_fourcc) { | 579 | switch (drm_fourcc) { |
@@ -599,22 +636,28 @@ int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc) | |||
599 | break; | 636 | break; |
600 | case DRM_FORMAT_RGBA8888: | 637 | case DRM_FORMAT_RGBA8888: |
601 | case DRM_FORMAT_RGBX8888: | 638 | case DRM_FORMAT_RGBX8888: |
639 | case DRM_FORMAT_RGBX8888_A8: | ||
602 | ipu_cpmem_set_format_rgb(ch, &def_rgbx_32); | 640 | ipu_cpmem_set_format_rgb(ch, &def_rgbx_32); |
603 | break; | 641 | break; |
604 | case DRM_FORMAT_BGRA8888: | 642 | case DRM_FORMAT_BGRA8888: |
605 | case DRM_FORMAT_BGRX8888: | 643 | case DRM_FORMAT_BGRX8888: |
644 | case DRM_FORMAT_BGRX8888_A8: | ||
606 | ipu_cpmem_set_format_rgb(ch, &def_bgrx_32); | 645 | ipu_cpmem_set_format_rgb(ch, &def_bgrx_32); |
607 | break; | 646 | break; |
608 | case DRM_FORMAT_BGR888: | 647 | case DRM_FORMAT_BGR888: |
648 | case DRM_FORMAT_BGR888_A8: | ||
609 | ipu_cpmem_set_format_rgb(ch, &def_bgr_24); | 649 | ipu_cpmem_set_format_rgb(ch, &def_bgr_24); |
610 | break; | 650 | break; |
611 | case DRM_FORMAT_RGB888: | 651 | case DRM_FORMAT_RGB888: |
652 | case DRM_FORMAT_RGB888_A8: | ||
612 | ipu_cpmem_set_format_rgb(ch, &def_rgb_24); | 653 | ipu_cpmem_set_format_rgb(ch, &def_rgb_24); |
613 | break; | 654 | break; |
614 | case DRM_FORMAT_RGB565: | 655 | case DRM_FORMAT_RGB565: |
656 | case DRM_FORMAT_RGB565_A8: | ||
615 | ipu_cpmem_set_format_rgb(ch, &def_rgb_16); | 657 | ipu_cpmem_set_format_rgb(ch, &def_rgb_16); |
616 | break; | 658 | break; |
617 | case DRM_FORMAT_BGR565: | 659 | case DRM_FORMAT_BGR565: |
660 | case DRM_FORMAT_BGR565_A8: | ||
618 | ipu_cpmem_set_format_rgb(ch, &def_bgr_16); | 661 | ipu_cpmem_set_format_rgb(ch, &def_bgr_16); |
619 | break; | 662 | break; |
620 | case DRM_FORMAT_ARGB1555: | 663 | case DRM_FORMAT_ARGB1555: |
@@ -636,6 +679,20 @@ int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc) | |||
636 | return -EINVAL; | 679 | return -EINVAL; |
637 | } | 680 | } |
638 | 681 | ||
682 | switch (drm_fourcc) { | ||
683 | case DRM_FORMAT_RGB565_A8: | ||
684 | case DRM_FORMAT_BGR565_A8: | ||
685 | case DRM_FORMAT_RGB888_A8: | ||
686 | case DRM_FORMAT_BGR888_A8: | ||
687 | case DRM_FORMAT_RGBX8888_A8: | ||
688 | case DRM_FORMAT_BGRX8888_A8: | ||
689 | ipu_ch_param_write_field(ch, IPU_FIELD_WID3, 7); | ||
690 | ipu_cpmem_set_separate_alpha(ch); | ||
691 | break; | ||
692 | default: | ||
693 | break; | ||
694 | } | ||
695 | |||
639 | return 0; | 696 | return 0; |
640 | } | 697 | } |
641 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt); | 698 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt); |
diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 899d2b00ad6d..6af74f0cf161 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h | |||
@@ -161,6 +161,28 @@ enum ipu_channel_irq { | |||
161 | #define IPUV3_CHANNEL_MEM_BG_ASYNC_ALPHA 52 | 161 | #define IPUV3_CHANNEL_MEM_BG_ASYNC_ALPHA 52 |
162 | #define IPUV3_NUM_CHANNELS 64 | 162 | #define IPUV3_NUM_CHANNELS 64 |
163 | 163 | ||
164 | static inline int ipu_channel_alpha_channel(int ch_num) | ||
165 | { | ||
166 | switch (ch_num) { | ||
167 | case IPUV3_CHANNEL_G_MEM_IC_PRP_VF: | ||
168 | return IPUV3_CHANNEL_G_MEM_IC_PRP_VF_ALPHA; | ||
169 | case IPUV3_CHANNEL_G_MEM_IC_PP: | ||
170 | return IPUV3_CHANNEL_G_MEM_IC_PP_ALPHA; | ||
171 | case IPUV3_CHANNEL_MEM_FG_SYNC: | ||
172 | return IPUV3_CHANNEL_MEM_FG_SYNC_ALPHA; | ||
173 | case IPUV3_CHANNEL_MEM_FG_ASYNC: | ||
174 | return IPUV3_CHANNEL_MEM_FG_ASYNC_ALPHA; | ||
175 | case IPUV3_CHANNEL_MEM_BG_SYNC: | ||
176 | return IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA; | ||
177 | case IPUV3_CHANNEL_MEM_BG_ASYNC: | ||
178 | return IPUV3_CHANNEL_MEM_BG_ASYNC_ALPHA; | ||
179 | case IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB: | ||
180 | return IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB_ALPHA; | ||
181 | default: | ||
182 | return -EINVAL; | ||
183 | } | ||
184 | } | ||
185 | |||
164 | int ipu_map_irq(struct ipu_soc *ipu, int irq); | 186 | int ipu_map_irq(struct ipu_soc *ipu, int irq); |
165 | int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, | 187 | int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, |
166 | enum ipu_channel_irq irq); | 188 | enum ipu_channel_irq irq); |