diff options
-rw-r--r-- | drivers/video/b2r2/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_generic.c | 358 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_hw.h | 249 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_hw_convert.c | 747 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_hw_convert.h | 53 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_internal.h | 3 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_node_split.c | 843 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_utils.c | 466 | ||||
-rw-r--r-- | drivers/video/b2r2/b2r2_utils.h | 18 | ||||
-rw-r--r-- | include/video/b2r2_blt.h | 1 |
10 files changed, 1491 insertions, 1249 deletions
diff --git a/drivers/video/b2r2/Makefile b/drivers/video/b2r2/Makefile index 0150ad6f761..9900ebf8216 100644 --- a/drivers/video/b2r2/Makefile +++ b/drivers/video/b2r2/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_FB_B2R2) += b2r2.o -b2r2-objs = b2r2_blt_main.o b2r2_core.o b2r2_mem_alloc.o b2r2_generic.o b2r2_node_gen.o b2r2_node_split.o b2r2_profiler_socket.o b2r2_timing.o b2r2_filters.o b2r2_utils.o b2r2_input_validation.o +b2r2-objs = b2r2_blt_main.o b2r2_core.o b2r2_mem_alloc.o b2r2_generic.o b2r2_node_gen.o b2r2_node_split.o b2r2_profiler_socket.o b2r2_timing.o b2r2_filters.o b2r2_utils.o b2r2_input_validation.o b2r2_hw_convert.o ifdef CONFIG_B2R2_DEBUG b2r2-objs += b2r2_debug.o diff --git a/drivers/video/b2r2/b2r2_generic.c b/drivers/video/b2r2/b2r2_generic.c index 1a27adbaadf..4191e497e13 100644 --- a/drivers/video/b2r2/b2r2_generic.c +++ b/drivers/video/b2r2/b2r2_generic.c @@ -18,6 +18,7 @@ #include "b2r2_global.h" #include "b2r2_debug.h" #include "b2r2_filters.h" +#include "b2r2_hw_convert.h" /* * Debug printing @@ -499,6 +500,8 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req, u32 src_color = req->user_req.src_color; const struct b2r2_blt_img *dst_img = &(req->user_req.dst_img); struct b2r2_control *cont = req->instance->control; + bool fullrange = (req->user_req.flags & + B2R2_BLT_FLAG_FULL_RANGE_YUV) != 0; b2r2_log_info(cont->dev, "%s ENTRY\n", __func__); @@ -525,17 +528,7 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req, * where it is stored in ABGR format. * Set up IVMX. */ - node->node.GROUP0.B2R2_INS |= - B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_RGB_TO_BGR; + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_BGR); } } break; @@ -568,16 +561,10 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req, * Format of the supplied src_color is * B2R2_BLT_FMT_32_BIT_AYUV8888. */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_BLT_YUV888_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_BLT_YUV888_TO_RGB); } else { /* SOURCE_FILL_RAW */ bool dst_yuv_planar = @@ -623,17 +610,12 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req, case B2R2_BLT_FMT_32_BIT_AYUV8888: case B2R2_BLT_FMT_24_BIT_VUY888: case B2R2_BLT_FMT_32_BIT_VUYA8888: - node->node.GROUP0.B2R2_INS |= - B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, + B2R2_CC_BLT_YUV888_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, + B2R2_CC_BLT_YUV888_TO_RGB); /* * Re-arrange the color components from * VUY(A) to (A)YUV @@ -663,14 +645,11 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req, * Chroma components are swapped so * it is YVU and not YUV. */ - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YVU_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, + B2R2_CC_YVU_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YVU_TO_RGB); break; default: /* @@ -680,17 +659,11 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req, * an intermediate buffer which is RGB. * Hence the conversion from YUV to RGB. */ - node->node.GROUP0.B2R2_INS |= - B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YUV_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, + B2R2_CC_YUV_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YUV_TO_RGB); break; } } @@ -766,6 +739,8 @@ static void setup_input_stage(const struct b2r2_blt_request *req, bool use_v_filter = false; struct b2r2_control *cont = req->instance->control; + bool fullrange = (req->user_req.flags & + B2R2_BLT_FLAG_FULL_RANGE_YUV) != 0; b2r2_log_info(cont->dev, "%s ENTRY\n", __func__); @@ -837,14 +812,7 @@ static void setup_input_stage(const struct b2r2_blt_request *req, /* Adjustments that depend on the source format */ switch (src_img->fmt) { case B2R2_BLT_FMT_32_BIT_ABGR8888: - /* Set up IVMX */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - - node->node.GROUP15.B2R2_VMX0 = B2R2_VMX0_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX1 = B2R2_VMX1_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX2 = B2R2_VMX2_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_RGB_TO_BGR; + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_BGR); break; case B2R2_BLT_FMT_Y_CB_Y_CR: /* @@ -852,29 +820,16 @@ static void setup_input_stage(const struct b2r2_blt_request *req, * Chroma components are swapped so * it is YVU and not YUV. */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YVU_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YVU_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YVU_TO_RGB); break; case B2R2_BLT_FMT_CB_Y_CR_Y: - /* Set up IVMX */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YUV_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YUV_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YUV_TO_RGB); break; case B2R2_BLT_FMT_24_BIT_YUV888: case B2R2_BLT_FMT_32_BIT_AYUV8888: @@ -889,16 +844,10 @@ static void setup_input_stage(const struct b2r2_blt_request *req, * B2R2 expects them to be as U, Y, V, (A) * with U at the first byte. */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_BLT_YUV888_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_BLT_YUV888_TO_RGB); /* * Re-arrange color components from VUY(A) to (A)YUV @@ -927,32 +876,21 @@ static void setup_input_stage(const struct b2r2_blt_request *req, u32 rsf_luma = 0; u32 rzi_luma = 0; - /* Set up IVMX */ - node->node.GROUP0.B2R2_INS |= - B2R2_INS_IVMX_ENABLED | B2R2_INS_RESCALE2D_ENABLED; - node->node.GROUP0.B2R2_CIC |= - B2R2_CIC_IVMX | B2R2_CIC_RESIZE_LUMA; + node->node.GROUP0.B2R2_INS |= B2R2_INS_RESCALE2D_ENABLED; + node->node.GROUP0.B2R2_CIC |= B2R2_CIC_RESIZE_LUMA; if (src_img->fmt == B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR || src_img->fmt == B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR) { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YVU_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YVU_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YVU_TO_RGB); } else { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YUV_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YUV_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YUV_TO_RGB); } fctl |= B2R2_FCTL_LUMA_HF2D_MODE_ENABLE_RESIZER | @@ -1316,6 +1254,8 @@ static void setup_dst_read_stage(const struct b2r2_blt_request *req, u32 dst_pitch = 0; struct b2r2_control *cont = req->instance->control; + bool fullrange = (req->user_req.flags & + B2R2_BLT_FLAG_FULL_RANGE_YUV) != 0; if (dst_img->pitch == 0) { /* Determine pitch based on format and width of the image. */ @@ -1329,37 +1269,24 @@ static void setup_dst_read_stage(const struct b2r2_blt_request *req, /* Adjustments that depend on the destination format */ switch (dst_img->fmt) { case B2R2_BLT_FMT_32_BIT_ABGR8888: - /* Set up IVMX */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - - node->node.GROUP15.B2R2_VMX0 = B2R2_VMX0_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX1 = B2R2_VMX1_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX2 = B2R2_VMX2_RGB_TO_BGR; - node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_RGB_TO_BGR; + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_BGR); break; case B2R2_BLT_FMT_Y_CB_Y_CR: - /* Set up IVMX */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; /* * Setup input VMX to convert YVU to RGB 601 VIDEO * Chroma components are swapped * so it is YVU and not YUV. */ - node->node.GROUP15.B2R2_VMX0 = B2R2_VMX0_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = B2R2_VMX1_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = B2R2_VMX2_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_YVU_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YVU_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YVU_TO_RGB); break; case B2R2_BLT_FMT_CB_Y_CR_Y: - /* Set up IVMX */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = B2R2_VMX0_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = B2R2_VMX1_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = B2R2_VMX2_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_YUV_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YUV_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YUV_TO_RGB); break; case B2R2_BLT_FMT_24_BIT_YUV888: case B2R2_BLT_FMT_32_BIT_AYUV8888: @@ -1374,16 +1301,10 @@ static void setup_dst_read_stage(const struct b2r2_blt_request *req, * B2R2 expects them to be as U, Y, V, (A) * with U at the first byte. */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_BLT_YUV888_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_BLT_YUV888_TO_RGB); /* * Re-arrange color components from VUY(A) to (A)YUV @@ -1404,30 +1325,18 @@ static void setup_dst_read_stage(const struct b2r2_blt_request *req, case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: { - /* Set up IVMX */ - node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; - if (dst_img->fmt == B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR || dst_img->fmt == B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR) { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YVU_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YVU_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YVU_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YVU_TO_RGB); } else { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_YUV_TO_RGB_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_YUV_TO_RGB_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_YUV_FULL_TO_RGB); + else + b2r2_setup_ivmx(node, B2R2_CC_YUV_TO_RGB); } switch (dst_img->fmt) { @@ -1781,6 +1690,8 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, u32 endianness = 0; struct b2r2_control *cont = req->instance->control; + bool fullrange = (req->user_req.flags & + B2R2_BLT_FLAG_FULL_RANGE_YUV) != 0; b2r2_log_info(cont->dev, "%s ENTRY\n", __func__); @@ -1803,12 +1714,10 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, u32 rsf = 0; const u32 group0_b2r2_ins = B2R2_INS_SOURCE_2_FETCH_FROM_MEM | - B2R2_INS_RECT_CLIP_ENABLED | - B2R2_INS_IVMX_ENABLED; + B2R2_INS_RECT_CLIP_ENABLED; const u32 group0_b2r2_cic = B2R2_CIC_SOURCE_2 | - B2R2_CIC_CLIP_WINDOW | - B2R2_CIC_IVMX; + B2R2_CIC_CLIP_WINDOW; u32 cb_addr = 0; u32 cr_addr = 0; @@ -1891,10 +1800,10 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, B2R2_TY_VSO_TOP_TO_BOTTOM | dst_dither; - node->node.GROUP15.B2R2_VMX0 = B2R2_VMX0_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = B2R2_VMX1_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = B2R2_VMX2_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_RGB_TO_YUV_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV_FULL); + else + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV); /* bypass ALU, no blending here. Handled in its own stage. */ node->node.GROUP0.B2R2_ACK = B2R2_ACK_MODE_BYPASS_S2_S3; @@ -1916,10 +1825,10 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, dst_dither | B2R2_TTY_CHROMA_NOT_LUMA; - node->node.GROUP15.B2R2_VMX0 = B2R2_VMX0_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = B2R2_VMX1_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = B2R2_VMX2_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_RGB_TO_YUV_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV_FULL); + else + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV); node->node.GROUP0.B2R2_ACK = B2R2_ACK_MODE_BYPASS_S2_S3; node->node.GROUP0.B2R2_INS = group0_b2r2_ins; @@ -1959,10 +1868,10 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, dst_dither | B2R2_TTY_CHROMA_NOT_LUMA; - node->node.GROUP15.B2R2_VMX0 = B2R2_VMX0_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = B2R2_VMX1_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = B2R2_VMX2_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_RGB_TO_YUV_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV_FULL); + else + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV); node->node.GROUP0.B2R2_ACK = B2R2_ACK_MODE_BYPASS_S2_S3; node->node.GROUP0.B2R2_INS = group0_b2r2_ins; @@ -1993,12 +1902,10 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, u32 rsf = 0; const u32 group0_b2r2_ins = B2R2_INS_SOURCE_2_FETCH_FROM_MEM | - B2R2_INS_RECT_CLIP_ENABLED | - B2R2_INS_IVMX_ENABLED; + B2R2_INS_RECT_CLIP_ENABLED; const u32 group0_b2r2_cic = B2R2_CIC_SOURCE_2 | - B2R2_CIC_CLIP_WINDOW | - B2R2_CIC_IVMX; + B2R2_CIC_CLIP_WINDOW; u32 chroma_addr = req->dst_resolved.physical_address + dst_pitch * dst_img->height; @@ -2047,23 +1954,15 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, if (dst_fmt == B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR || dst_fmt == B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR) { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_RGB_TO_YVU_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_RGB_TO_YVU_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_RGB_TO_YVU_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_RGB_TO_YVU_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YVU_FULL); + else + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YVU); } else { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_RGB_TO_YUV_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV_FULL); + else + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV); } /* bypass ALU, no blending here. Handled in its own stage. */ @@ -2088,23 +1987,15 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, if (dst_fmt == B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR || dst_fmt == B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR) { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_RGB_TO_YVU_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_RGB_TO_YVU_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_RGB_TO_YVU_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_RGB_TO_YVU_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YVU_FULL); + else + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YVU); } else { - node->node.GROUP15.B2R2_VMX0 = - B2R2_VMX0_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX1 = - B2R2_VMX1_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX2 = - B2R2_VMX2_RGB_TO_YUV_601_VIDEO; - node->node.GROUP15.B2R2_VMX3 = - B2R2_VMX3_RGB_TO_YUV_601_VIDEO; + if (fullrange) + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV_FULL); + else + b2r2_setup_ivmx(node, B2R2_CC_RGB_TO_YUV); } node->node.GROUP0.B2R2_ACK = B2R2_ACK_MODE_BYPASS_S2_S3; @@ -2126,43 +2017,24 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req, } else { /* single buffer target */ - /* Set up OVMX */ switch (dst_fmt) { case B2R2_BLT_FMT_32_BIT_ABGR8888: - node->node.GROUP0.B2R2_INS |= B2R2_INS_OVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_OVMX; - node->node.GROUP16.B2R2_VMX0 = B2R2_VMX0_RGB_TO_BGR; - node->node.GROUP16.B2R2_VMX1 = B2R2_VMX1_RGB_TO_BGR; - node->node.GROUP16.B2R2_VMX2 = B2R2_VMX2_RGB_TO_BGR; - node->node.GROUP16.B2R2_VMX3 = B2R2_VMX3_RGB_TO_BGR; + b2r2_setup_ovmx(node, B2R2_CC_RGB_TO_BGR); break; case B2R2_BLT_FMT_Y_CB_Y_CR: - node->node.GROUP0.B2R2_INS |= B2R2_INS_OVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_OVMX; - node->node.GROUP16.B2R2_VMX0 = - B2R2_VMX0_RGB_TO_YVU_601_VIDEO; - node->node.GROUP16.B2R2_VMX1 = - B2R2_VMX1_RGB_TO_YVU_601_VIDEO; - node->node.GROUP16.B2R2_VMX2 = - B2R2_VMX2_RGB_TO_YVU_601_VIDEO; - node->node.GROUP16.B2R2_VMX3 = - B2R2_VMX3_RGB_TO_YVU_601_VIDEO; + if (fullrange) + b2r2_setup_ovmx(node, B2R2_CC_RGB_TO_YVU_FULL); + else + b2r2_setup_ovmx(node, B2R2_CC_RGB_TO_YVU); break; case B2R2_BLT_FMT_24_BIT_YUV888: /* fall through */ case B2R2_BLT_FMT_32_BIT_AYUV8888: /* fall through */ case B2R2_BLT_FMT_24_BIT_VUY888: /* fall through */ case B2R2_BLT_FMT_32_BIT_VUYA8888: - node->node.GROUP0.B2R2_INS |= B2R2_INS_OVMX_ENABLED; - node->node.GROUP0.B2R2_CIC |= B2R2_CIC_OVMX; - node->node.GROUP16.B2R2_VMX0 = - B2R2_VMX0_RGB_TO_BLT_YUV888_601_VIDEO; - node->node.GROUP16.B2R2_VMX1 = - B2R2_VMX1_RGB_TO_BLT_YUV888_601_VIDEO; - node->node.GROUP16.B2R2_VMX2 = - B2R2_VMX2_RGB_TO_BLT_YUV888_601_VIDEO; - node->node.GROUP16.B2R2_VMX3 = - B2R2_VMX3_RGB_TO_BLT_YUV888_601_VIDEO; - + if (fullrange) + b2r2_setup_ovmx(node, B2R2_CC_RGB_TO_BLT_YUV888_FULL); + else + b2r2_setup_ovmx(node, B2R2_CC_RGB_TO_BLT_YUV888); /* * Re-arrange color components from (A)YUV to VUY(A) * when bytes are stored in memory. diff --git a/drivers/video/b2r2/b2r2_hw.h b/drivers/video/b2r2/b2r2_hw.h index d492168913a..9739912d78c 100644 --- a/drivers/video/b2r2/b2r2_hw.h +++ b/drivers/video/b2r2/b2r2_hw.h @@ -455,253 +455,4 @@ enum b2r2_plug_page_size { # define B2R2_PLUG_PAGE_SIZE_DEFAULT 0 #endif -/* VMX register values for RGB to YUV color conversion */ -/* Magic numbers from 27.11 in DB8500_DesignSpecification_v2.5.pdf */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_RGB_TO_YUV_601_VIDEO 0x107e4beb -#define B2R2_VMX1_RGB_TO_YUV_601_VIDEO 0x0982581d -#define B2R2_VMX2_RGB_TO_YUV_601_VIDEO 0xfa9ea483 -#define B2R2_VMX3_RGB_TO_YUV_601_VIDEO 0x08000080 - -/* 601 Gfx Matrix (full range conversion) */ -#define B2R2_VMX0_RGB_TO_YUV_601_GFX 0x0e1e8bee -#define B2R2_VMX1_RGB_TO_YUV_601_GFX 0x08420419 -#define B2R2_VMX2_RGB_TO_YUV_601_GFX 0xfb5ed471 -#define B2R2_VMX3_RGB_TO_YUV_601_GFX 0x08004080 - -/* 709 Video Matrix (standard 709 conversion) */ -#define B2R2_VMX0_RGB_TO_YUV_709_VIDEO 0x107e27f4 -#define B2R2_VMX1_RGB_TO_YUV_709_VIDEO 0x06e2dc13 -#define B2R2_VMX2_RGB_TO_YUV_709_VIDEO 0xfc5e6c83 -#define B2R2_VMX3_RGB_TO_YUV_709_VIDEO 0x08000080 - -/* 709 Gfx Matrix (standard 709 conversion) */ -#define B2R2_VMX0_RGB_TO_YUV_709_GFX 0x0e3e6bf5 -#define B2R2_VMX1_RGB_TO_YUV_709_GFX 0x05e27410 -#define B2R2_VMX2_RGB_TO_YUV_709_GFX 0xfcdea471 -#define B2R2_VMX3_RGB_TO_YUV_709_GFX 0x08004080 - -/* VMX register values for YUV to RGB color conversion */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_YUV_TO_RGB_601_VIDEO 0x2c440000 -#define B2R2_VMX1_YUV_TO_RGB_601_VIDEO 0xe9a403aa -#define B2R2_VMX2_YUV_TO_RGB_601_VIDEO 0x0004013f -#define B2R2_VMX3_YUV_TO_RGB_601_VIDEO 0x34f21322 - -/* 601 Gfx Matrix (full range conversion) */ -#define B2R2_VMX0_YUV_TO_RGB_601_GFX 0x3324a800 -#define B2R2_VMX1_YUV_TO_RGB_601_GFX 0xe604ab9c -#define B2R2_VMX2_YUV_TO_RGB_601_GFX 0x0004a957 -#define B2R2_VMX3_YUV_TO_RGB_601_GFX 0x32121eeb - -/* 709 Video Matrix (standard 709 conversion) */ -#define B2R2_VMX0_YUV_TO_RGB_709_VIDEO 0x31440000 -#define B2R2_VMX1_YUV_TO_RGB_709_VIDEO 0xf16403d1 -#define B2R2_VMX2_YUV_TO_RGB_709_VIDEO 0x00040145 -#define B2R2_VMX3_YUV_TO_RGB_709_VIDEO 0x33b14b18 - -/* 709 Gfx Matrix (standard 709 conversion) */ -#define B2R2_VMX0_YUV_TO_RGB_709_GFX 0x3964a800 -#define B2R2_VMX1_YUV_TO_RGB_709_GFX 0xef04abc9 -#define B2R2_VMX2_YUV_TO_RGB_709_GFX 0x0004a95f -#define B2R2_VMX3_YUV_TO_RGB_709_GFX 0x307132df - -/* VMX register values for RGB to BGR conversion */ -#define B2R2_VMX0_RGB_TO_BGR 0x00000100 -#define B2R2_VMX1_RGB_TO_BGR 0x00040000 -#define B2R2_VMX2_RGB_TO_BGR 0x20000000 -#define B2R2_VMX3_RGB_TO_BGR 0x00000000 - -/* VMX register values for BGR to YUV color conversion */ -/* Note: All BGR -> YUV values are calculated by multiplying - * the RGB -> YUV matrices [A], with [S] to form [A]x[S] where - * |0 0 1| - * S = |0 1 0| - * |1 0 0| - * Essentially swapping first and third columns in - * the matrices (VMX0, VMX1 and VMX2 values). - * The offset vector VMX3 remains untouched. - * Put another way, the value of bits 0 through 9 - * is swapped with the value of - * bits 20 through 31 in VMX0, VMX1 and VMX2, - * taking into consideration the compression - * that is used on bits 0 through 9. Bit 0 being LSB. - */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_BGR_TO_YUV_601_VIDEO 0xfd7e4883 -#define B2R2_VMX1_BGR_TO_YUV_601_VIDEO 0x03a2584c -#define B2R2_VMX2_BGR_TO_YUV_601_VIDEO 0x107ea7d4 -#define B2R2_VMX3_BGR_TO_YUV_601_VIDEO 0x08000080 - -/* 601 Gfx Matrix (full range conversion) */ -#define B2R2_VMX0_BGR_TO_YUV_601_GFX 0xfdde8870 -#define B2R2_VMX1_BGR_TO_YUV_601_GFX 0x03220442 -#define B2R2_VMX2_BGR_TO_YUV_601_GFX 0x0e3ed7da -#define B2R2_VMX3_BGR_TO_YUV_601_GFX 0x08004080 - -/* 709 Video Matrix (standard 709 conversion) */ -#define B2R2_VMX0_BGR_TO_YUV_709_VIDEO 0xfe9e2483 -#define B2R2_VMX1_BGR_TO_YUV_709_VIDEO 0x0262dc37 -#define B2R2_VMX2_BGR_TO_YUV_709_VIDEO 0x107e6fe2 -#define B2R2_VMX3_BGR_TO_YUV_709_VIDEO 0x08000080 - -/* 709 Gfx Matrix (standard 709 conversion) */ -#define B2R2_VMX0_BGR_TO_YUV_709_GFX 0xfebe6871 -#define B2R2_VMX1_BGR_TO_YUV_709_GFX 0x0202742f -#define B2R2_VMX2_BGR_TO_YUV_709_GFX 0x0e3ea7e6 -#define B2R2_VMX3_BGR_TO_YUV_709_GFX 0x08004080 - - -/* VMX register values for YUV to BGR conversion */ -/* Note: All YUV -> BGR values are constructed - * from the YUV -> RGB ones, by swapping - * first and third rows in the matrix - * (VMX0 and VMX2 values). Further, the first and - * third values in the offset vector need to be - * swapped as well, i.e. bits 0 through 9 are swapped - * with bits 20 through 29 in the VMX3 value. - * Bit 0 being LSB. - */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_YUV_TO_BGR_601_VIDEO 0x0004013f -#define B2R2_VMX1_YUV_TO_BGR_601_VIDEO 0xe9a403aa -#define B2R2_VMX2_YUV_TO_BGR_601_VIDEO 0x2c440000 -#define B2R2_VMX3_YUV_TO_BGR_601_VIDEO 0x3222134f - -/* 601 Gfx Matrix (full range conversion) */ -#define B2R2_VMX0_YUV_TO_BGR_601_GFX 0x0004a957 -#define B2R2_VMX1_YUV_TO_BGR_601_GFX 0xe604ab9c -#define B2R2_VMX2_YUV_TO_BGR_601_GFX 0x3324a800 -#define B2R2_VMX3_YUV_TO_BGR_601_GFX 0x2eb21f21 - -/* 709 Video Matrix (standard 709 conversion) */ -#define B2R2_VMX0_YUV_TO_BGR_709_VIDEO 0x00040145 -#define B2R2_VMX1_YUV_TO_BGR_709_VIDEO 0xf16403d1 -#define B2R2_VMX2_YUV_TO_BGR_709_VIDEO 0x31440000 -#define B2R2_VMX3_YUV_TO_BGR_709_VIDEO 0x31814b3b - -/* 709 Gfx Matrix (standard 709 conversion) */ -#define B2R2_VMX0_YUV_TO_BGR_709_GFX 0x0004a95f -#define B2R2_VMX1_YUV_TO_BGR_709_GFX 0xef04abc9 -#define B2R2_VMX2_YUV_TO_BGR_709_GFX 0x3964a800 -#define B2R2_VMX3_YUV_TO_BGR_709_GFX 0x2df13307 - - -/* VMX register values for YVU to RGB conversion */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_YVU_TO_RGB_601_VIDEO 0x00040120 -#define B2R2_VMX1_YVU_TO_RGB_601_VIDEO 0xF544034D -#define B2R2_VMX2_YVU_TO_RGB_601_VIDEO 0x37840000 -#define B2R2_VMX3_YVU_TO_RGB_601_VIDEO 0x34f21322 - -/* VMX register values for RGB to YVU conversion */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_RGB_TO_YVU_601_VIDEO 0xfa9ea483 -#define B2R2_VMX1_RGB_TO_YVU_601_VIDEO 0x0982581d -#define B2R2_VMX2_RGB_TO_YVU_601_VIDEO 0x107e4beb -#define B2R2_VMX3_RGB_TO_YVU_601_VIDEO 0x08000080 - -/* VMX register values for YVU to BGR conversion */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_YVU_TO_BGR_601_VIDEO 0x37840000 -#define B2R2_VMX1_YVU_TO_BGR_601_VIDEO 0xF544034D -#define B2R2_VMX2_YVU_TO_BGR_601_VIDEO 0x00040120 -#define B2R2_VMX3_YVU_TO_BGR_601_VIDEO 0x3222134F - -/* VMX register values for BGR to YVU conversion */ - -/* 601 Video Matrix (standard 601 conversion) */ -#define B2R2_VMX0_BGR_TO_YVU_601_VIDEO 0x107ea7d4 -#define B2R2_VMX1_BGR_TO_YVU_601_VIDEO 0x03a2584c -#define B2R2_VMX2_BGR_TO_YVU_601_VIDEO 0xfd7e4883 -#define B2R2_VMX3_BGR_TO_YVU_601_VIDEO 0x08000080 - -/* VMX register values for YVU to YUV conversion */ - -/* 601 Video Matrix (standard 601 conversion) */ -/* Internally, the components are in fact stored - * with luma in the middle, i.e. UYV, which is why - * the values are just like for RGB->BGR conversion. - */ -#define B2R2_VMX0_YVU_TO_YUV_601_VIDEO 0x00000100 -#define B2R2_VMX1_YVU_TO_YUV_601_VIDEO 0x00040000 -#define B2R2_VMX2_YVU_TO_YUV_601_VIDEO 0x20000000 -#define B2R2_VMX3_YVU_TO_YUV_601_VIDEO 0x00000000 - -/* VMX register values for RGB to BLT_YUV888 conversion */ - -/* 601 Video Matrix (standard 601 conversion) */ -/* - * BLT_YUV888 has color components laid out in memory as V, U, Y, (Alpha) - * with V at the first byte (due to little endian addressing). - * B2R2 expects them to be as U, Y, V, (A) - * with U at the first byte. - * Note: RGB -> BLT_YUV888 values are calculated by multiplying - * the RGB -> YUV matrix [A], with [S] to form [S]x[A] where - * |0 1 0| - * S = |0 0 1| - * |1 0 0| - * Essentially changing the order of rows in the original - * matrix [A]. - * row1 -> row3 - * row2 -> row1 - * row3 -> row2 - * Values in the offset vector are swapped in the same manner. - */ -#define B2R2_VMX0_RGB_TO_BLT_YUV888_601_VIDEO 0x0982581d -#define B2R2_VMX1_RGB_TO_BLT_YUV888_601_VIDEO 0xfa9ea483 -#define B2R2_VMX2_RGB_TO_BLT_YUV888_601_VIDEO 0x107e4beb -#define B2R2_VMX3_RGB_TO_BLT_YUV888_601_VIDEO 0x00020080 - -/* VMX register values for BLT_YUV888 to RGB conversion */ - -/* - * Note: BLT_YUV888 -> RGB values are calculated by multiplying - * the YUV -> RGB matrix [A], with [S] to form [A]x[S] where - * |0 0 1| - * S = |1 0 0| - * |0 1 0| - * Essentially changing the order of columns in the original - * matrix [A]. - * col1 -> col3 - * col2 -> col1 - * col3 -> col2 - * Values in the offset vector remain unchanged. - */ -#define B2R2_VMX0_BLT_YUV888_TO_RGB_601_VIDEO 0x20000121 -#define B2R2_VMX1_BLT_YUV888_TO_RGB_601_VIDEO 0x201ea74c -#define B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO 0x2006f000 -#define B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO 0x34f21322 - -/* VMX register values for YUV to BLT_YUV888 conversion */ -#define B2R2_VMX0_YUV_TO_BLT_YUV888 0x00040000 -#define B2R2_VMX1_YUV_TO_BLT_YUV888 0x00000100 -#define B2R2_VMX2_YUV_TO_BLT_YUV888 0x20000000 -#define B2R2_VMX3_YUV_TO_BLT_YUV888 0x00000000 - -/* VMX register values for BLT_YUV888 to YUV conversion */ -#define B2R2_VMX0_BLT_YUV888_TO_YUV 0x00000100 -#define B2R2_VMX1_BLT_YUV888_TO_YUV 0x20000000 -#define B2R2_VMX2_BLT_YUV888_TO_YUV 0x00040000 -#define B2R2_VMX3_BLT_YUV888_TO_YUV 0x00000000 - -/* VMX register values for YVU to BLT_YUV888 conversion */ -#define B2R2_VMX0_YVU_TO_BLT_YUV888 0x00040000 -#define B2R2_VMX1_YVU_TO_BLT_YUV888 0x20000000 -#define B2R2_VMX2_YVU_TO_BLT_YUV888 0x00000100 -#define B2R2_VMX3_YVU_TO_BLT_YUV888 0x00000000 - -/* VMX register values for BLT_YUV888 to YVU conversion */ -#define B2R2_VMX0_BLT_YUV888_TO_YVU 0x00040000 -#define B2R2_VMX1_BLT_YUV888_TO_YVU 0x20000000 -#define B2R2_VMX2_BLT_YUV888_TO_YVU 0x00000100 -#define B2R2_VMX3_BLT_YUV888_TO_YVU 0x00000000 - #endif /* B2R2_HW_H__ */ diff --git a/drivers/video/b2r2/b2r2_hw_convert.c b/drivers/video/b2r2/b2r2_hw_convert.c new file mode 100644 index 00000000000..d1b44db79c3 --- /dev/null +++ b/drivers/video/b2r2/b2r2_hw_convert.c @@ -0,0 +1,747 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * ST-Ericsson B2R2 node splitter + * + * Author: Jorgen Nilsson <jorgen.nilsson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL), version 2. + */ + +#include "b2r2_hw_convert.h" +#include "b2r2_internal.h" +#include "b2r2_utils.h" + +/* + * Macros and constants + */ + +/* VMX register values for RGB to YUV color conversion */ +/* Magic numbers from 27.11 in DB8500_DesignSpecification_v2.5.pdf */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_RGB_TO_YUV_601_FULL_RANGE 0x107e4beb +#define B2R2_VMX1_RGB_TO_YUV_601_FULL_RANGE 0x0982581d +#define B2R2_VMX2_RGB_TO_YUV_601_FULL_RANGE 0xfa9ea483 +#define B2R2_VMX3_RGB_TO_YUV_601_FULL_RANGE 0x08000080 + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_RGB_TO_YUV_601_STANDARD 0x0e1e8bee +#define B2R2_VMX1_RGB_TO_YUV_601_STANDARD 0x08420419 +#define B2R2_VMX2_RGB_TO_YUV_601_STANDARD 0xfb5ed471 +#define B2R2_VMX3_RGB_TO_YUV_601_STANDARD 0x08004080 + +/* 709 Full range conversion matrix */ +#define B2R2_VMX0_RGB_TO_YUV_709_FULL_RANGE 0x107e27f4 +#define B2R2_VMX1_RGB_TO_YUV_709_FULL_RANGE 0x06e2dc13 +#define B2R2_VMX2_RGB_TO_YUV_709_FULL_RANGE 0xfc5e6c83 +#define B2R2_VMX3_RGB_TO_YUV_709_FULL_RANGE 0x08000080 + +/* 709 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_RGB_TO_YUV_709_STANDARD 0x0e3e6bf5 +#define B2R2_VMX1_RGB_TO_YUV_709_STANDARD 0x05e27410 +#define B2R2_VMX2_RGB_TO_YUV_709_STANDARD 0xfcdea471 +#define B2R2_VMX3_RGB_TO_YUV_709_STANDARD 0x08004080 + +/* VMX register values for YUV to RGB color conversion */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_YUV_TO_RGB_601_FULL_RANGE 0x2c440000 +#define B2R2_VMX1_YUV_TO_RGB_601_FULL_RANGE 0xe9a403aa +#define B2R2_VMX2_YUV_TO_RGB_601_FULL_RANGE 0x0004013f +#define B2R2_VMX3_YUV_TO_RGB_601_FULL_RANGE 0x34f21322 + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_YUV_TO_RGB_601_STANDARD 0x3324a800 +#define B2R2_VMX1_YUV_TO_RGB_601_STANDARD 0xe604ab9c +#define B2R2_VMX2_YUV_TO_RGB_601_STANDARD 0x0004a957 +#define B2R2_VMX3_YUV_TO_RGB_601_STANDARD 0x32121eeb + +/* 709 Full range conversion matrix */ +#define B2R2_VMX0_YUV_TO_RGB_709_FULL_RANGE 0x31440000 +#define B2R2_VMX1_YUV_TO_RGB_709_FULL_RANGE 0xf16403d1 +#define B2R2_VMX2_YUV_TO_RGB_709_FULL_RANGE 0x00040145 +#define B2R2_VMX3_YUV_TO_RGB_709_FULL_RANGE 0x33b14b18 + +/* 709 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_YUV_TO_RGB_709_STANDARD 0x3964a800 +#define B2R2_VMX1_YUV_TO_RGB_709_STANDARD 0xef04abc9 +#define B2R2_VMX2_YUV_TO_RGB_709_STANDARD 0x0004a95f +#define B2R2_VMX3_YUV_TO_RGB_709_STANDARD 0x307132df + +/* VMX register values for RGB to BGR conversion */ +#define B2R2_VMX0_RGB_TO_BGR 0x00000100 +#define B2R2_VMX1_RGB_TO_BGR 0x00040000 +#define B2R2_VMX2_RGB_TO_BGR 0x20000000 +#define B2R2_VMX3_RGB_TO_BGR 0x00000000 + +/* VMX register values for BGR to YUV color conversion */ +/* Note: All BGR -> YUV values are calculated by multiplying + * the RGB -> YUV matrices [A], with [S] to form [A]x[S] where + * |0 0 1| + * S = |0 1 0| + * |1 0 0| + * Essentially swapping first and third columns in + * the matrices (VMX0, VMX1 and VMX2 values). + * The offset vector VMX3 remains untouched. + * Put another way, the value of bits 0 through 9 + * is swapped with the value of + * bits 20 through 31 in VMX0, VMX1 and VMX2, + * taking into consideration the compression + * that is used on bits 0 through 9. Bit 0 being LSB. + */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_BGR_TO_YUV_601_FULL_RANGE 0xfd7e4883 +#define B2R2_VMX1_BGR_TO_YUV_601_FULL_RANGE 0x03a2584c +#define B2R2_VMX2_BGR_TO_YUV_601_FULL_RANGE 0x107ea7d4 +#define B2R2_VMX3_BGR_TO_YUV_601_FULL_RANGE 0x08000080 + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_BGR_TO_YUV_601_STANDARD 0xfdde8870 +#define B2R2_VMX1_BGR_TO_YUV_601_STANDARD 0x03220442 +#define B2R2_VMX2_BGR_TO_YUV_601_STANDARD 0x0e3ed7da +#define B2R2_VMX3_BGR_TO_YUV_601_STANDARD 0x08004080 + +/* 709 Full range conversion matrix */ +#define B2R2_VMX0_BGR_TO_YUV_709_FULL_RANGE 0xfe9e2483 +#define B2R2_VMX1_BGR_TO_YUV_709_FULL_RANGE 0x0262dc37 +#define B2R2_VMX2_BGR_TO_YUV_709_FULL_RANGE 0x107e6fe2 +#define B2R2_VMX3_BGR_TO_YUV_709_FULL_RANGE 0x08000080 + +/* 709 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_BGR_TO_YUV_709_STANDARD 0xfebe6871 +#define B2R2_VMX1_BGR_TO_YUV_709_STANDARD 0x0202742f +#define B2R2_VMX2_BGR_TO_YUV_709_STANDARD 0x0e3ea7e6 +#define B2R2_VMX3_BGR_TO_YUV_709_STANDARD 0x08004080 + + +/* VMX register values for YUV to BGR conversion */ +/* Note: All YUV -> BGR values are constructed + * from the YUV -> RGB ones, by swapping + * first and third rows in the matrix + * (VMX0 and VMX2 values). Further, the first and + * third values in the offset vector need to be + * swapped as well, i.e. bits 0 through 9 are swapped + * with bits 20 through 29 in the VMX3 value. + * Bit 0 being LSB. + */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_YUV_TO_BGR_601_FULL_RANGE (B2R2_VMX2_YUV_TO_RGB_601_FULL_RANGE) +#define B2R2_VMX1_YUV_TO_BGR_601_FULL_RANGE (B2R2_VMX1_YUV_TO_RGB_601_FULL_RANGE) +#define B2R2_VMX2_YUV_TO_BGR_601_FULL_RANGE (B2R2_VMX0_YUV_TO_RGB_601_FULL_RANGE) +#define B2R2_VMX3_YUV_TO_BGR_601_FULL_RANGE 0x3222134f + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_YUV_TO_BGR_601_STANDARD (B2R2_VMX2_YUV_TO_RGB_601_STANDARD) +#define B2R2_VMX1_YUV_TO_BGR_601_STANDARD (B2R2_VMX1_YUV_TO_RGB_601_STANDARD) +#define B2R2_VMX2_YUV_TO_BGR_601_STANDARD (B2R2_VMX0_YUV_TO_RGB_601_STANDARD) +#define B2R2_VMX3_YUV_TO_BGR_601_STANDARD 0x2eb21f21 + +/* 709 Full range conversion matrix */ +#define B2R2_VMX0_YUV_TO_BGR_709_FULL_RANGE (B2R2_VMX2_YUV_TO_RGB_709_FULL_RANGE) +#define B2R2_VMX1_YUV_TO_BGR_709_FULL_RANGE (B2R2_VMX1_YUV_TO_RGB_709_FULL_RANGE) +#define B2R2_VMX2_YUV_TO_BGR_709_FULL_RANGE (B2R2_VMX0_YUV_TO_RGB_709_FULL_RANGE) +#define B2R2_VMX3_YUV_TO_BGR_709_FULL_RANGE 0x31814b3b + +/* 709 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_YUV_TO_BGR_709_STANDARD (B2R2_VMX2_YUV_TO_RGB_709_STANDARD) +#define B2R2_VMX1_YUV_TO_BGR_709_STANDARD (B2R2_VMX1_YUV_TO_RGB_709_STANDARD) +#define B2R2_VMX2_YUV_TO_BGR_709_STANDARD (B2R2_VMX0_YUV_TO_RGB_709_STANDARD) +#define B2R2_VMX3_YUV_TO_BGR_709_STANDARD 0x2df13307 + + +/* VMX register values for YVU to RGB conversion */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_YVU_TO_RGB_601_FULL_RANGE 0x00040120 +#define B2R2_VMX1_YVU_TO_RGB_601_FULL_RANGE 0xF544034D +#define B2R2_VMX2_YVU_TO_RGB_601_FULL_RANGE 0x37840000 +#define B2R2_VMX3_YVU_TO_RGB_601_FULL_RANGE (B2R2_VMX3_YUV_TO_RGB_601_FULL_RANGE) + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_YVU_TO_RGB_601_STANDARD 0x0004A999 +#define B2R2_VMX1_YVU_TO_RGB_601_STANDARD 0xF384AB30 +#define B2R2_VMX2_YVU_TO_RGB_601_STANDARD 0x40A4A800 +#define B2R2_VMX3_YVU_TO_RGB_601_STANDARD (B2R2_VMX3_YUV_TO_RGB_601_STANDARD) + +/* VMX register values for RGB to YVU conversion */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_RGB_TO_YVU_601_FULL_RANGE (B2R2_VMX2_RGB_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX1_RGB_TO_YVU_601_FULL_RANGE (B2R2_VMX1_RGB_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX2_RGB_TO_YVU_601_FULL_RANGE (B2R2_VMX0_RGB_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX3_RGB_TO_YVU_601_FULL_RANGE (B2R2_VMX3_RGB_TO_YUV_601_FULL_RANGE) + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_RGB_TO_YVU_601_STANDARD (B2R2_VMX2_RGB_TO_YUV_601_STANDARD) +#define B2R2_VMX1_RGB_TO_YVU_601_STANDARD (B2R2_VMX1_RGB_TO_YUV_601_STANDARD) +#define B2R2_VMX2_RGB_TO_YVU_601_STANDARD (B2R2_VMX0_RGB_TO_YUV_601_STANDARD) +#define B2R2_VMX3_RGB_TO_YVU_601_STANDARD (B2R2_VMX3_RGB_TO_YUV_601_STANDARD) + +/* VMX register values for YVU to BGR conversion */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_YVU_TO_BGR_601_FULL_RANGE (B2R2_VMX2_YVU_TO_RGB_601_FULL_RANGE) +#define B2R2_VMX1_YVU_TO_BGR_601_FULL_RANGE (B2R2_VMX1_YVU_TO_RGB_601_FULL_RANGE) +#define B2R2_VMX2_YVU_TO_BGR_601_FULL_RANGE (B2R2_VMX0_YVU_TO_RGB_601_FULL_RANGE) +#define B2R2_VMX3_YVU_TO_BGR_601_FULL_RANGE 0x3222134F + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_YVU_TO_BGR_601_STANDARD (B2R2_VMX2_YVU_TO_RGB_601_STANDARD) +#define B2R2_VMX1_YVU_TO_BGR_601_STANDARD (B2R2_VMX1_YVU_TO_RGB_601_STANDARD) +#define B2R2_VMX2_YVU_TO_BGR_601_STANDARD (B2R2_VMX0_YVU_TO_RGB_601_STANDARD) +#define B2R2_VMX3_YVU_TO_BGR_601_STANDARD 0x3222134F + +/* VMX register values for BGR to YVU conversion */ + +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_BGR_TO_YVU_601_FULL_RANGE (B2R2_VMX2_BGR_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX1_BGR_TO_YVU_601_FULL_RANGE (B2R2_VMX1_BGR_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX2_BGR_TO_YVU_601_FULL_RANGE (B2R2_VMX0_BGR_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX3_BGR_TO_YVU_601_FULL_RANGE (B2R2_VMX3_BGR_TO_YUV_601_FULL_RANGE) + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_BGR_TO_YVU_601_STANDARD (B2R2_VMX2_BGR_TO_YUV_601_STANDARD) +#define B2R2_VMX1_BGR_TO_YVU_601_STANDARD (B2R2_VMX1_BGR_TO_YUV_601_STANDARD) +#define B2R2_VMX2_BGR_TO_YVU_601_STANDARD (B2R2_VMX0_BGR_TO_YUV_601_STANDARD) +#define B2R2_VMX3_BGR_TO_YVU_601_STANDARD (B2R2_VMX3_BGR_TO_YUV_601_STANDARD) + +/* VMX register values for YVU to YUV conversion */ + +/* 601 Video Matrix (standard 601 conversion) */ +/* Internally, the components are in fact stored + * with luma in the middle, i.e. UYV, which is why + * the values are just like for RGB->BGR conversion. + */ +#define B2R2_VMX0_YVU_TO_YUV 0x00000100 +#define B2R2_VMX1_YVU_TO_YUV 0x00040000 +#define B2R2_VMX2_YVU_TO_YUV 0x20000000 +#define B2R2_VMX3_YVU_TO_YUV 0x00000000 + +/* VMX register values for RGB to BLT_YUV888 conversion */ + +/* + * BLT_YUV888 has color components laid out in memory as V, U, Y, (Alpha) + * with V at the first byte (due to little endian addressing). + * B2R2 expects them to be as U, Y, V, (A) + * with U at the first byte. + * Note: RGB -> BLT_YUV888 values are calculated by multiplying + * the RGB -> YUV matrix [A], with [S] to form [S]x[A] where + * |0 1 0| + * S = |0 0 1| + * |1 0 0| + * Essentially changing the order of rows in the original + * matrix [A]. + * row1 -> row3 + * row2 -> row1 + * row3 -> row2 + * Values in the offset vector are swapped in the same manner. + */ +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_RGB_TO_BLT_YUV888_601_FULL_RANGE (B2R2_VMX1_RGB_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX1_RGB_TO_BLT_YUV888_601_FULL_RANGE (B2R2_VMX2_RGB_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX2_RGB_TO_BLT_YUV888_601_FULL_RANGE (B2R2_VMX0_RGB_TO_YUV_601_FULL_RANGE) +#define B2R2_VMX3_RGB_TO_BLT_YUV888_601_FULL_RANGE 0x00020080 + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_RGB_TO_BLT_YUV888_601_STANDARD (B2R2_VMX1_RGB_TO_YUV_601_STANDARD) +#define B2R2_VMX1_RGB_TO_BLT_YUV888_601_STANDARD (B2R2_VMX2_RGB_TO_YUV_601_STANDARD) +#define B2R2_VMX2_RGB_TO_BLT_YUV888_601_STANDARD (B2R2_VMX0_RGB_TO_YUV_601_STANDARD) +#define B2R2_VMX3_RGB_TO_BLT_YUV888_601_STANDARD 0x00020080 + +/* VMX register values for BLT_YUV888 to RGB conversion */ + +/* + * Note: BLT_YUV888 -> RGB values are calculated by multiplying + * the YUV -> RGB matrix [A], with [S] to form [A]x[S] where + * |0 0 1| + * S = |1 0 0| + * |0 1 0| + * Essentially changing the order of columns in the original + * matrix [A]. + * col1 -> col3 + * col2 -> col1 + * col3 -> col2 + * Values in the offset vector remain unchanged. + */ +/* 601 Full range conversion matrix */ +#define B2R2_VMX0_BLT_YUV888_TO_RGB_601_FULL_RANGE 0x20000121 +#define B2R2_VMX1_BLT_YUV888_TO_RGB_601_FULL_RANGE 0x201ea74c +#define B2R2_VMX2_BLT_YUV888_TO_RGB_601_FULL_RANGE 0x2006f000 +#define B2R2_VMX3_BLT_YUV888_TO_RGB_601_FULL_RANGE (B2R2_VMX3_YUV_TO_RGB_601_FULL_RANGE) + +/* 601 Standard (clamped) conversion matrix */ +#define B2R2_VMX0_BLT_YUV888_TO_RGB_601_STANDARD 0x25400133 +#define B2R2_VMX1_BLT_YUV888_TO_RGB_601_STANDARD 0x255E7330 +#define B2R2_VMX2_BLT_YUV888_TO_RGB_601_STANDARD 0x25481400 +#define B2R2_VMX3_BLT_YUV888_TO_RGB_601_STANDARD (B2R2_VMX3_YUV_TO_RGB_601_FULL_RANGE) + +/* VMX register values for YUV to BLT_YUV888 conversion */ +#define B2R2_VMX0_YUV_TO_BLT_YUV888 0x00040000 +#define B2R2_VMX1_YUV_TO_BLT_YUV888 0x00000100 +#define B2R2_VMX2_YUV_TO_BLT_YUV888 0x20000000 +#define B2R2_VMX3_YUV_TO_BLT_YUV888 0x00000000 + +/* VMX register values for BLT_YUV888 to YUV conversion */ +#define B2R2_VMX0_BLT_YUV888_TO_YUV 0x00000100 +#define B2R2_VMX1_BLT_YUV888_TO_YUV 0x20000000 +#define B2R2_VMX2_BLT_YUV888_TO_YUV 0x00040000 +#define B2R2_VMX3_BLT_YUV888_TO_YUV 0x00000000 + +/* VMX register values for YVU to BLT_YUV888 conversion */ +#define B2R2_VMX0_YVU_TO_BLT_YUV888 0x00040000 +#define B2R2_VMX1_YVU_TO_BLT_YUV888 0x20000000 +#define B2R2_VMX2_YVU_TO_BLT_YUV888 0x00000100 +#define B2R2_VMX3_YVU_TO_BLT_YUV888 0x00000000 + +/* VMX register values for BLT_YUV888 to YVU conversion */ +#define B2R2_VMX0_BLT_YUV888_TO_YVU 0x00040000 +#define B2R2_VMX1_BLT_YUV888_TO_YVU 0x20000000 +#define B2R2_VMX2_BLT_YUV888_TO_YVU 0x00000100 +#define B2R2_VMX3_BLT_YUV888_TO_YVU 0x00000000 + +/* + * Internal types + */ + +/* + * Global variables + */ + + /** + * VMx values for color space conversion + * (component swap) + */ +static const u32 vmx_yuv_to_blt_yuv888[] = { + B2R2_VMX0_YUV_TO_BLT_YUV888, + B2R2_VMX1_YUV_TO_BLT_YUV888, + B2R2_VMX2_YUV_TO_BLT_YUV888, + B2R2_VMX3_YUV_TO_BLT_YUV888, +}; + +static const u32 vmx_blt_yuv888_to_yuv[] = { + B2R2_VMX0_BLT_YUV888_TO_YUV, + B2R2_VMX1_BLT_YUV888_TO_YUV, + B2R2_VMX2_BLT_YUV888_TO_YUV, + B2R2_VMX3_BLT_YUV888_TO_YUV, +}; + +static const u32 vmx_yvu_to_blt_yuv888[] = { + B2R2_VMX0_YVU_TO_BLT_YUV888, + B2R2_VMX1_YVU_TO_BLT_YUV888, + B2R2_VMX2_YVU_TO_BLT_YUV888, + B2R2_VMX3_YVU_TO_BLT_YUV888, +}; + +static const u32 vmx_blt_yuv888_to_yvu[] = { + B2R2_VMX0_BLT_YUV888_TO_YVU, + B2R2_VMX1_BLT_YUV888_TO_YVU, + B2R2_VMX2_BLT_YUV888_TO_YVU, + B2R2_VMX3_BLT_YUV888_TO_YVU, +}; + +static const u32 vmx_rgb_to_bgr[] = { + B2R2_VMX0_RGB_TO_BGR, + B2R2_VMX1_RGB_TO_BGR, + B2R2_VMX2_RGB_TO_BGR, + B2R2_VMX3_RGB_TO_BGR, +}; + +static const u32 vmx_yvu_to_yuv[] = { + B2R2_VMX0_YVU_TO_YUV, + B2R2_VMX1_YVU_TO_YUV, + B2R2_VMX2_YVU_TO_YUV, + B2R2_VMX3_YVU_TO_YUV, +}; + +/** + * VMx values for color space conversions + * (standard 601 conversions) + */ +static const u32 vmx_rgb_to_yuv[] = { + B2R2_VMX0_RGB_TO_YUV_601_STANDARD, + B2R2_VMX1_RGB_TO_YUV_601_STANDARD, + B2R2_VMX2_RGB_TO_YUV_601_STANDARD, + B2R2_VMX3_RGB_TO_YUV_601_STANDARD, +}; + +static const u32 vmx_yuv_to_rgb[] = { + B2R2_VMX0_YUV_TO_RGB_601_STANDARD, + B2R2_VMX1_YUV_TO_RGB_601_STANDARD, + B2R2_VMX2_YUV_TO_RGB_601_STANDARD, + B2R2_VMX3_YUV_TO_RGB_601_STANDARD, +}; + +static const u32 vmx_rgb_to_blt_yuv888[] = { + B2R2_VMX0_RGB_TO_BLT_YUV888_601_STANDARD, + B2R2_VMX1_RGB_TO_BLT_YUV888_601_STANDARD, + B2R2_VMX2_RGB_TO_BLT_YUV888_601_STANDARD, + B2R2_VMX3_RGB_TO_BLT_YUV888_601_STANDARD, +}; + +static const u32 vmx_blt_yuv888_to_rgb[] = { + B2R2_VMX0_BLT_YUV888_TO_RGB_601_STANDARD, + B2R2_VMX1_BLT_YUV888_TO_RGB_601_STANDARD, + B2R2_VMX2_BLT_YUV888_TO_RGB_601_STANDARD, + B2R2_VMX3_BLT_YUV888_TO_RGB_601_STANDARD, +}; + +static const u32 vmx_rgb_to_yvu[] = { + B2R2_VMX0_RGB_TO_YVU_601_STANDARD, + B2R2_VMX1_RGB_TO_YVU_601_STANDARD, + B2R2_VMX2_RGB_TO_YVU_601_STANDARD, + B2R2_VMX3_RGB_TO_YVU_601_STANDARD, +}; + +static const u32 vmx_yvu_to_rgb[] = { + B2R2_VMX0_YVU_TO_RGB_601_STANDARD, + B2R2_VMX1_YVU_TO_RGB_601_STANDARD, + B2R2_VMX2_YVU_TO_RGB_601_STANDARD, + B2R2_VMX3_YVU_TO_RGB_601_STANDARD, +}; + +static const u32 vmx_bgr_to_yuv[] = { + B2R2_VMX0_BGR_TO_YUV_601_STANDARD, + B2R2_VMX1_BGR_TO_YUV_601_STANDARD, + B2R2_VMX2_BGR_TO_YUV_601_STANDARD, + B2R2_VMX3_BGR_TO_YUV_601_STANDARD, +}; + +static const u32 vmx_yuv_to_bgr[] = { + B2R2_VMX0_YUV_TO_BGR_601_STANDARD, + B2R2_VMX1_YUV_TO_BGR_601_STANDARD, + B2R2_VMX2_YUV_TO_BGR_601_STANDARD, + B2R2_VMX3_YUV_TO_BGR_601_STANDARD, +}; + +static const u32 vmx_bgr_to_yvu[] = { + B2R2_VMX0_BGR_TO_YVU_601_STANDARD, + B2R2_VMX1_BGR_TO_YVU_601_STANDARD, + B2R2_VMX2_BGR_TO_YVU_601_STANDARD, + B2R2_VMX3_BGR_TO_YVU_601_STANDARD, +}; + +static const u32 vmx_yvu_to_bgr[] = { + B2R2_VMX0_YVU_TO_BGR_601_STANDARD, + B2R2_VMX1_YVU_TO_BGR_601_STANDARD, + B2R2_VMX2_YVU_TO_BGR_601_STANDARD, + B2R2_VMX3_YVU_TO_BGR_601_STANDARD, +}; + +/** + * VMx values for color space conversions + * (full range conversions) + */ + +static const u32 vmx_full_rgb_to_yuv[] = { + B2R2_VMX0_RGB_TO_YUV_601_FULL_RANGE, + B2R2_VMX1_RGB_TO_YUV_601_FULL_RANGE, + B2R2_VMX2_RGB_TO_YUV_601_FULL_RANGE, + B2R2_VMX3_RGB_TO_YUV_601_FULL_RANGE, +}; + +static const u32 vmx_full_yuv_to_rgb[] = { + B2R2_VMX0_YUV_TO_RGB_601_FULL_RANGE, + B2R2_VMX1_YUV_TO_RGB_601_FULL_RANGE, + B2R2_VMX2_YUV_TO_RGB_601_FULL_RANGE, + B2R2_VMX3_YUV_TO_RGB_601_FULL_RANGE, +}; + +static const u32 vmx_full_rgb_to_blt_yuv888[] = { + B2R2_VMX0_RGB_TO_BLT_YUV888_601_FULL_RANGE, + B2R2_VMX1_RGB_TO_BLT_YUV888_601_FULL_RANGE, + B2R2_VMX2_RGB_TO_BLT_YUV888_601_FULL_RANGE, + B2R2_VMX3_RGB_TO_BLT_YUV888_601_FULL_RANGE, +}; + +static const u32 vmx_full_blt_yuv888_to_rgb[] = { + B2R2_VMX0_BLT_YUV888_TO_RGB_601_FULL_RANGE, + B2R2_VMX1_BLT_YUV888_TO_RGB_601_FULL_RANGE, + B2R2_VMX2_BLT_YUV888_TO_RGB_601_FULL_RANGE, + B2R2_VMX3_BLT_YUV888_TO_RGB_601_FULL_RANGE, +}; + +static const u32 vmx_full_yvu_to_rgb[] = { + B2R2_VMX0_YVU_TO_RGB_601_FULL_RANGE, + B2R2_VMX1_YVU_TO_RGB_601_FULL_RANGE, + B2R2_VMX2_YVU_TO_RGB_601_FULL_RANGE, + B2R2_VMX3_YVU_TO_RGB_601_FULL_RANGE, +}; + +static const u32 vmx_full_rgb_to_yvu[] = { + B2R2_VMX0_RGB_TO_YVU_601_FULL_RANGE, + B2R2_VMX1_RGB_TO_YVU_601_FULL_RANGE, + B2R2_VMX2_RGB_TO_YVU_601_FULL_RANGE, + B2R2_VMX3_RGB_TO_YVU_601_FULL_RANGE, +}; + +static const u32 vmx_full_bgr_to_yuv[] = { + B2R2_VMX0_BGR_TO_YUV_601_FULL_RANGE, + B2R2_VMX1_BGR_TO_YUV_601_FULL_RANGE, + B2R2_VMX2_BGR_TO_YUV_601_FULL_RANGE, + B2R2_VMX3_BGR_TO_YUV_601_FULL_RANGE, +}; + +static const u32 vmx_full_yuv_to_bgr[] = { + B2R2_VMX0_YUV_TO_BGR_601_FULL_RANGE, + B2R2_VMX1_YUV_TO_BGR_601_FULL_RANGE, + B2R2_VMX2_YUV_TO_BGR_601_FULL_RANGE, + B2R2_VMX3_YUV_TO_BGR_601_FULL_RANGE, +}; + +static const u32 vmx_full_bgr_to_yvu[] = { + B2R2_VMX0_BGR_TO_YVU_601_FULL_RANGE, + B2R2_VMX1_BGR_TO_YVU_601_FULL_RANGE, + B2R2_VMX2_BGR_TO_YVU_601_FULL_RANGE, + B2R2_VMX3_BGR_TO_YVU_601_FULL_RANGE, +}; + +static const u32 vmx_full_yvu_to_bgr[] = { + B2R2_VMX0_YVU_TO_BGR_601_FULL_RANGE, + B2R2_VMX1_YVU_TO_BGR_601_FULL_RANGE, + B2R2_VMX2_YVU_TO_BGR_601_FULL_RANGE, + B2R2_VMX3_YVU_TO_BGR_601_FULL_RANGE, +}; + +/* + * Forward declaration of private functions + */ + +/* + * Public functions + */ + +/** + * Setup input versatile matrix for color space conversion + */ +int b2r2_setup_ivmx(struct b2r2_node *node, enum b2r2_color_conversion cc) +{ + const u32 *vmx = NULL; + + if (b2r2_get_vmx(cc, &vmx) < 0 || vmx == NULL) + return -1; + + node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED; + node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX; + + node->node.GROUP15.B2R2_VMX0 = vmx[0]; + node->node.GROUP15.B2R2_VMX1 = vmx[1]; + node->node.GROUP15.B2R2_VMX2 = vmx[2]; + node->node.GROUP15.B2R2_VMX3 = vmx[3]; + + return 0; +} + +/** + * Setup output versatile matrix for color space conversion + */ +int b2r2_setup_ovmx(struct b2r2_node *node, enum b2r2_color_conversion cc) +{ + const u32 *vmx = NULL; + + if (b2r2_get_vmx(cc, &vmx) < 0 || vmx == NULL) + return -1; + + node->node.GROUP0.B2R2_INS |= B2R2_INS_OVMX_ENABLED; + node->node.GROUP0.B2R2_CIC |= B2R2_CIC_OVMX; + + node->node.GROUP16.B2R2_VMX0 = vmx[0]; + node->node.GROUP16.B2R2_VMX1 = vmx[1]; + node->node.GROUP16.B2R2_VMX2 = vmx[2]; + node->node.GROUP16.B2R2_VMX3 = vmx[3]; + + return 0; +} + +enum b2r2_color_conversion b2r2_get_color_conversion(enum b2r2_blt_fmt src_fmt, + enum b2r2_blt_fmt dst_fmt, bool fullrange) +{ + if (b2r2_is_rgb_fmt(src_fmt)) { + if (b2r2_is_yvu_fmt(dst_fmt)) + return fullrange ? B2R2_CC_RGB_TO_YVU_FULL : + B2R2_CC_RGB_TO_YVU; + else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || + dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) + /* + * (A)YUV/VUY(A) formats differ only in component + * order. This is handled by the endianness bit + * in B2R2_STY/TTY registers when src/target are set. + */ + return fullrange ? B2R2_CC_RGB_TO_BLT_YUV888_FULL : + B2R2_CC_RGB_TO_BLT_YUV888; + else if (b2r2_is_yuv_fmt(dst_fmt)) + return fullrange ? B2R2_CC_RGB_TO_YUV_FULL : + B2R2_CC_RGB_TO_YUV; + else if (b2r2_is_bgr_fmt(dst_fmt)) + return B2R2_CC_RGB_TO_BGR; + } else if (b2r2_is_yvu_fmt(src_fmt)) { + if (b2r2_is_rgb_fmt(dst_fmt)) + return fullrange ? B2R2_CC_YVU_FULL_TO_RGB : + B2R2_CC_YVU_TO_RGB; + else if (b2r2_is_bgr_fmt(dst_fmt)) + return fullrange ? B2R2_CC_YVU_FULL_TO_BGR : + B2R2_CC_YVU_TO_BGR; + else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || + dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) + return B2R2_CC_YVU_TO_BLT_YUV888; + else if (b2r2_is_yuv_fmt(dst_fmt) && + !b2r2_is_yvu_fmt(dst_fmt)) + return B2R2_CC_YVU_TO_YUV; + } else if (src_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || + src_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || + src_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || + src_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) { + /* + * (A)YUV/VUY(A) formats differ only in component + * order. This is handled by the endianness bit + * in B2R2_STY/TTY registers when src/target are set. + */ + if (b2r2_is_rgb_fmt(dst_fmt)) + return fullrange ? B2R2_CC_BLT_YUV888_FULL_TO_RGB : + B2R2_CC_BLT_YUV888_TO_RGB; + else if (b2r2_is_yvu_fmt(dst_fmt)) + return B2R2_CC_BLT_YUV888_TO_YVU; + else if (b2r2_is_yuv_fmt(dst_fmt)) { + switch (dst_fmt) { + case B2R2_BLT_FMT_24_BIT_YUV888: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + case B2R2_BLT_FMT_24_BIT_VUY888: + case B2R2_BLT_FMT_32_BIT_VUYA8888: + return B2R2_CC_NOTHING; + default: + return B2R2_CC_BLT_YUV888_TO_YUV; + } + } + } else if (b2r2_is_yuv_fmt(src_fmt)) { + if (b2r2_is_rgb_fmt(dst_fmt)) + return fullrange ? B2R2_CC_YUV_FULL_TO_RGB : + B2R2_CC_YUV_TO_RGB; + else if (b2r2_is_bgr_fmt(dst_fmt)) + return fullrange ? B2R2_CC_YUV_FULL_TO_BGR : + B2R2_CC_YUV_TO_BGR; + else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || + dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) + return B2R2_CC_YUV_TO_BLT_YUV888; + else if (b2r2_is_yvu_fmt(dst_fmt)) + return B2R2_CC_YVU_TO_YUV; + } else if (b2r2_is_bgr_fmt(src_fmt)) { + if (b2r2_is_rgb_fmt(dst_fmt)) + return B2R2_CC_RGB_TO_BGR; + else if (b2r2_is_yvu_fmt(dst_fmt)) + return fullrange ? B2R2_CC_BGR_TO_YVU_FULL : + B2R2_CC_BGR_TO_YVU; + else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || + dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || + dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) + BUG_ON(1); + else if (b2r2_is_yuv_fmt(dst_fmt)) + return fullrange ? B2R2_CC_BGR_TO_YUV_FULL : + B2R2_CC_BGR_TO_YUV; + } + + return B2R2_CC_NOTHING; +} + +int b2r2_get_vmx(enum b2r2_color_conversion cc, const u32 **vmx) +{ + if (vmx == NULL) + return -1; + + switch (cc) { + case B2R2_CC_RGB_TO_BGR: + *vmx = &vmx_rgb_to_bgr[0]; + break; + case B2R2_CC_BLT_YUV888_TO_YVU: + *vmx = &vmx_blt_yuv888_to_yvu[0]; + break; + case B2R2_CC_BLT_YUV888_TO_YUV: + *vmx = &vmx_blt_yuv888_to_yuv[0]; + break; + case B2R2_CC_YVU_TO_YUV: + *vmx = &vmx_yvu_to_yuv[0]; + break; + case B2R2_CC_YVU_TO_BLT_YUV888: + *vmx = &vmx_yvu_to_blt_yuv888[0]; + break; + case B2R2_CC_YUV_TO_BLT_YUV888: + *vmx = &vmx_yuv_to_blt_yuv888[0]; + break; + case B2R2_CC_RGB_TO_YUV: + *vmx = &vmx_rgb_to_yuv[0]; + break; + case B2R2_CC_RGB_TO_YUV_FULL: + *vmx = &vmx_full_rgb_to_yuv[0]; + break; + case B2R2_CC_RGB_TO_YVU: + *vmx = &vmx_rgb_to_yvu[0]; + break; + case B2R2_CC_RGB_TO_YVU_FULL: + *vmx = &vmx_full_rgb_to_yvu[0]; + break; + case B2R2_CC_RGB_TO_BLT_YUV888: + *vmx = &vmx_rgb_to_blt_yuv888[0]; + break; + case B2R2_CC_RGB_TO_BLT_YUV888_FULL: + *vmx = &vmx_full_rgb_to_blt_yuv888[0]; + break; + case B2R2_CC_BGR_TO_YVU: + *vmx = &vmx_bgr_to_yvu[0]; + break; + case B2R2_CC_BGR_TO_YVU_FULL: + *vmx = &vmx_full_bgr_to_yvu[0]; + break; + case B2R2_CC_BGR_TO_YUV: + *vmx = &vmx_bgr_to_yuv[0]; + break; + case B2R2_CC_BGR_TO_YUV_FULL: + *vmx = &vmx_full_bgr_to_yuv[0]; + break; + case B2R2_CC_YUV_TO_RGB: + *vmx = &vmx_yuv_to_rgb[0]; + break; + case B2R2_CC_YUV_FULL_TO_RGB: + *vmx = &vmx_full_yuv_to_rgb[0]; + break; + case B2R2_CC_YUV_TO_BGR: + *vmx = &vmx_yuv_to_bgr[0]; + break; + case B2R2_CC_YUV_FULL_TO_BGR: + *vmx = &vmx_full_yuv_to_bgr[0]; + break; + case B2R2_CC_YVU_TO_RGB: + *vmx = &vmx_yvu_to_rgb[0]; + break; + case B2R2_CC_YVU_FULL_TO_RGB: + *vmx = &vmx_full_yvu_to_rgb[0]; + break; + case B2R2_CC_YVU_TO_BGR: + *vmx = &vmx_yvu_to_bgr[0]; + break; + case B2R2_CC_YVU_FULL_TO_BGR: + *vmx = &vmx_full_yvu_to_bgr[0]; + break; + case B2R2_CC_BLT_YUV888_TO_RGB: + *vmx = &vmx_blt_yuv888_to_rgb[0]; + break; + case B2R2_CC_BLT_YUV888_FULL_TO_RGB: + *vmx = &vmx_full_blt_yuv888_to_rgb[0]; + break; + case B2R2_CC_NOTHING: + default: + break; + } + + return 0; +} + + diff --git a/drivers/video/b2r2/b2r2_hw_convert.h b/drivers/video/b2r2/b2r2_hw_convert.h new file mode 100644 index 00000000000..e173e898e44 --- /dev/null +++ b/drivers/video/b2r2/b2r2_hw_convert.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * ST-Ericsson B2R2 hw color conversion definitions + * + * Author: Jorgen Nilsson <jorgen.nilsson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL), version 2. + */ + +#ifndef B2R2_HW_CONVERT_H__ +#define B2R2_HW_CONVERT_H__ + +#include "b2r2_internal.h" + +enum b2r2_color_conversion { + B2R2_CC_NOTHING = 0, + B2R2_CC_RGB_TO_BGR, + B2R2_CC_BLT_YUV888_TO_YVU, + B2R2_CC_BLT_YUV888_TO_YUV, + B2R2_CC_YUV_TO_BLT_YUV888, + B2R2_CC_YVU_TO_YUV, + B2R2_CC_YVU_TO_BLT_YUV888, + B2R2_CC_RGB_TO_YUV, + B2R2_CC_RGB_TO_YUV_FULL, + B2R2_CC_RGB_TO_YVU, + B2R2_CC_RGB_TO_YVU_FULL, + B2R2_CC_RGB_TO_BLT_YUV888, + B2R2_CC_RGB_TO_BLT_YUV888_FULL, + B2R2_CC_BGR_TO_YVU, + B2R2_CC_BGR_TO_YVU_FULL, + B2R2_CC_BGR_TO_YUV, + B2R2_CC_BGR_TO_YUV_FULL, + B2R2_CC_YUV_TO_RGB, + B2R2_CC_YUV_FULL_TO_RGB, + B2R2_CC_YUV_TO_BGR, + B2R2_CC_YUV_FULL_TO_BGR, + B2R2_CC_YVU_TO_RGB, + B2R2_CC_YVU_FULL_TO_RGB, + B2R2_CC_YVU_TO_BGR, + B2R2_CC_YVU_FULL_TO_BGR, + B2R2_CC_BLT_YUV888_TO_RGB, + B2R2_CC_BLT_YUV888_FULL_TO_RGB, +}; + +int b2r2_setup_ivmx(struct b2r2_node *node, enum b2r2_color_conversion cc); +int b2r2_setup_ovmx(struct b2r2_node *node, enum b2r2_color_conversion cc); +enum b2r2_color_conversion b2r2_get_color_conversion(enum b2r2_blt_fmt src_fmt, + enum b2r2_blt_fmt dst_fmt, bool fullrange); +int b2r2_get_vmx(enum b2r2_color_conversion cc, const u32 **vmx); + +#endif /* B2R2_HW_CONVERT_H__ */ diff --git a/drivers/video/b2r2/b2r2_internal.h b/drivers/video/b2r2/b2r2_internal.h index 7a46bbda19e..c46e814df14 100644 --- a/drivers/video/b2r2/b2r2_internal.h +++ b/drivers/video/b2r2/b2r2_internal.h @@ -264,6 +264,8 @@ struct b2r2_node_split_buf { * @ivmx - the ivmx matrix to use for color conversion * @blend - determines if blending is enabled * @clip - determines if destination clipping is enabled + * @rotation - determines if rotation is requested + * @fullrange - determines YUV<->RGB conversion matrix (iVMx) * @swap_fg_bg - determines if FG and BG should be swapped when blending * @flags - the flags passed in the blt request * @flag_param - parameter required by certain flags, @@ -294,6 +296,7 @@ struct b2r2_node_split_job { bool blend; bool clip; bool rotation; + bool fullrange; bool swap_fg_bg; diff --git a/drivers/video/b2r2/b2r2_node_split.c b/drivers/video/b2r2/b2r2_node_split.c index 6587ef0c343..d773865223b 100644 --- a/drivers/video/b2r2/b2r2_node_split.c +++ b/drivers/video/b2r2/b2r2_node_split.c @@ -12,7 +12,7 @@ #include "b2r2_debug.h" #include "b2r2_node_split.h" #include "b2r2_internal.h" -#include "b2r2_hw.h" +#include "b2r2_hw_convert.h" #include "b2r2_filters.h" #include "b2r2_utils.h" @@ -37,120 +37,6 @@ * Global variables */ -/** - * VMX values for different color space conversions - */ -static const u32 vmx_rgb_to_yuv[] = { - B2R2_VMX0_RGB_TO_YUV_601_VIDEO, - B2R2_VMX1_RGB_TO_YUV_601_VIDEO, - B2R2_VMX2_RGB_TO_YUV_601_VIDEO, - B2R2_VMX3_RGB_TO_YUV_601_VIDEO, -}; - -static const u32 vmx_rgb_to_blt_yuv888[] = { - B2R2_VMX0_RGB_TO_BLT_YUV888_601_VIDEO, - B2R2_VMX1_RGB_TO_BLT_YUV888_601_VIDEO, - B2R2_VMX2_RGB_TO_BLT_YUV888_601_VIDEO, - B2R2_VMX3_RGB_TO_BLT_YUV888_601_VIDEO, -}; - -static const u32 vmx_yuv_to_rgb[] = { - B2R2_VMX0_YUV_TO_RGB_601_VIDEO, - B2R2_VMX1_YUV_TO_RGB_601_VIDEO, - B2R2_VMX2_YUV_TO_RGB_601_VIDEO, - B2R2_VMX3_YUV_TO_RGB_601_VIDEO, -}; - -static const u32 vmx_blt_yuv888_to_rgb[] = { - B2R2_VMX0_BLT_YUV888_TO_RGB_601_VIDEO, - B2R2_VMX1_BLT_YUV888_TO_RGB_601_VIDEO, - B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO, - B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO, -}; - -static const u32 vmx_yuv_to_blt_yuv888[] = { - B2R2_VMX0_YUV_TO_BLT_YUV888, - B2R2_VMX1_YUV_TO_BLT_YUV888, - B2R2_VMX2_YUV_TO_BLT_YUV888, - B2R2_VMX3_YUV_TO_BLT_YUV888, -}; - -static const u32 vmx_blt_yuv888_to_yuv[] = { - B2R2_VMX0_BLT_YUV888_TO_YUV, - B2R2_VMX1_BLT_YUV888_TO_YUV, - B2R2_VMX2_BLT_YUV888_TO_YUV, - B2R2_VMX3_BLT_YUV888_TO_YUV, -}; - -static const u32 vmx_yvu_to_blt_yuv888[] = { - B2R2_VMX0_YVU_TO_BLT_YUV888, - B2R2_VMX1_YVU_TO_BLT_YUV888, - B2R2_VMX2_YVU_TO_BLT_YUV888, - B2R2_VMX3_YVU_TO_BLT_YUV888, -}; - -static const u32 vmx_blt_yuv888_to_yvu[] = { - B2R2_VMX0_BLT_YUV888_TO_YVU, - B2R2_VMX1_BLT_YUV888_TO_YVU, - B2R2_VMX2_BLT_YUV888_TO_YVU, - B2R2_VMX3_BLT_YUV888_TO_YVU, -}; - -static const u32 vmx_yvu_to_rgb[] = { - B2R2_VMX0_YVU_TO_RGB_601_VIDEO, - B2R2_VMX1_YVU_TO_RGB_601_VIDEO, - B2R2_VMX2_YVU_TO_RGB_601_VIDEO, - B2R2_VMX3_YVU_TO_RGB_601_VIDEO, -}; - -static const u32 vmx_rgb_to_yvu[] = { - B2R2_VMX0_RGB_TO_YVU_601_VIDEO, - B2R2_VMX1_RGB_TO_YVU_601_VIDEO, - B2R2_VMX2_RGB_TO_YVU_601_VIDEO, - B2R2_VMX3_RGB_TO_YVU_601_VIDEO, -}; - -static const u32 vmx_rgb_to_bgr[] = { - B2R2_VMX0_RGB_TO_BGR, - B2R2_VMX1_RGB_TO_BGR, - B2R2_VMX2_RGB_TO_BGR, - B2R2_VMX3_RGB_TO_BGR, -}; - -static const u32 vmx_bgr_to_yuv[] = { - B2R2_VMX0_BGR_TO_YUV_601_VIDEO, - B2R2_VMX1_BGR_TO_YUV_601_VIDEO, - B2R2_VMX2_BGR_TO_YUV_601_VIDEO, - B2R2_VMX3_BGR_TO_YUV_601_VIDEO, -}; - -static const u32 vmx_yuv_to_bgr[] = { - B2R2_VMX0_YUV_TO_BGR_601_VIDEO, - B2R2_VMX1_YUV_TO_BGR_601_VIDEO, - B2R2_VMX2_YUV_TO_BGR_601_VIDEO, - B2R2_VMX3_YUV_TO_BGR_601_VIDEO, -}; - -static const u32 vmx_bgr_to_yvu[] = { - B2R2_VMX0_BGR_TO_YVU_601_VIDEO, - B2R2_VMX1_BGR_TO_YVU_601_VIDEO, - B2R2_VMX2_BGR_TO_YVU_601_VIDEO, - B2R2_VMX3_BGR_TO_YVU_601_VIDEO, -}; - -static const u32 vmx_yvu_to_bgr[] = { - B2R2_VMX0_YVU_TO_BGR_601_VIDEO, - B2R2_VMX1_YVU_TO_BGR_601_VIDEO, - B2R2_VMX2_YVU_TO_BGR_601_VIDEO, - B2R2_VMX3_YVU_TO_BGR_601_VIDEO, -}; - -static const u32 vmx_yvu_to_yuv[] = { - B2R2_VMX0_YVU_TO_YUV_601_VIDEO, - B2R2_VMX1_YVU_TO_YUV_601_VIDEO, - B2R2_VMX2_YVU_TO_YUV_601_VIDEO, - B2R2_VMX3_YVU_TO_YUV_601_VIDEO, -}; /* * Forward declaration of private functions @@ -158,7 +44,8 @@ static const u32 vmx_yvu_to_yuv[] = { static int analyze_fmt_conv(struct b2r2_control *cont, struct b2r2_node_split_buf *src, struct b2r2_node_split_buf *dst, - const u32 **vmx, u32 *node_count); + const u32 **vmx, u32 *node_count, + bool fullrange); static int analyze_color_fill(struct b2r2_node_split_job *this, const struct b2r2_blt_request *req, u32 *node_count); static int analyze_copy(struct b2r2_node_split_job *this, @@ -239,26 +126,6 @@ static int setup_tmp_buf(struct b2r2_control *cont, struct b2r2_node_split_buf *this, u32 max_size, enum b2r2_blt_fmt pref_fmt, u32 pref_width, u32 pref_height); -static enum b2r2_ty get_alpha_range(enum b2r2_blt_fmt fmt); -static u32 set_alpha(enum b2r2_blt_fmt fmt, u8 alpha, u32 color); -static u8 get_alpha(enum b2r2_blt_fmt fmt, u32 pixel); -static bool fmt_has_alpha(enum b2r2_blt_fmt fmt); - -static bool is_rgb_fmt(enum b2r2_blt_fmt fmt); -static bool is_bgr_fmt(enum b2r2_blt_fmt fmt); -static bool is_yuv_fmt(enum b2r2_blt_fmt fmt); -static bool is_yvu_fmt(enum b2r2_blt_fmt fmt); -static bool is_yuv420_fmt(enum b2r2_blt_fmt fmt); -static bool is_yuv422_fmt(enum b2r2_blt_fmt fmt); -static bool is_yuv444_fmt(enum b2r2_blt_fmt fmt); -static bool is_yvu420_fmt(enum b2r2_blt_fmt fmt); -static bool is_yvu422_fmt(enum b2r2_blt_fmt fmt); - -static int fmt_byte_pitch(enum b2r2_blt_fmt fmt, u32 width); -static enum b2r2_native_fmt to_native_fmt(enum b2r2_blt_fmt fmt); -static u32 to_RGB888(u32 color, const enum b2r2_blt_fmt fmt); -static enum b2r2_fmt_type get_fmt_type(enum b2r2_blt_fmt fmt); - static bool is_transform(const struct b2r2_blt_request *req); static s32 rescale(struct b2r2_control *cont, s32 dim, u16 sf); static s32 inv_rescale(s32 dim, u16 sf); @@ -318,7 +185,7 @@ int b2r2_node_split_analyze(const struct b2r2_blt_request *req, case B2R2_BLT_FMT_32_BIT_AYUV8888: case B2R2_BLT_FMT_24_BIT_VUY888: case B2R2_BLT_FMT_32_BIT_VUYA8888: - if (is_bgr_fmt(req->user_req.dst_img.fmt)) { + if (b2r2_is_bgr_fmt(req->user_req.dst_img.fmt)) { ret = -ENOSYS; goto unsupported; } @@ -333,7 +200,7 @@ int b2r2_node_split_analyze(const struct b2r2_blt_request *req, case B2R2_BLT_FMT_32_BIT_AYUV8888: case B2R2_BLT_FMT_24_BIT_VUY888: case B2R2_BLT_FMT_32_BIT_VUYA8888: - if (is_bgr_fmt(req->user_req.src_img.fmt)) { + if (b2r2_is_bgr_fmt(req->user_req.src_img.fmt)) { ret = -ENOSYS; goto unsupported; } @@ -359,7 +226,7 @@ int b2r2_node_split_analyze(const struct b2r2_blt_request *req, } if ((this->flags & B2R2_BLT_FLAG_SOURCE_COLOR_KEY) && - (is_yuv_fmt(req->user_req.src_img.fmt) || + (b2r2_is_yuv_fmt(req->user_req.src_img.fmt) || req->user_req.src_img.fmt == B2R2_BLT_FMT_1_BIT_A1 || req->user_req.src_img.fmt == B2R2_BLT_FMT_8_BIT_A8)) { b2r2_log_warn(cont->dev, "%s: Unsupported: source color keying " @@ -430,11 +297,15 @@ int b2r2_node_split_analyze(const struct b2r2_blt_request *req, (this->global_alpha != 255)) this->blend = true; else if (this->flags & B2R2_BLT_FLAG_PER_PIXEL_ALPHA_BLEND) - this->blend = (color_fill && fmt_has_alpha(this->dst.fmt)) || - fmt_has_alpha(this->src.fmt); + this->blend = (color_fill && b2r2_fmt_has_alpha(this->dst.fmt)) || + b2r2_fmt_has_alpha(this->src.fmt); else if (this->flags & B2R2_BLT_FLAG_BG_BLEND) this->blend = true; + /* Check for full range YUV conversion */ + if (this->flags & B2R2_BLT_FLAG_FULL_RANGE_YUV) + this->fullrange = true; + if (this->blend && this->src.type == B2R2_FMT_TYPE_PLANAR) { b2r2_log_warn(cont->dev, "%s: Unsupported: blend with planar" " source\n", __func__); @@ -511,9 +382,9 @@ int b2r2_node_split_analyze(const struct b2r2_blt_request *req, * likely a bug in the hardware. */ upsample = this->src.type != B2R2_FMT_TYPE_RASTER && - is_yuv_fmt(this->src.fmt); + b2r2_is_yuv_fmt(this->src.fmt); downsample = this->dst.type != B2R2_FMT_TYPE_RASTER && - is_yuv_fmt(this->dst.fmt); + b2r2_is_yuv_fmt(this->dst.fmt); if (is_transform(req) || upsample || downsample) ret = analyze_transform(this, req, &this->node_count, @@ -798,40 +669,40 @@ error: static bool bg_format_require_ivmx(enum b2r2_blt_fmt bg_fmt, enum b2r2_blt_fmt dst_fmt) { - if (is_rgb_fmt(bg_fmt)) { - if (is_yvu_fmt(dst_fmt)) + if (b2r2_is_rgb_fmt(bg_fmt)) { + if (b2r2_is_yvu_fmt(dst_fmt)) return true; else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) return true; - else if (is_yuv_fmt(dst_fmt)) + else if (b2r2_is_yuv_fmt(dst_fmt)) return true; - else if (is_bgr_fmt(dst_fmt)) + else if (b2r2_is_bgr_fmt(dst_fmt)) return true; - } else if (is_yvu_fmt(bg_fmt)) { - if (is_rgb_fmt(dst_fmt)) + } else if (b2r2_is_yvu_fmt(bg_fmt)) { + if (b2r2_is_rgb_fmt(dst_fmt)) return true; - else if (is_bgr_fmt(dst_fmt)) + else if (b2r2_is_bgr_fmt(dst_fmt)) return true; else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) return true; - else if (is_yuv_fmt(dst_fmt) && - !is_yvu_fmt(dst_fmt)) + else if (b2r2_is_yuv_fmt(dst_fmt) && + !b2r2_is_yvu_fmt(dst_fmt)) return true; } else if (bg_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || bg_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || bg_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || bg_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) { - if (is_rgb_fmt(dst_fmt)) { + if (b2r2_is_rgb_fmt(dst_fmt)) { return true; - } else if (is_yvu_fmt(dst_fmt)) { + } else if (b2r2_is_yvu_fmt(dst_fmt)) { return true; - } else if (is_yuv_fmt(dst_fmt)) { + } else if (b2r2_is_yuv_fmt(dst_fmt)) { switch (dst_fmt) { case B2R2_BLT_FMT_24_BIT_YUV888: case B2R2_BLT_FMT_32_BIT_AYUV8888: @@ -842,29 +713,29 @@ static bool bg_format_require_ivmx(enum b2r2_blt_fmt bg_fmt, return true; } } - } else if (is_yuv_fmt(bg_fmt)) { - if (is_rgb_fmt(dst_fmt)) + } else if (b2r2_is_yuv_fmt(bg_fmt)) { + if (b2r2_is_rgb_fmt(dst_fmt)) return true; - else if (is_bgr_fmt(dst_fmt)) + else if (b2r2_is_bgr_fmt(dst_fmt)) return true; else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) return true; - else if (is_yvu_fmt(dst_fmt)) + else if (b2r2_is_yvu_fmt(dst_fmt)) return true; - } else if (is_bgr_fmt(bg_fmt)) { - if (is_rgb_fmt(dst_fmt)) + } else if (b2r2_is_bgr_fmt(bg_fmt)) { + if (b2r2_is_rgb_fmt(dst_fmt)) return true; - else if (is_yvu_fmt(dst_fmt)) + else if (b2r2_is_yvu_fmt(dst_fmt)) return true; else if (dst_fmt == B2R2_BLT_FMT_24_BIT_YUV888 || dst_fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 || dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) return true; - else if (is_yuv_fmt(dst_fmt)) + else if (b2r2_is_yuv_fmt(dst_fmt)) return true; } @@ -877,88 +748,12 @@ static bool bg_format_require_ivmx(enum b2r2_blt_fmt bg_fmt, static int analyze_fmt_conv(struct b2r2_control *cont, struct b2r2_node_split_buf *src, struct b2r2_node_split_buf *dst, - const u32 **vmx, u32 *node_count) + const u32 **vmx, u32 *node_count, bool fullrange) { - if (is_rgb_fmt(src->fmt)) { - if (is_yvu_fmt(dst->fmt)) - *vmx = &vmx_rgb_to_yvu[0]; - else if (dst->fmt == B2R2_BLT_FMT_24_BIT_YUV888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || - dst->fmt == B2R2_BLT_FMT_24_BIT_VUY888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) - /* - * (A)YUV/VUY(A) formats differ only in component - * order. This is handled by the endianness bit - * in B2R2_STY/TTY registers when src/target are set. - */ - *vmx = &vmx_rgb_to_blt_yuv888[0]; - else if (is_yuv_fmt(dst->fmt)) - *vmx = &vmx_rgb_to_yuv[0]; - else if (is_bgr_fmt(dst->fmt)) - *vmx = &vmx_rgb_to_bgr[0]; - } else if (is_yvu_fmt(src->fmt)) { - if (is_rgb_fmt(dst->fmt)) - *vmx = &vmx_yvu_to_rgb[0]; - else if (is_bgr_fmt(dst->fmt)) - *vmx = &vmx_yvu_to_bgr[0]; - else if (dst->fmt == B2R2_BLT_FMT_24_BIT_YUV888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || - dst->fmt == B2R2_BLT_FMT_24_BIT_VUY888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) - *vmx = &vmx_yvu_to_blt_yuv888[0]; - else if (is_yuv_fmt(dst->fmt) && - !is_yvu_fmt(dst->fmt)) - *vmx = &vmx_yvu_to_yuv[0]; - } else if (src->fmt == B2R2_BLT_FMT_24_BIT_YUV888 || - src->fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || - src->fmt == B2R2_BLT_FMT_24_BIT_VUY888 || - src->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) { - /* - * (A)YUV/VUY(A) formats differ only in component - * order. This is handled by the endianness bit - * in B2R2_STY/TTY registers when src/target are set. - */ - if (is_rgb_fmt(dst->fmt)) { - *vmx = &vmx_blt_yuv888_to_rgb[0]; - } else if (is_yvu_fmt(dst->fmt)) { - *vmx = &vmx_blt_yuv888_to_yvu[0]; - } else if (is_yuv_fmt(dst->fmt)) { - switch (dst->fmt) { - case B2R2_BLT_FMT_24_BIT_YUV888: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - case B2R2_BLT_FMT_24_BIT_VUY888: - case B2R2_BLT_FMT_32_BIT_VUYA8888: /* do nothing */ - break; - default: - *vmx = &vmx_blt_yuv888_to_yuv[0]; - break; - } - } - } else if (is_yuv_fmt(src->fmt)) { - if (is_rgb_fmt(dst->fmt)) - *vmx = &vmx_yuv_to_rgb[0]; - else if (is_bgr_fmt(dst->fmt)) - *vmx = &vmx_yuv_to_bgr[0]; - else if (dst->fmt == B2R2_BLT_FMT_24_BIT_YUV888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || - dst->fmt == B2R2_BLT_FMT_24_BIT_VUY888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) - *vmx = &vmx_yuv_to_blt_yuv888[0]; - else if (is_yvu_fmt(dst->fmt)) - *vmx = &vmx_yvu_to_yuv[0]; - } else if (is_bgr_fmt(src->fmt)) { - if (is_rgb_fmt(dst->fmt)) - *vmx = &vmx_rgb_to_bgr[0]; - else if (is_yvu_fmt(dst->fmt)) - *vmx = &vmx_bgr_to_yvu[0]; - else if (dst->fmt == B2R2_BLT_FMT_24_BIT_YUV888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_AYUV8888 || - dst->fmt == B2R2_BLT_FMT_24_BIT_VUY888 || - dst->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888) - BUG_ON(1); - else if (is_yuv_fmt(dst->fmt)) - *vmx = &vmx_bgr_to_yuv[0]; - } + enum b2r2_color_conversion cc = + b2r2_get_color_conversion(src->fmt, dst->fmt, fullrange); + + b2r2_get_vmx(cc, vmx); if (dst->type == B2R2_FMT_TYPE_RASTER) { *node_count = 1; @@ -1019,11 +814,11 @@ static int analyze_color_fill(struct b2r2_node_split_job *this, this->src.fmt = this->dst.fmt; } else { /* If the dst fmt is YUV the fill fmt will be as well */ - if (is_yuv_fmt(this->dst.fmt)) { + if (b2r2_is_yuv_fmt(this->dst.fmt)) { this->src.fmt = B2R2_BLT_FMT_32_BIT_AYUV8888; - } else if (is_rgb_fmt(this->dst.fmt)) { + } else if (b2r2_is_rgb_fmt(this->dst.fmt)) { this->src.fmt = B2R2_BLT_FMT_32_BIT_ARGB8888; - } else if (is_bgr_fmt(this->dst.fmt)) { + } else if (b2r2_is_bgr_fmt(this->dst.fmt)) { /* Color will still be ARGB, we will translate using IVMX (configured later) */ this->src.fmt = B2R2_BLT_FMT_32_BIT_ARGB8888; @@ -1041,8 +836,8 @@ static int analyze_color_fill(struct b2r2_node_split_job *this, if (((this->flags & B2R2_BLT_FLAG_PER_PIXEL_ALPHA_BLEND) != 0) && ((this->flags & B2R2_BLT_FLAG_SOURCE_FILL_RAW) - == 0) && fmt_has_alpha(this->src.fmt)) { - u8 pixel_alpha = get_alpha(this->src.fmt, + == 0) && b2r2_fmt_has_alpha(this->src.fmt)) { + u8 pixel_alpha = b2r2_get_alpha(this->src.fmt, this->src.color); u32 new_global = pixel_alpha * this->global_alpha / 255; @@ -1050,13 +845,13 @@ static int analyze_color_fill(struct b2r2_node_split_job *this, /* Set the pixel alpha to full opaque so we don't get any nasty surprises */ - this->src.color = set_alpha(this->src.fmt, 0xFF, + this->src.color = b2r2_set_alpha(this->src.fmt, 0xFF, this->src.color); } ret = analyze_fmt_conv( cont, &this->src, &this->dst, &this->ivmx, - node_count); + node_count, this->fullrange); if (ret < 0) goto error; } @@ -1191,7 +986,7 @@ static int analyze_copy(struct b2r2_node_split_job *this, this->type = B2R2_COPY; ret = analyze_fmt_conv(cont, &this->src, &this->dst, - &this->ivmx, ©_count); + &this->ivmx, ©_count, this->fullrange); if (ret < 0) goto error; @@ -1272,12 +1067,14 @@ static int analyze_rot_scale_downscale(struct b2r2_node_split_job *this, * Calculate how many nodes are required to copy to and from the tmp * buffer */ - ret = analyze_fmt_conv(cont, src, tmp, &this->ivmx, &nodes_per_rescale); + ret = analyze_fmt_conv(cont, src, tmp, &this->ivmx, &nodes_per_rescale, + this->fullrange); if (ret < 0) goto error; /* We will not do any format conversion in the rotation stage */ - ret = analyze_fmt_conv(cont, tmp, dst, &dummy_vmx, &nodes_per_rot); + ret = analyze_fmt_conv(cont, tmp, dst, &dummy_vmx, &nodes_per_rot, + this->fullrange); if (ret < 0) goto error; @@ -1399,7 +1196,7 @@ static int analyze_scaling(struct b2r2_node_split_job *this, /* Find out how many nodes a simple copy would require */ ret = analyze_fmt_conv(cont, &this->src, &this->dst, &this->ivmx, - ©_count); + ©_count, this->fullrange); if (ret < 0) goto error; @@ -1461,7 +1258,7 @@ static int analyze_rotate(struct b2r2_node_split_job *this, /* Find out how many nodes a simple copy would require */ ret = analyze_fmt_conv(cont, &this->src, &this->dst, &this->ivmx, - &nodes_per_tile); + &nodes_per_tile, this->fullrange); if (ret < 0) goto error; @@ -1489,9 +1286,9 @@ static int analyze_rotate(struct b2r2_node_split_job *this, struct b2r2_node_split_buf *tmp = &this->tmp_bufs[0]; enum b2r2_blt_fmt tmp_fmt; - if (is_yuv_fmt(this->dst.fmt)) + if (b2r2_is_yuv_fmt(this->dst.fmt)) tmp_fmt = B2R2_BLT_FMT_32_BIT_AYUV8888; - else if (is_bgr_fmt(this->dst.fmt)) + else if (b2r2_is_bgr_fmt(this->dst.fmt)) tmp_fmt = B2R2_BLT_FMT_32_BIT_ABGR8888; else tmp_fmt = B2R2_BLT_FMT_32_BIT_ARGB8888; @@ -1952,7 +1749,7 @@ static void configure_direct_fill( /* Source setup */ /* It seems B2R2 checks so that source and dest has the same format */ - node->node.GROUP3.B2R2_STY = to_native_fmt(dst->fmt); + node->node.GROUP3.B2R2_STY = b2r2_to_native_fmt(dst->fmt); node->node.GROUP2.B2R2_S1CF = color; node->node.GROUP2.B2R2_S2CF = 0; @@ -2043,7 +1840,7 @@ static int configure_fill( /* TO BE REMOVED: */ set_src_2(node, dst->addr, dst); - node->node.GROUP4.B2R2_STY = to_native_fmt(fmt); + node->node.GROUP4.B2R2_STY = b2r2_to_native_fmt(fmt); /* Setup the iVMX for color conversion */ if (ivmx != NULL) @@ -2140,7 +1937,7 @@ static int configure_copy( node->node.GROUP0.B2R2_INS |= B2R2_INS_CKEY_ENABLED; node->node.GROUP0.B2R2_CIC |= B2R2_CIC_COLOR_KEY; - key_color = to_RGB888(this->flag_param, src->fmt); + key_color = b2r2_to_RGB888(this->flag_param, src->fmt); node->node.GROUP12.B2R2_KEY1 = key_color; node->node.GROUP12.B2R2_KEY2 = key_color; } @@ -2328,20 +2125,20 @@ static int configure_scale( luma_vsrc_init = src_y & 0x3ff; /* Check for upsampling of chroma */ - upsample = !src_raster && !is_yuv444_fmt(src->fmt); + upsample = !src_raster && !b2r2_is_yuv444_fmt(src->fmt); if (upsample) { h_rsf /= 2; - if (is_yuv420_fmt(src->fmt)) + if (b2r2_is_yuv420_fmt(src->fmt)) v_rsf /= 2; } /* Check for downsampling of chroma */ - downsample = !dst_raster && !is_yuv444_fmt(dst->fmt); + downsample = !dst_raster && !b2r2_is_yuv444_fmt(dst->fmt); if (downsample) { h_rsf *= 2; - if (is_yuv420_fmt(dst->fmt)) + if (b2r2_is_yuv420_fmt(dst->fmt)) v_rsf *= 2; } @@ -2552,11 +2349,11 @@ static void configure_src(struct b2r2_control *cont, * For 420 and 422 the chroma has lower resolution than the * luma */ - if (!is_yuv444_fmt(src->fmt)) { + if (!b2r2_is_yuv444_fmt(src->fmt)) { tmp_buf.win.x >>= 1; tmp_buf.win.width = (tmp_buf.win.width + 1) / 2; - if (is_yuv420_fmt(src->fmt)) { + if (b2r2_is_yuv420_fmt(src->fmt)) { tmp_buf.win.height = (tmp_buf.win.height + 1) / 2; tmp_buf.win.y >>= 1; @@ -2569,7 +2366,7 @@ static void configure_src(struct b2r2_control *cont, case B2R2_FMT_TYPE_PLANAR: memcpy(&tmp_buf, src, sizeof(tmp_buf)); - if (!is_yuv444_fmt(src->fmt)) { + if (!b2r2_is_yuv444_fmt(src->fmt)) { /* * Each chroma buffer will have half as many values * per line as the luma buffer @@ -2584,7 +2381,7 @@ static void configure_src(struct b2r2_control *cont, * If the buffer is in YUV420 format, the vertical * resolution is half as well */ - if (is_yuv420_fmt(src->fmt)) { + if (b2r2_is_yuv420_fmt(src->fmt)) { tmp_buf.win.height = (tmp_buf.win.height + 1) / 2; tmp_buf.win.y >>= 1; @@ -2692,7 +2489,7 @@ static int configure_dst(struct b2r2_control *cont, struct b2r2_node *node, dst_planes[1].addr = dst->chroma_addr; dst_planes[1].plane_selection = B2R2_TTY_CHROMA_NOT_LUMA; - if (!is_yuv444_fmt(dst->fmt)) { + if (!b2r2_is_yuv444_fmt(dst->fmt)) { /* Horizontal resolution is half */ dst_planes[1].win.x /= 2; /* @@ -2709,7 +2506,7 @@ static int configure_dst(struct b2r2_control *cont, struct b2r2_node *node, * resolution is half as well. Height must be rounded in * the same way as is done for width. */ - if (is_yuv420_fmt(dst->fmt)) { + if (b2r2_is_yuv420_fmt(dst->fmt)) { dst_planes[1].win.y /= 2; dst_planes[1].win.height = (dst_planes[1].win.height + 1) / 2; @@ -2720,7 +2517,7 @@ static int configure_dst(struct b2r2_control *cont, struct b2r2_node *node, /* There will be a third plane as well */ nbr_planes = 3; - if (!is_yuv444_fmt(dst->fmt)) { + if (!b2r2_is_yuv444_fmt(dst->fmt)) { /* The chroma planes have half the luma pitch */ dst_planes[1].pitch /= 2; } @@ -2885,7 +2682,7 @@ static void set_buf(struct b2r2_control *cont, memset(buf, 0, sizeof(*buf)); buf->fmt = img->fmt; - buf->type = get_fmt_type(img->fmt); + buf->type = b2r2_get_fmt_type(img->fmt); if (color_fill) { buf->type = B2R2_FMT_TYPE_RASTER; @@ -2893,10 +2690,10 @@ static void set_buf(struct b2r2_control *cont, } else { buf->addr = addr; - buf->alpha_range = get_alpha_range(img->fmt); + buf->alpha_range = b2r2_get_alpha_range(img->fmt); if (img->pitch == 0) - buf->pitch = fmt_byte_pitch(img->fmt, img->width); + buf->pitch = b2r2_fmt_byte_pitch(img->fmt, img->width); else buf->pitch = img->pitch; @@ -2909,15 +2706,15 @@ static void set_buf(struct b2r2_control *cont, buf->pitch * buf->height); break; case B2R2_FMT_TYPE_PLANAR: - if (is_yuv422_fmt(buf->fmt) || - is_yuv420_fmt(buf->fmt)) { + if (b2r2_is_yuv422_fmt(buf->fmt) || + b2r2_is_yuv420_fmt(buf->fmt)) { buf->chroma_addr = (u32)(((u8 *)addr) + buf->pitch * buf->height); } else { buf->chroma_cr_addr = (u32)(((u8 *)addr) + buf->pitch * buf->height); } - if (is_yuv420_fmt(buf->fmt)) { + if (b2r2_is_yuv420_fmt(buf->fmt)) { /* * Use ceil(height/2) in case * buffer height is not divisible by 2. @@ -2926,16 +2723,16 @@ static void set_buf(struct b2r2_control *cont, (u32)(((u8 *)buf->chroma_addr) + (buf->pitch >> 1) * ((buf->height + 1) >> 1)); - } else if (is_yuv422_fmt(buf->fmt)) { + } else if (b2r2_is_yuv422_fmt(buf->fmt)) { buf->chroma_cr_addr = (u32)(((u8 *)buf->chroma_addr) + (buf->pitch >> 1) * buf->height); - } else if (is_yvu420_fmt(buf->fmt)) { + } else if (b2r2_is_yvu420_fmt(buf->fmt)) { buf->chroma_addr = (u32)(((u8 *)buf->chroma_cr_addr) + (buf->pitch >> 1) * ((buf->height + 1) >> 1)); - } else if (is_yvu422_fmt(buf->fmt)) { + } else if (b2r2_is_yvu422_fmt(buf->fmt)) { buf->chroma_addr = (u32)(((u8 *)buf->chroma_cr_addr) + (buf->pitch >> 1) * buf->height); @@ -2969,13 +2766,13 @@ static int setup_tmp_buf(struct b2r2_control *cont, u32 size; /* Determine what format we should use for the tmp buf */ - if (is_rgb_fmt(pref_fmt)) { + if (b2r2_is_rgb_fmt(pref_fmt)) { fmt = B2R2_BLT_FMT_32_BIT_ARGB8888; - } else if (is_bgr_fmt(pref_fmt)) { + } else if (b2r2_is_bgr_fmt(pref_fmt)) { fmt = B2R2_BLT_FMT_32_BIT_ABGR8888; - } else if (is_yvu_fmt(pref_fmt)) { + } else if (b2r2_is_yvu_fmt(pref_fmt)) { fmt = B2R2_BLT_FMT_CB_Y_CR_Y; - } else if (is_yuv_fmt(pref_fmt)) { + } else if (b2r2_is_yuv_fmt(pref_fmt)) { fmt = B2R2_BLT_FMT_32_BIT_AYUV8888; } else { /* Wait, what? */ @@ -2989,13 +2786,13 @@ static int setup_tmp_buf(struct b2r2_control *cont, /* See if we can fit the entire preferred rectangle */ width = pref_width; height = pref_height; - pitch = fmt_byte_pitch(fmt, width); + pitch = b2r2_fmt_byte_pitch(fmt, width); size = pitch * height; if (size > max_size) { /* We need to limit the size, so we choose a different width */ width = MIN(width, B2R2_RESCALE_MAX_WIDTH); - pitch = fmt_byte_pitch(fmt, width); + pitch = b2r2_fmt_byte_pitch(fmt, width); height = MIN(height, max_size / pitch); size = pitch * height; } @@ -3028,472 +2825,6 @@ error: } /** - * get_alpha_range() - returns the alpha range of the given format - */ -static enum b2r2_ty get_alpha_range(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_24_BIT_ARGB8565: - case B2R2_BLT_FMT_32_BIT_ARGB8888: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - case B2R2_BLT_FMT_32_BIT_VUYA8888: - case B2R2_BLT_FMT_8_BIT_A8: - case B2R2_BLT_FMT_32_BIT_ABGR8888: - return B2R2_TY_ALPHA_RANGE_255; /* 0 - 255 */ - default: - return B2R2_TY_ALPHA_RANGE_128; /* 0 - 128 */ - } -} - -/** - * get_alpha() - returns the pixel alpha in 0...255 range - */ -static u8 get_alpha(enum b2r2_blt_fmt fmt, u32 pixel) -{ - switch (fmt) { - case B2R2_BLT_FMT_32_BIT_ARGB8888: - case B2R2_BLT_FMT_32_BIT_ABGR8888: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - return (pixel >> 24) & 0xff; - case B2R2_BLT_FMT_32_BIT_VUYA8888: - return pixel & 0xff; - case B2R2_BLT_FMT_24_BIT_ARGB8565: - return (pixel & 0xfff) >> 16; - case B2R2_BLT_FMT_16_BIT_ARGB4444: - return (((pixel >> 12) & 0xf) * 255) / 15; - case B2R2_BLT_FMT_16_BIT_ARGB1555: - return (pixel >> 15) * 255; - case B2R2_BLT_FMT_1_BIT_A1: - return pixel * 255; - case B2R2_BLT_FMT_8_BIT_A8: - return pixel; - default: - return 255; - } -} - -/** - * set_alpha() - returns a color value with the alpha component set - */ -static u32 set_alpha(enum b2r2_blt_fmt fmt, u8 alpha, u32 color) -{ - u32 alpha_mask; - - switch (fmt) { - case B2R2_BLT_FMT_32_BIT_ARGB8888: - case B2R2_BLT_FMT_32_BIT_ABGR8888: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - color &= 0x00ffffff; - alpha_mask = alpha << 24; - break; - case B2R2_BLT_FMT_32_BIT_VUYA8888: - color &= 0xffffff00; - alpha_mask = alpha; - break; - case B2R2_BLT_FMT_24_BIT_ARGB8565: - color &= 0x00ffff; - alpha_mask = alpha << 16; - break; - case B2R2_BLT_FMT_16_BIT_ARGB4444: - color &= 0x0fff; - alpha_mask = (alpha << 8) & 0xF000; - break; - case B2R2_BLT_FMT_16_BIT_ARGB1555: - color &= 0x7fff; - alpha_mask = (alpha / 255) << 15 ; - break; - case B2R2_BLT_FMT_1_BIT_A1: - color = 0; - alpha_mask = (alpha / 255); - break; - case B2R2_BLT_FMT_8_BIT_A8: - color = 0; - alpha_mask = alpha; - break; - default: - alpha_mask = 0; - } - - return color | alpha_mask; -} - -/** - * fmt_has_alpha() - returns whether the given format carries an alpha value - */ -static bool fmt_has_alpha(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_16_BIT_ARGB4444: - case B2R2_BLT_FMT_16_BIT_ARGB1555: - case B2R2_BLT_FMT_32_BIT_ARGB8888: - case B2R2_BLT_FMT_32_BIT_ABGR8888: - case B2R2_BLT_FMT_24_BIT_ARGB8565: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - case B2R2_BLT_FMT_32_BIT_VUYA8888: - case B2R2_BLT_FMT_1_BIT_A1: - case B2R2_BLT_FMT_8_BIT_A8: - return true; - default: - return false; - } -} - -/** - * is_rgb_fmt() - returns whether the given format is a rgb format - */ -static bool is_rgb_fmt(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_16_BIT_ARGB4444: - case B2R2_BLT_FMT_16_BIT_ARGB1555: - case B2R2_BLT_FMT_16_BIT_RGB565: - case B2R2_BLT_FMT_24_BIT_RGB888: - case B2R2_BLT_FMT_32_BIT_ARGB8888: - case B2R2_BLT_FMT_24_BIT_ARGB8565: - case B2R2_BLT_FMT_1_BIT_A1: - case B2R2_BLT_FMT_8_BIT_A8: - return true; - default: - return false; - } -} - -/** - * is_bgr_fmt() - returns whether the given format is a bgr format - */ -static bool is_bgr_fmt(enum b2r2_blt_fmt fmt) -{ - return (fmt == B2R2_BLT_FMT_32_BIT_ABGR8888); -} - -/** - * is_yuv_fmt() - returns whether the given format is a yuv format - */ -static bool is_yuv_fmt(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_24_BIT_YUV888: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - case B2R2_BLT_FMT_24_BIT_VUY888: - case B2R2_BLT_FMT_32_BIT_VUYA8888: - case B2R2_BLT_FMT_Y_CB_Y_CR: - case B2R2_BLT_FMT_CB_Y_CR_Y: - case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: - case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: - case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: - return true; - default: - return false; - } -} - -/** - * is_yvu_fmt() - returns whether the given format is a yvu format - */ -static bool is_yvu_fmt(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_Y_CB_Y_CR: - case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: - return true; - default: - return false; - } -} - -/** - * is_yuv420_fmt() - returns whether the given format is a yuv420 format - */ -static bool is_yuv420_fmt(enum b2r2_blt_fmt fmt) -{ - - switch (fmt) { - case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: - return true; - default: - return false; - } -} - -static bool is_yuv422_fmt(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_Y_CB_Y_CR: - case B2R2_BLT_FMT_CB_Y_CR_Y: - case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: - return true; - default: - return false; - } -} - -/** - * is_yvu420_fmt() - returns whether the given format is a yvu420 format - */ -static bool is_yvu420_fmt(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: - return true; - default: - return false; - } -} - -static bool is_yvu422_fmt(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_CB_Y_CR_Y: - case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: - return true; - default: - return false; - } -} - - -/** - * is_yuv444_fmt() - returns whether the given format is a yuv444 format - */ -static bool is_yuv444_fmt(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_24_BIT_YUV888: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - case B2R2_BLT_FMT_24_BIT_VUY888: - case B2R2_BLT_FMT_32_BIT_VUYA8888: - case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: - return true; - default: - return false; - } -} - -/** - * get_fmt_byte_pitch() - returns the pitch of a pixmap with the given width - */ -static int fmt_byte_pitch(enum b2r2_blt_fmt fmt, u32 width) -{ - int pitch; - - switch (fmt) { - - case B2R2_BLT_FMT_1_BIT_A1: - pitch = width >> 3; /* Shift is faster than division */ - if ((width & 0x3) != 0) /* Check for remainder */ - pitch++; - return pitch; - - case B2R2_BLT_FMT_8_BIT_A8: /* Fall through */ - case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: /* Fall through */ - case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: /* Fall through */ - case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: /* Fall through */ - case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: - return width; - - case B2R2_BLT_FMT_16_BIT_ARGB4444: /* Fall through */ - case B2R2_BLT_FMT_16_BIT_ARGB1555: /* Fall through */ - case B2R2_BLT_FMT_16_BIT_RGB565: /* Fall through */ - case B2R2_BLT_FMT_Y_CB_Y_CR: /* Fall through */ - case B2R2_BLT_FMT_CB_Y_CR_Y: - return width << 1; - - case B2R2_BLT_FMT_24_BIT_RGB888: /* Fall through */ - case B2R2_BLT_FMT_24_BIT_ARGB8565: /* Fall through */ - case B2R2_BLT_FMT_24_BIT_YUV888: /* Fall through */ - case B2R2_BLT_FMT_24_BIT_VUY888: - return width * 3; - - case B2R2_BLT_FMT_32_BIT_ARGB8888: /* Fall through */ - case B2R2_BLT_FMT_32_BIT_ABGR8888: /* Fall through */ - case B2R2_BLT_FMT_32_BIT_AYUV8888: /* Fall through */ - case B2R2_BLT_FMT_32_BIT_VUYA8888: - return width << 2; - - default: - /* Should never, ever happen */ - BUG_ON(1); - return 0; - } -} - -/** - * to_native_fmt() - returns the native B2R2 format - */ -static enum b2r2_native_fmt to_native_fmt(enum b2r2_blt_fmt fmt) -{ - - switch (fmt) { - case B2R2_BLT_FMT_UNUSED: - return B2R2_NATIVE_RGB565; - case B2R2_BLT_FMT_1_BIT_A1: - return B2R2_NATIVE_A1; - case B2R2_BLT_FMT_8_BIT_A8: - return B2R2_NATIVE_A8; - case B2R2_BLT_FMT_16_BIT_RGB565: - return B2R2_NATIVE_RGB565; - case B2R2_BLT_FMT_16_BIT_ARGB4444: - return B2R2_NATIVE_ARGB4444; - case B2R2_BLT_FMT_16_BIT_ARGB1555: - return B2R2_NATIVE_ARGB1555; - case B2R2_BLT_FMT_24_BIT_ARGB8565: - return B2R2_NATIVE_ARGB8565; - case B2R2_BLT_FMT_24_BIT_RGB888: - return B2R2_NATIVE_RGB888; - case B2R2_BLT_FMT_24_BIT_YUV888: - case B2R2_BLT_FMT_24_BIT_VUY888: /* Not actually supported by HW */ - return B2R2_NATIVE_YCBCR888; - case B2R2_BLT_FMT_32_BIT_ABGR8888: /* Not actually supported by HW */ - case B2R2_BLT_FMT_32_BIT_ARGB8888: - return B2R2_NATIVE_ARGB8888; - case B2R2_BLT_FMT_32_BIT_AYUV8888: - case B2R2_BLT_FMT_32_BIT_VUYA8888: /* Not actually supported by HW */ - return B2R2_NATIVE_AYCBCR8888; - case B2R2_BLT_FMT_CB_Y_CR_Y: - return B2R2_NATIVE_YCBCR422R; - case B2R2_BLT_FMT_Y_CB_Y_CR: - return B2R2_NATIVE_YCBCR422R; - case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: - return B2R2_NATIVE_YCBCR42X_R2B; - case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: - case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: - return B2R2_NATIVE_YCBCR42X_MBN; - case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: - return B2R2_NATIVE_YUV; - default: - /* Should never ever happen */ - return B2R2_NATIVE_BYTE; - } -} - -/** - * Bit-expand the color from fmt to RGB888 with blue at LSB. - * Copy MSBs into missing LSBs. - */ -static u32 to_RGB888(u32 color, const enum b2r2_blt_fmt fmt) -{ - u32 out_color = 0; - u32 r = 0; - u32 g = 0; - u32 b = 0; - switch (fmt) { - case B2R2_BLT_FMT_16_BIT_ARGB4444: - r = ((color & 0xf00) << 12) | ((color & 0xf00) << 8); - g = ((color & 0xf0) << 8) | ((color & 0xf0) << 4); - b = ((color & 0xf) << 4) | (color & 0xf); - out_color = r | g | b; - break; - case B2R2_BLT_FMT_16_BIT_ARGB1555: - r = ((color & 0x7c00) << 9) | ((color & 0x7000) << 4); - g = ((color & 0x3e0) << 6) | ((color & 0x380) << 1); - b = ((color & 0x1f) << 3) | ((color & 0x1c) >> 2); - out_color = r | g | b; - break; - case B2R2_BLT_FMT_16_BIT_RGB565: - r = ((color & 0xf800) << 8) | ((color & 0xe000) << 3); - g = ((color & 0x7e0) << 5) | ((color & 0x600) >> 1); - b = ((color & 0x1f) << 3) | ((color & 0x1c) >> 2); - out_color = r | g | b; - break; - case B2R2_BLT_FMT_24_BIT_RGB888: - case B2R2_BLT_FMT_32_BIT_ARGB8888: - out_color = color & 0xffffff; - break; - case B2R2_BLT_FMT_32_BIT_ABGR8888: - r = (color & 0xff) << 16; - g = color & 0xff00; - b = (color & 0xff0000) >> 16; - out_color = r | g | b; - break; - case B2R2_BLT_FMT_24_BIT_ARGB8565: - r = ((color & 0xf800) << 8) | ((color & 0xe000) << 3); - g = ((color & 0x7e0) << 5) | ((color & 0x600) >> 1); - b = ((color & 0x1f) << 3) | ((color & 0x1c) >> 2); - out_color = r | g | b; - break; - default: - break; - } - - return out_color; -} - -/** - * get_fmt_type() - returns the type of the given format (raster, planar, etc.) - */ -static enum b2r2_fmt_type get_fmt_type(enum b2r2_blt_fmt fmt) -{ - switch (fmt) { - case B2R2_BLT_FMT_16_BIT_ARGB4444: - case B2R2_BLT_FMT_16_BIT_ARGB1555: - case B2R2_BLT_FMT_16_BIT_RGB565: - case B2R2_BLT_FMT_24_BIT_RGB888: - case B2R2_BLT_FMT_32_BIT_ARGB8888: - case B2R2_BLT_FMT_Y_CB_Y_CR: - case B2R2_BLT_FMT_CB_Y_CR_Y: - case B2R2_BLT_FMT_32_BIT_ABGR8888: - case B2R2_BLT_FMT_24_BIT_ARGB8565: - case B2R2_BLT_FMT_24_BIT_YUV888: - case B2R2_BLT_FMT_32_BIT_AYUV8888: - case B2R2_BLT_FMT_24_BIT_VUY888: - case B2R2_BLT_FMT_32_BIT_VUYA8888: - case B2R2_BLT_FMT_1_BIT_A1: - case B2R2_BLT_FMT_8_BIT_A8: - return B2R2_FMT_TYPE_RASTER; - case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: - case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: - return B2R2_FMT_TYPE_PLANAR; - case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: - case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: - case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: - return B2R2_FMT_TYPE_SEMI_PLANAR; - default: - return B2R2_FMT_TYPE_RASTER; - } -} - -/** * is_transform() - returns whether the given request is a transform operation */ static bool is_transform(const struct b2r2_blt_request *req) @@ -3555,7 +2886,7 @@ static void set_target(struct b2r2_node *node, u32 addr, node->dst_tmp_index = buf->tmp_buf_index; node->node.GROUP1.B2R2_TBA = addr; - node->node.GROUP1.B2R2_TTY = buf->pitch | to_native_fmt(buf->fmt) | + node->node.GROUP1.B2R2_TTY = buf->pitch | b2r2_to_native_fmt(buf->fmt) | buf->alpha_range | buf->chroma_selection | buf->hso | buf->vso | buf->dither | buf->plane_selection; @@ -3611,7 +2942,7 @@ static void set_src(struct b2r2_src_config *src, u32 addr, struct b2r2_node_split_buf *buf) { src->B2R2_SBA = addr; - src->B2R2_STY = buf->pitch | to_native_fmt(buf->fmt) | + src->B2R2_STY = buf->pitch | b2r2_to_native_fmt(buf->fmt) | buf->alpha_range | buf->hso | buf->vso; if (buf->fmt == B2R2_BLT_FMT_24_BIT_VUY888 || @@ -3640,7 +2971,7 @@ static void set_src_1(struct b2r2_node *node, u32 addr, node->node.GROUP0.B2R2_INS |= B2R2_INS_SOURCE_1_FETCH_FROM_MEM; node->node.GROUP3.B2R2_SBA = addr; - node->node.GROUP3.B2R2_STY = buf->pitch | to_native_fmt(buf->fmt) | + node->node.GROUP3.B2R2_STY = buf->pitch | b2r2_to_native_fmt(buf->fmt) | buf->alpha_range | buf->hso | buf->vso; if (buf->fmt == B2R2_BLT_FMT_24_BIT_VUY888 || diff --git a/drivers/video/b2r2/b2r2_utils.c b/drivers/video/b2r2/b2r2_utils.c index 3df7a272211..d482701089e 100644 --- a/drivers/video/b2r2/b2r2_utils.c +++ b/drivers/video/b2r2/b2r2_utils.c @@ -631,3 +631,469 @@ s32 b2r2_align_up(s32 value, s32 alignment) return value + value_to_add; } + +/** + * b2r2_get_alpha_range() - returns the alpha range of the given format + */ +enum b2r2_ty b2r2_get_alpha_range(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_24_BIT_ARGB8565: + case B2R2_BLT_FMT_32_BIT_ARGB8888: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + case B2R2_BLT_FMT_32_BIT_VUYA8888: + case B2R2_BLT_FMT_8_BIT_A8: + case B2R2_BLT_FMT_32_BIT_ABGR8888: + return B2R2_TY_ALPHA_RANGE_255; /* 0 - 255 */ + default: + return B2R2_TY_ALPHA_RANGE_128; /* 0 - 128 */ + } +} + +/** + * b2r2_get_alpha() - returns the pixel alpha in 0...255 range + */ +u8 b2r2_get_alpha(enum b2r2_blt_fmt fmt, u32 pixel) +{ + switch (fmt) { + case B2R2_BLT_FMT_32_BIT_ARGB8888: + case B2R2_BLT_FMT_32_BIT_ABGR8888: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + return (pixel >> 24) & 0xff; + case B2R2_BLT_FMT_32_BIT_VUYA8888: + return pixel & 0xff; + case B2R2_BLT_FMT_24_BIT_ARGB8565: + return (pixel & 0xfff) >> 16; + case B2R2_BLT_FMT_16_BIT_ARGB4444: + return (((pixel >> 12) & 0xf) * 255) / 15; + case B2R2_BLT_FMT_16_BIT_ARGB1555: + return (pixel >> 15) * 255; + case B2R2_BLT_FMT_1_BIT_A1: + return pixel * 255; + case B2R2_BLT_FMT_8_BIT_A8: + return pixel; + default: + return 255; + } +} + +/** + * b2r2_set_alpha() - returns a color value with the alpha component set + */ +u32 b2r2_set_alpha(enum b2r2_blt_fmt fmt, u8 alpha, u32 color) +{ + u32 alpha_mask; + + switch (fmt) { + case B2R2_BLT_FMT_32_BIT_ARGB8888: + case B2R2_BLT_FMT_32_BIT_ABGR8888: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + color &= 0x00ffffff; + alpha_mask = alpha << 24; + break; + case B2R2_BLT_FMT_32_BIT_VUYA8888: + color &= 0xffffff00; + alpha_mask = alpha; + break; + case B2R2_BLT_FMT_24_BIT_ARGB8565: + color &= 0x00ffff; + alpha_mask = alpha << 16; + break; + case B2R2_BLT_FMT_16_BIT_ARGB4444: + color &= 0x0fff; + alpha_mask = (alpha << 8) & 0xF000; + break; + case B2R2_BLT_FMT_16_BIT_ARGB1555: + color &= 0x7fff; + alpha_mask = (alpha / 255) << 15 ; + break; + case B2R2_BLT_FMT_1_BIT_A1: + color = 0; + alpha_mask = (alpha / 255); + break; + case B2R2_BLT_FMT_8_BIT_A8: + color = 0; + alpha_mask = alpha; + break; + default: + alpha_mask = 0; + } + + return color | alpha_mask; +} + +/** + * b2r2_fmt_has_alpha() - returns whether the given format carries an alpha value + */ +bool b2r2_fmt_has_alpha(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_16_BIT_ARGB4444: + case B2R2_BLT_FMT_16_BIT_ARGB1555: + case B2R2_BLT_FMT_32_BIT_ARGB8888: + case B2R2_BLT_FMT_32_BIT_ABGR8888: + case B2R2_BLT_FMT_24_BIT_ARGB8565: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + case B2R2_BLT_FMT_32_BIT_VUYA8888: + case B2R2_BLT_FMT_1_BIT_A1: + case B2R2_BLT_FMT_8_BIT_A8: + return true; + default: + return false; + } +} + +/** + * b2r2_is_rgb_fmt() - returns whether the given format is a rgb format + */ +bool b2r2_is_rgb_fmt(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_16_BIT_ARGB4444: + case B2R2_BLT_FMT_16_BIT_ARGB1555: + case B2R2_BLT_FMT_16_BIT_RGB565: + case B2R2_BLT_FMT_24_BIT_RGB888: + case B2R2_BLT_FMT_32_BIT_ARGB8888: + case B2R2_BLT_FMT_24_BIT_ARGB8565: + case B2R2_BLT_FMT_1_BIT_A1: + case B2R2_BLT_FMT_8_BIT_A8: + return true; + default: + return false; + } +} + +/** + * b2r2_is_bgr_fmt() - returns whether the given format is a bgr format + */ +bool b2r2_is_bgr_fmt(enum b2r2_blt_fmt fmt) +{ + return (fmt == B2R2_BLT_FMT_32_BIT_ABGR8888); +} + +/** + * b2r2_is_yuv_fmt() - returns whether the given format is a yuv format + */ +bool b2r2_is_yuv_fmt(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_24_BIT_YUV888: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + case B2R2_BLT_FMT_24_BIT_VUY888: + case B2R2_BLT_FMT_32_BIT_VUYA8888: + case B2R2_BLT_FMT_Y_CB_Y_CR: + case B2R2_BLT_FMT_CB_Y_CR_Y: + case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: + case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: + case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: + return true; + default: + return false; + } +} + +/** + * b2r2_is_yvu_fmt() - returns whether the given format is a yvu format + */ +bool b2r2_is_yvu_fmt(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_Y_CB_Y_CR: + case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: + return true; + default: + return false; + } +} + +/** + * b2r2_is_yuv420_fmt() - returns whether the given format is a yuv420 format + */ +bool b2r2_is_yuv420_fmt(enum b2r2_blt_fmt fmt) +{ + + switch (fmt) { + case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: + return true; + default: + return false; + } +} + +bool b2r2_is_yuv422_fmt(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_Y_CB_Y_CR: + case B2R2_BLT_FMT_CB_Y_CR_Y: + case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: + return true; + default: + return false; + } +} + +/** + * b2r2_is_yvu420_fmt() - returns whether the given format is a yvu420 format + */ +bool b2r2_is_yvu420_fmt(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: + return true; + default: + return false; + } +} + +bool b2r2_is_yvu422_fmt(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_CB_Y_CR_Y: + case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: + return true; + default: + return false; + } +} + + +/** + * b2r2_is_yuv444_fmt() - returns whether the given format is a yuv444 format + */ +bool b2r2_is_yuv444_fmt(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_24_BIT_YUV888: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + case B2R2_BLT_FMT_24_BIT_VUY888: + case B2R2_BLT_FMT_32_BIT_VUYA8888: + case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: + return true; + default: + return false; + } +} + +/** + * b2r2_fmt_byte_pitch() - returns the pitch of a pixmap with the given width + */ +int b2r2_fmt_byte_pitch(enum b2r2_blt_fmt fmt, u32 width) +{ + int pitch; + + switch (fmt) { + + case B2R2_BLT_FMT_1_BIT_A1: + pitch = width >> 3; /* Shift is faster than division */ + if ((width & 0x3) != 0) /* Check for remainder */ + pitch++; + return pitch; + + case B2R2_BLT_FMT_8_BIT_A8: /* Fall through */ + case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: /* Fall through */ + case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: /* Fall through */ + case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: /* Fall through */ + case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: + return width; + + case B2R2_BLT_FMT_16_BIT_ARGB4444: /* Fall through */ + case B2R2_BLT_FMT_16_BIT_ARGB1555: /* Fall through */ + case B2R2_BLT_FMT_16_BIT_RGB565: /* Fall through */ + case B2R2_BLT_FMT_Y_CB_Y_CR: /* Fall through */ + case B2R2_BLT_FMT_CB_Y_CR_Y: + return width << 1; + + case B2R2_BLT_FMT_24_BIT_RGB888: /* Fall through */ + case B2R2_BLT_FMT_24_BIT_ARGB8565: /* Fall through */ + case B2R2_BLT_FMT_24_BIT_YUV888: /* Fall through */ + case B2R2_BLT_FMT_24_BIT_VUY888: + return width * 3; + + case B2R2_BLT_FMT_32_BIT_ARGB8888: /* Fall through */ + case B2R2_BLT_FMT_32_BIT_ABGR8888: /* Fall through */ + case B2R2_BLT_FMT_32_BIT_AYUV8888: /* Fall through */ + case B2R2_BLT_FMT_32_BIT_VUYA8888: + return width << 2; + + default: + /* Should never, ever happen */ + BUG_ON(1); + return 0; + } +} + +/** + * b2r2_to_native_fmt() - returns the native B2R2 format + */ +enum b2r2_native_fmt b2r2_to_native_fmt(enum b2r2_blt_fmt fmt) +{ + + switch (fmt) { + case B2R2_BLT_FMT_UNUSED: + return B2R2_NATIVE_RGB565; + case B2R2_BLT_FMT_1_BIT_A1: + return B2R2_NATIVE_A1; + case B2R2_BLT_FMT_8_BIT_A8: + return B2R2_NATIVE_A8; + case B2R2_BLT_FMT_16_BIT_RGB565: + return B2R2_NATIVE_RGB565; + case B2R2_BLT_FMT_16_BIT_ARGB4444: + return B2R2_NATIVE_ARGB4444; + case B2R2_BLT_FMT_16_BIT_ARGB1555: + return B2R2_NATIVE_ARGB1555; + case B2R2_BLT_FMT_24_BIT_ARGB8565: + return B2R2_NATIVE_ARGB8565; + case B2R2_BLT_FMT_24_BIT_RGB888: + return B2R2_NATIVE_RGB888; + case B2R2_BLT_FMT_24_BIT_YUV888: + case B2R2_BLT_FMT_24_BIT_VUY888: /* Not actually supported by HW */ + return B2R2_NATIVE_YCBCR888; + case B2R2_BLT_FMT_32_BIT_ABGR8888: /* Not actually supported by HW */ + case B2R2_BLT_FMT_32_BIT_ARGB8888: + return B2R2_NATIVE_ARGB8888; + case B2R2_BLT_FMT_32_BIT_AYUV8888: + case B2R2_BLT_FMT_32_BIT_VUYA8888: /* Not actually supported by HW */ + return B2R2_NATIVE_AYCBCR8888; + case B2R2_BLT_FMT_CB_Y_CR_Y: + return B2R2_NATIVE_YCBCR422R; + case B2R2_BLT_FMT_Y_CB_Y_CR: + return B2R2_NATIVE_YCBCR422R; + case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: + return B2R2_NATIVE_YCBCR42X_R2B; + case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: + case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: + return B2R2_NATIVE_YCBCR42X_MBN; + case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: + return B2R2_NATIVE_YUV; + default: + /* Should never ever happen */ + return B2R2_NATIVE_BYTE; + } +} + +/** + * Bit-expand the color from fmt to RGB888 with blue at LSB. + * Copy MSBs into missing LSBs. + */ +u32 b2r2_to_RGB888(u32 color, const enum b2r2_blt_fmt fmt) +{ + u32 out_color = 0; + u32 r = 0; + u32 g = 0; + u32 b = 0; + switch (fmt) { + case B2R2_BLT_FMT_16_BIT_ARGB4444: + r = ((color & 0xf00) << 12) | ((color & 0xf00) << 8); + g = ((color & 0xf0) << 8) | ((color & 0xf0) << 4); + b = ((color & 0xf) << 4) | (color & 0xf); + out_color = r | g | b; + break; + case B2R2_BLT_FMT_16_BIT_ARGB1555: + r = ((color & 0x7c00) << 9) | ((color & 0x7000) << 4); + g = ((color & 0x3e0) << 6) | ((color & 0x380) << 1); + b = ((color & 0x1f) << 3) | ((color & 0x1c) >> 2); + out_color = r | g | b; + break; + case B2R2_BLT_FMT_16_BIT_RGB565: + r = ((color & 0xf800) << 8) | ((color & 0xe000) << 3); + g = ((color & 0x7e0) << 5) | ((color & 0x600) >> 1); + b = ((color & 0x1f) << 3) | ((color & 0x1c) >> 2); + out_color = r | g | b; + break; + case B2R2_BLT_FMT_24_BIT_RGB888: + case B2R2_BLT_FMT_32_BIT_ARGB8888: + out_color = color & 0xffffff; + break; + case B2R2_BLT_FMT_32_BIT_ABGR8888: + r = (color & 0xff) << 16; + g = color & 0xff00; + b = (color & 0xff0000) >> 16; + out_color = r | g | b; + break; + case B2R2_BLT_FMT_24_BIT_ARGB8565: + r = ((color & 0xf800) << 8) | ((color & 0xe000) << 3); + g = ((color & 0x7e0) << 5) | ((color & 0x600) >> 1); + b = ((color & 0x1f) << 3) | ((color & 0x1c) >> 2); + out_color = r | g | b; + break; + default: + break; + } + + return out_color; +} + +/** + * b2r2_get_fmt_type() - returns the type of the given format (raster, planar, etc.) + */ +enum b2r2_fmt_type b2r2_get_fmt_type(enum b2r2_blt_fmt fmt) +{ + switch (fmt) { + case B2R2_BLT_FMT_16_BIT_ARGB4444: + case B2R2_BLT_FMT_16_BIT_ARGB1555: + case B2R2_BLT_FMT_16_BIT_RGB565: + case B2R2_BLT_FMT_24_BIT_RGB888: + case B2R2_BLT_FMT_32_BIT_ARGB8888: + case B2R2_BLT_FMT_Y_CB_Y_CR: + case B2R2_BLT_FMT_CB_Y_CR_Y: + case B2R2_BLT_FMT_32_BIT_ABGR8888: + case B2R2_BLT_FMT_24_BIT_ARGB8565: + case B2R2_BLT_FMT_24_BIT_YUV888: + case B2R2_BLT_FMT_32_BIT_AYUV8888: + case B2R2_BLT_FMT_24_BIT_VUY888: + case B2R2_BLT_FMT_32_BIT_VUYA8888: + case B2R2_BLT_FMT_1_BIT_A1: + case B2R2_BLT_FMT_8_BIT_A8: + return B2R2_FMT_TYPE_RASTER; + case B2R2_BLT_FMT_YUV420_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_PLANAR: + case B2R2_BLT_FMT_YUV444_PACKED_PLANAR: + return B2R2_FMT_TYPE_PLANAR; + case B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU420_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR: + case B2R2_BLT_FMT_YUV420_PACKED_SEMIPLANAR_MB_STE: + case B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE: + return B2R2_FMT_TYPE_SEMI_PLANAR; + default: + return B2R2_FMT_TYPE_RASTER; + } +} diff --git a/drivers/video/b2r2/b2r2_utils.h b/drivers/video/b2r2/b2r2_utils.h index 0516447b42f..e639e454121 100644 --- a/drivers/video/b2r2/b2r2_utils.h +++ b/drivers/video/b2r2/b2r2_utils.h @@ -63,4 +63,22 @@ s32 b2r2_div_round_up(s32 dividend, s32 divisor); bool b2r2_is_aligned(s32 value, s32 alignment); s32 b2r2_align_up(s32 value, s32 alignment); +enum b2r2_ty b2r2_get_alpha_range(enum b2r2_blt_fmt fmt); +u8 b2r2_get_alpha(enum b2r2_blt_fmt fmt, u32 pixel); +u32 b2r2_set_alpha(enum b2r2_blt_fmt fmt, u8 alpha, u32 color); +bool b2r2_fmt_has_alpha(enum b2r2_blt_fmt fmt); +bool b2r2_is_rgb_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_bgr_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_yuv_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_yvu_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_yuv420_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_yuv422_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_yvu420_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_yvu422_fmt(enum b2r2_blt_fmt fmt); +bool b2r2_is_yuv444_fmt(enum b2r2_blt_fmt fmt); +int b2r2_fmt_byte_pitch(enum b2r2_blt_fmt fmt, u32 width); +enum b2r2_native_fmt b2r2_to_native_fmt(enum b2r2_blt_fmt fmt); +u32 b2r2_to_RGB888(u32 color, const enum b2r2_blt_fmt fmt); +enum b2r2_fmt_type b2r2_get_fmt_type(enum b2r2_blt_fmt fmt); + #endif diff --git a/include/video/b2r2_blt.h b/include/video/b2r2_blt.h index 771d4f60fdb..0964c95af36 100644 --- a/include/video/b2r2_blt.h +++ b/include/video/b2r2_blt.h @@ -372,6 +372,7 @@ enum b2r2_blt_flag { B2R2_BLT_FLAG_DST_NO_CACHE_FLUSH = BIT(16),/*0x10000*/ B2R2_BLT_FLAG_BG_BLEND = BIT(17),/*0x20000*/ B2R2_BLT_FLAG_BG_NO_CACHE_FLUSH = BIT(18),/*0x40000*/ + B2R2_BLT_FLAG_FULL_RANGE_YUV = BIT(19),/*0x20000*/ B2R2_BLT_FLAG_REPORT_WHEN_DONE = BIT(29),/*0x20000000*/ B2R2_BLT_FLAG_REPORT_PERFORMANCE = BIT(30),/*0x40000000*/ B2R2_BLT_FLAG_CLUT_COLOR_CORRECTION = BIT(31),/*0x80000000*/ |