aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2015-01-09 05:03:13 -0500
committerPhilipp Zabel <p.zabel@pengutronix.de>2017-03-15 10:42:31 -0400
commite72db3b1e50febff493bc5e3fb57da9cb8cc3d91 (patch)
tree3ad57c2c2fe02185979ab99f6584c32b06c2431d
parentba2b5277dc52cc96944d9765281bdf1e12681f66 (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.c6
-rw-r--r--drivers/gpu/ipu-v3/ipu-cpmem.c57
-rw-r--r--include/video/imx-ipu-v3.h22
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. */
543static 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
558static 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
540int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc) 577int 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}
641EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt); 698EXPORT_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
164static 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
164int ipu_map_irq(struct ipu_soc *ipu, int irq); 186int ipu_map_irq(struct ipu_soc *ipu, int irq);
165int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, 187int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
166 enum ipu_channel_irq irq); 188 enum ipu_channel_irq irq);