summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>2011-08-26 20:41:41 +0530
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 16:00:18 +0200
commitaf67808803975d8d61def779f8eac971fe1c915e (patch)
tree83bcad5697d47af14e69584035ec4a593b0d6abd
parentbe6bef0765a85c9ed462076a19c192d836faaa9c (diff)
b2r2:Migrate driver to kernel 3.0
Migrate the following b2r2 driver patches to kernel3.0 dbc424d b2r2: Add optimized path for VUY(A)888(8) 24/32-bit formats 2142b2d b2r2: Add VUY(A)888(8) 24/32-bit formats 797c68c [b2r2] Fix QA tools warning in b2r2_node_split.c ST-Ericsson ID: 352334 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: NA Change-Id: I5f3160a9568ad17eb05eae0b7b8adba146153ea9 Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/29563
-rw-r--r--drivers/video/b2r2/b2r2_blt_main.c112
-rw-r--r--drivers/video/b2r2/b2r2_generic.c147
-rw-r--r--drivers/video/b2r2/b2r2_hw.h24
-rw-r--r--drivers/video/b2r2/b2r2_input_validation.c5
-rw-r--r--drivers/video/b2r2/b2r2_node_split.c123
-rw-r--r--drivers/video/b2r2/b2r2_utils.c12
-rw-r--r--include/video/b2r2_blt.h6
7 files changed, 341 insertions, 88 deletions
diff --git a/drivers/video/b2r2/b2r2_blt_main.c b/drivers/video/b2r2/b2r2_blt_main.c
index a2b21f4a2c1..097d2854a83 100644
--- a/drivers/video/b2r2/b2r2_blt_main.c
+++ b/drivers/video/b2r2/b2r2_blt_main.c
@@ -339,7 +339,7 @@ static int b2r2_blt_release(struct inode *inode, struct file *filp)
job = b2r2_core_job_find_first_with_tag((int) instance);
while (job) {
b2r2_core_job_cancel(job);
- /* This release matches addref in b2r2_core_job_find... */
+ /* Matches addref in b2r2_core_job_find... */
b2r2_core_job_release(job, __func__);
job = b2r2_core_job_find_first_with_tag((int) instance);
}
@@ -483,8 +483,8 @@ static long b2r2_blt_ioctl(struct file *file,
b2r2_log_info("b2r2_blt=%d Going generic.\n", ret);
request_gen = kmalloc(sizeof(*request_gen), GFP_KERNEL);
if (!request_gen) {
- b2r2_log_err(
- "%s: Failed to alloc mem for request_gen\n", __func__);
+ b2r2_log_err("%s: Failed to alloc mem for "
+ "request_gen\n", __func__);
return -ENOMEM;
}
@@ -513,19 +513,27 @@ static long b2r2_blt_ioctl(struct file *file,
* make a copy that the HW can use.
*/
if ((request_gen->user_req.flags &
- B2R2_BLT_FLAG_CLUT_COLOR_CORRECTION) != 0) {
- request_gen->clut = dma_alloc_coherent(b2r2_blt_device(),
- CLUT_SIZE, &(request_gen->clut_phys_addr),
+ B2R2_BLT_FLAG_CLUT_COLOR_CORRECTION)
+ != 0) {
+ request_gen->clut =
+ dma_alloc_coherent(b2r2_blt_device(),
+ CLUT_SIZE,
+ &(request_gen->clut_phys_addr),
GFP_DMA | GFP_KERNEL);
if (request_gen->clut == NULL) {
- b2r2_log_err("%s CLUT allocation failed.\n", __func__);
+ b2r2_log_err("%s CLUT allocation "
+ "failed.\n", __func__);
kfree(request_gen);
return -ENOMEM;
}
- if (copy_from_user(request_gen->clut, request_gen->user_req.clut, CLUT_SIZE)) {
- b2r2_log_err("%s: CLUT copy_from_user failed\n", __func__);
- dma_free_coherent(b2r2_blt_device(), CLUT_SIZE, request_gen->clut,
+ if (copy_from_user(request_gen->clut,
+ request_gen->user_req.clut,
+ CLUT_SIZE)) {
+ b2r2_log_err("%s: CLUT copy_from_user "
+ "failed\n", __func__);
+ dma_free_coherent(b2r2_blt_device(),
+ CLUT_SIZE, request_gen->clut,
request_gen->clut_phys_addr);
request_gen->clut = NULL;
request_gen->clut_phys_addr = 0;
@@ -537,7 +545,8 @@ static long b2r2_blt_ioctl(struct file *file,
request_gen->profile = is_profiler_registered_approx();
ret = b2r2_generic_blt(instance, request_gen);
- b2r2_log_info("\nb2r2_generic_blt=%d Generic done.\n", ret);
+ b2r2_log_info("\nb2r2_generic_blt=%d Generic done.\n",
+ ret);
}
#endif /* CONFIG_B2R2_GENERIC_FALLBACK */
@@ -1339,9 +1348,8 @@ static void tile_job_callback_gen(struct b2r2_core_job *job)
#ifdef CONFIG_DEBUG_FS
/* Notify if a tile job is cancelled */
- if (job->job_state == B2R2_CORE_JOB_CANCELED) {
+ if (job->job_state == B2R2_CORE_JOB_CANCELED)
b2r2_log_info("%s: Tile job cancelled:\n", __func__);
- }
#endif
/* Local addref / release within this func */
@@ -1832,19 +1840,24 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
x = -dst_rect->x;
for (; x < dst_rect->width &&
- x + dst_rect->x < dst_img_width; x += tmp_buf_width) {
+ x + dst_rect->x < dst_img_width;
+ x += tmp_buf_width) {
/*
* Tile jobs are freed by the supplied release function
* when ref_count on a tile_job reaches zero.
*/
- struct b2r2_core_job *tile_job = kmalloc(sizeof(*tile_job), GFP_KERNEL);
+ struct b2r2_core_job *tile_job =
+ kmalloc(sizeof(*tile_job), GFP_KERNEL);
if (tile_job == NULL) {
/*
- * Skip this tile. Do not abort, just hope for better luck
- * with rest of the tiles. Memory might become available.
+ * Skip this tile. Do not abort,
+ * just hope for better luck
+ * with rest of the tiles.
+ * Memory might become available.
*/
b2r2_log_info("%s: Failed to alloc job. "
- "Skipping tile at (x, y)=(%d, %d)\n", __func__, x, y);
+ "Skipping tile at (x, y)=(%d, %d)\n",
+ __func__, x, y);
continue;
}
tile_job->tag = request->job.tag;
@@ -1865,7 +1878,8 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
* Only a part of the tile can be written.
* Limit imposed by buffer size.
*/
- dst_rect_tile.width = dst_img_width - (x + dst_rect->x);
+ dst_rect_tile.width =
+ dst_img_width - (x + dst_rect->x);
} else if (x + tmp_buf_width > dst_rect->width) {
/*
* Only a part of the tile can be written.
@@ -1877,10 +1891,12 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
dst_rect_tile.width = tmp_buf_width;
}
/*
- * Where applicable, calculate area in src buffer that is needed
- * to generate the specified part of destination rectangle.
+ * Where applicable, calculate area in src buffer
+ * that is needed to generate the specified part
+ * of destination rectangle.
*/
- b2r2_generic_set_areas(request, request->first_node, &dst_rect_tile);
+ b2r2_generic_set_areas(request,
+ request->first_node, &dst_rect_tile);
/* Submit the job */
b2r2_log_info("%s: Submitting job\n", __func__);
@@ -1940,7 +1956,8 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
x + dst_rect->x < dst_img_width; x += tmp_buf_width) {
struct b2r2_core_job *tile_job = NULL;
if (x + tmp_buf_width < dst_rect->width &&
- x + dst_rect->x + tmp_buf_width < dst_img_width) {
+ x + dst_rect->x + tmp_buf_width <
+ dst_img_width) {
/*
* Tile jobs are freed by the supplied release function
* when ref_count on a tile_job reaches zero.
@@ -1987,26 +2004,29 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
}
/*
* y is now the last row. Either because the whole dst_rect
- * has been processed, or because the last row that will be written
- * to dst_img has been reached. Limits imposed in the same way
- * as for width.
+ * has been processed, or because the last row that will be
+ * written to dst_img has been reached. Limits imposed in
+ * the same way as for width.
*/
dst_rect_tile.y = y;
if (y + dst_rect->y + tmp_buf_height > dst_img_height)
- dst_rect_tile.height = dst_img_height - (y + dst_rect->y);
+ dst_rect_tile.height =
+ dst_img_height - (y + dst_rect->y);
else if (y + tmp_buf_height > dst_rect->height)
dst_rect_tile.height = dst_rect->height - y;
else
dst_rect_tile.height = tmp_buf_height;
- b2r2_generic_set_areas(request, request->first_node, &dst_rect_tile);
+ b2r2_generic_set_areas(request,
+ request->first_node, &dst_rect_tile);
b2r2_log_info("%s: Submitting job\n", __func__);
inc_stat(&stat_n_in_blt_add);
mutex_lock(&instance->lock);
if (x + tmp_buf_width < dst_rect->width &&
- x + dst_rect->x + tmp_buf_width < dst_img_width) {
+ x + dst_rect->x + tmp_buf_width <
+ dst_img_width) {
request_id = b2r2_core_job_add(tile_job);
} else {
/*
@@ -2036,7 +2056,8 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
inc_stat(&stat_n_in_blt_wait);
if (x + tmp_buf_width < dst_rect->width &&
- x + dst_rect->x + tmp_buf_width < dst_img_width) {
+ x + dst_rect->x + tmp_buf_width <
+ dst_img_width) {
ret = b2r2_core_job_wait(tile_job);
} else {
/*
@@ -2056,8 +2077,10 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
"%s: Synchronous wait done\n", __func__);
if (x + tmp_buf_width < dst_rect->width &&
- x + dst_rect->x + tmp_buf_width < dst_img_width)
- nsec_active_in_b2r2 += tile_job->nsec_active_in_hw;
+ x + dst_rect->x + tmp_buf_width <
+ dst_img_width)
+ nsec_active_in_b2r2 +=
+ tile_job->nsec_active_in_hw;
else
nsec_active_in_b2r2 +=
request->job.nsec_active_in_hw;
@@ -2069,7 +2092,8 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
* when the last tile is processed.
*/
if (x + tmp_buf_width < dst_rect->width &&
- x + dst_rect->x + tmp_buf_width < dst_img_width) {
+ x + dst_rect->x + tmp_buf_width <
+ dst_img_width) {
b2r2_core_job_release(tile_job, __func__);
} else {
b2r2_core_job_release(&request->job, __func__);
@@ -2100,7 +2124,8 @@ static int b2r2_generic_blt(struct b2r2_blt_instance *instance,
if (request->profile) {
request->nsec_active_in_cpu =
- (s32)((u32)task_sched_runtime(current) - thread_runtime_at_start);
+ (s32)((u32)task_sched_runtime(current) -
+ thread_runtime_at_start);
request->total_time_nsec =
(s32)(b2r2_get_curr_nsec() - request->start_time_nsec);
request->job.nsec_active_in_hw = nsec_active_in_b2r2;
@@ -2433,7 +2458,8 @@ static int resolve_buf(struct b2r2_blt_img *img,
if (file == NULL)
return -EINVAL;
#ifdef CONFIG_FB
- if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+ if (MAJOR(file->f_dentry->d_inode->i_rdev) ==
+ FB_MAJOR) {
/*
* This is a frame buffer device, find fb_info
* (OK to do it like this, no locking???)
@@ -2503,7 +2529,8 @@ static int resolve_buf(struct b2r2_blt_img *img,
* @resolved_buf: Gathered info (physical address etc.) about buffer
* @is_dst: true if the buffer is a destination buffer, false if the buffer is a
* source buffer.
- * @rect: rectangle in the image buffer that should be synced. NULL the buffer is a source mask.
+ * @rect: rectangle in the image buffer that should be synced.
+ * NULL if the buffer is a source mask.
* @img_width: width of the complete image buffer
* @fmt: buffer format
*/
@@ -2554,11 +2581,15 @@ static void sync_buf(struct b2r2_blt_img *img,
(img->fmt ==
B2R2_BLT_FMT_YUV422_PACKED_SEMIPLANAR_MB_STE)) {
sa.start = (unsigned long)resolved->virtual_address;
- sa.end = (unsigned long)resolved->virtual_address + img->buf.len;
+ sa.end = (unsigned long)resolved->virtual_address +
+ img->buf.len;
start_phys = resolved->physical_address;
end_phys = resolved->physical_address + img->buf.len;
} else {
- /* buffer is not a src_mask so make use of rect when clean & flush caches*/
+ /*
+ * buffer is not a src_mask so make use of rect when
+ * clean & flush caches
+ */
u32 bpp; /* Bits per pixel */
u32 pitch;
@@ -2573,11 +2604,13 @@ static void sync_buf(struct b2r2_blt_img *img,
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:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
bpp = 24;
break;
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:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
bpp = 32;
break;
default:
@@ -2930,7 +2963,8 @@ static int debugfs_b2r2_blt_request_read(struct file *filp, char __user *buf,
goto out;
}
- dev_size = sprintf_req(&debugfs_latest_request, Buf, sizeof(char) * 4096);
+ dev_size = sprintf_req(&debugfs_latest_request, Buf,
+ sizeof(char) * 4096);
/* No more to read if offset != 0 */
if (*f_pos > dev_size)
diff --git a/drivers/video/b2r2/b2r2_generic.c b/drivers/video/b2r2/b2r2_generic.c
index 738e11bf4ba..5941e39be91 100644
--- a/drivers/video/b2r2/b2r2_generic.c
+++ b/drivers/video/b2r2/b2r2_generic.c
@@ -180,11 +180,13 @@ static inline enum b2r2_native_fmt to_native_fmt(enum b2r2_blt_fmt fmt)
return B2R2_NATIVE_ARGB8565;
case B2R2_BLT_FMT_24_BIT_RGB888:
return B2R2_NATIVE_RGB888;
+ case B2R2_BLT_FMT_24_BIT_VUY888:
case B2R2_BLT_FMT_24_BIT_YUV888:
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_VUYA8888: /* fall through */
case B2R2_BLT_FMT_32_BIT_AYUV8888:
return B2R2_NATIVE_AYCBCR8888;
case B2R2_BLT_FMT_CB_Y_CR_Y:
@@ -220,6 +222,7 @@ static inline enum b2r2_ty get_alpha_range(enum b2r2_blt_fmt 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 */
@@ -250,15 +253,15 @@ static unsigned int get_pitch(enum b2r2_blt_fmt format, u32 width)
case B2R2_BLT_FMT_16_BIT_ARGB4444:
return width * 2;
break;
- case B2R2_BLT_FMT_24_BIT_RGB888: /* all 24 bits/pixel RGB formats */
+ case B2R2_BLT_FMT_24_BIT_RGB888: /* all 24 bits/pixel raster formats */
case B2R2_BLT_FMT_24_BIT_ARGB8565:
case B2R2_BLT_FMT_24_BIT_YUV888:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
return width * 3;
break;
- case B2R2_BLT_FMT_32_BIT_ARGB8888: /* all 32 bits/pixel RGB formats */
+ case B2R2_BLT_FMT_32_BIT_ARGB8888: /* all 32 bits/pixel formats */
case B2R2_BLT_FMT_32_BIT_ABGR8888:
- return width * 4;
- break;
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
return width * 4;
break;
@@ -532,6 +535,8 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req,
case B2R2_BLT_FMT_CB_Y_CR_Y:
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_YUV420_PACKED_PLANAR:
case B2R2_BLT_FMT_YUV422_PACKED_PLANAR:
case B2R2_BLT_FMT_YVU420_PACKED_PLANAR:
@@ -607,6 +612,8 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req,
switch (dst_img->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:
node->node.GROUP0.B2R2_INS |=
B2R2_INS_IVMX_ENABLED;
node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX;
@@ -618,6 +625,27 @@ static void setup_fill_input_stage(const struct b2r2_blt_request *req,
B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO;
node->node.GROUP15.B2R2_VMX3 =
B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO;
+ /*
+ * Re-arrange the color components from
+ * VUY(A) to (A)YUV
+ */
+ if (dst_img->fmt ==
+ B2R2_BLT_FMT_24_BIT_VUY888) {
+ u32 Y = src_color & 0xff;
+ u32 U = src_color & 0xff00;
+ u32 V = src_color & 0xff0000;
+ src_color = (Y << 16) | U | (V >> 16);
+ } else if (dst_img->fmt ==
+ B2R2_BLT_FMT_32_BIT_VUYA8888) {
+ u32 A = src_color & 0xff;
+ u32 Y = src_color & 0xff00;
+ u32 U = src_color & 0xff0000;
+ u32 V = src_color & 0xff000000;
+ src_color = (A << 24) |
+ (Y << 8) |
+ (U >> 8) |
+ (V >> 24);
+ }
break;
case B2R2_BLT_FMT_Y_CB_Y_CR:
/*
@@ -703,6 +731,7 @@ static void setup_input_stage(const struct b2r2_blt_request *req,
/* horizontal and vertical scan order for out_buf */
enum b2r2_ty dst_hso = B2R2_TY_HSO_LEFT_TO_RIGHT;
enum b2r2_ty dst_vso = B2R2_TY_VSO_TOP_TO_BOTTOM;
+ u32 endianness = 0;
u32 fctl = 0;
u32 rsf = 0;
u32 rzi = 0;
@@ -838,9 +867,13 @@ static void setup_input_stage(const struct b2r2_blt_request *req,
break;
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:
/*
* Set up IVMX.
- * Color components are laid out in memory as V, U, Y, (A)
+ * For B2R2_BLT_FMT_32_BIT_YUV888 and
+ * B2R2_BLT_FMT_32_BIT_AYUV8888
+ * the color components are laid out in memory as V, U, Y, (A)
* 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.
@@ -855,6 +888,14 @@ static void setup_input_stage(const struct b2r2_blt_request *req,
B2R2_VMX2_BLT_YUV888_TO_RGB_601_VIDEO;
node->node.GROUP15.B2R2_VMX3 =
B2R2_VMX3_BLT_YUV888_TO_RGB_601_VIDEO;
+
+ /*
+ * Re-arrange color components from VUY(A) to (A)YUV
+ * for input VMX to work on them further.
+ */
+ if (src_img->fmt == B2R2_BLT_FMT_24_BIT_VUY888 ||
+ src_img->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888)
+ endianness = B2R2_TY_ENDIAN_BIG_NOT_LITTLE;
break;
case B2R2_BLT_FMT_YUV420_PACKED_PLANAR:
case B2R2_BLT_FMT_YUV422_PACKED_PLANAR:
@@ -1161,7 +1202,8 @@ static void setup_input_stage(const struct b2r2_blt_request *req,
to_native_fmt(src_img->fmt) |
get_alpha_range(src_img->fmt) |
B2R2_TY_HSO_LEFT_TO_RIGHT |
- B2R2_TY_VSO_TOP_TO_BOTTOM;
+ B2R2_TY_VSO_TOP_TO_BOTTOM |
+ endianness;
node->node.GROUP0.B2R2_INS |= B2R2_INS_SOURCE_2_FETCH_FROM_MEM;
node->node.GROUP0.B2R2_CIC |= B2R2_CIC_SOURCE_2;
@@ -1240,6 +1282,7 @@ static void setup_dst_read_stage(const struct b2r2_blt_request *req,
const struct b2r2_blt_img *dst_img = &(req->user_req.dst_img);
u32 fctl = 0;
u32 rsf = 0;
+ u32 endianness = 0;
bool yuv_semi_planar =
dst_img->fmt == B2R2_BLT_FMT_YUV420_PACKED_SEMI_PLANAR ||
dst_img->fmt == B2R2_BLT_FMT_YUV422_PACKED_SEMI_PLANAR ||
@@ -1278,36 +1321,59 @@ static void setup_dst_read_stage(const struct b2r2_blt_request *req,
node->node.GROUP15.B2R2_VMX3 = B2R2_VMX3_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;
+ 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;
+ break;
case B2R2_BLT_FMT_24_BIT_YUV888:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
- /* Set up IVMX */
+ case B2R2_BLT_FMT_24_BIT_VUY888:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
+ /*
+ * Set up IVMX.
+ * For B2R2_BLT_FMT_32_BIT_YUV888 and
+ * B2R2_BLT_FMT_32_BIT_AYUV8888
+ * the color components are laid out in memory as V, U, Y, (A)
+ * 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.
+ */
node->node.GROUP0.B2R2_INS |= B2R2_INS_IVMX_ENABLED;
node->node.GROUP0.B2R2_CIC |= B2R2_CIC_IVMX;
- if (dst_img->fmt == B2R2_BLT_FMT_Y_CB_Y_CR) {
- /*
- * 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;
- } 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;
- }
+ 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;
+
+ /*
+ * Re-arrange color components from VUY(A) to (A)YUV
+ * for input VMX to work on them further.
+ */
+ if (dst_img->fmt == B2R2_BLT_FMT_24_BIT_VUY888 ||
+ dst_img->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888)
+ endianness = B2R2_TY_ENDIAN_BIG_NOT_LITTLE;
break;
case B2R2_BLT_FMT_YUV420_PACKED_PLANAR:
case B2R2_BLT_FMT_YUV422_PACKED_PLANAR:
@@ -1536,7 +1602,8 @@ static void setup_dst_read_stage(const struct b2r2_blt_request *req,
to_native_fmt(dst_img->fmt) |
get_alpha_range(dst_img->fmt) |
B2R2_TY_HSO_LEFT_TO_RIGHT |
- B2R2_TY_VSO_TOP_TO_BOTTOM;
+ B2R2_TY_VSO_TOP_TO_BOTTOM |
+ endianness;
node->node.GROUP0.B2R2_INS |=
B2R2_INS_SOURCE_2_FETCH_FROM_MEM;
@@ -1689,6 +1756,7 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req,
u32 dst_dither = 0;
u32 dst_pitch = 0;
+ u32 endianness = 0;
b2r2_log_info("%s ENTRY\n", __func__);
@@ -2057,7 +2125,9 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req,
B2R2_VMX3_RGB_TO_YVU_601_VIDEO;
break;
case B2R2_BLT_FMT_24_BIT_YUV888: /* fall through */
- case B2R2_BLT_FMT_32_BIT_AYUV8888:
+ 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 =
@@ -2068,6 +2138,14 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req,
B2R2_VMX2_RGB_TO_BLT_YUV888_601_VIDEO;
node->node.GROUP16.B2R2_VMX3 =
B2R2_VMX3_RGB_TO_BLT_YUV888_601_VIDEO;
+
+ /*
+ * Re-arrange color components from (A)YUV to VUY(A)
+ * when bytes are stored in memory.
+ */
+ if (dst_fmt == B2R2_BLT_FMT_24_BIT_VUY888 ||
+ dst_fmt == B2R2_BLT_FMT_32_BIT_VUYA8888)
+ endianness = B2R2_TY_ENDIAN_BIG_NOT_LITTLE;
break;
default:
break;
@@ -2080,7 +2158,8 @@ static void setup_writeback_stage(const struct b2r2_blt_request *req,
get_alpha_range(dst_img->fmt) |
B2R2_TY_HSO_LEFT_TO_RIGHT |
B2R2_TY_VSO_TOP_TO_BOTTOM |
- dst_dither;
+ dst_dither |
+ endianness;
node->node.GROUP0.B2R2_ACK = B2R2_ACK_MODE_BYPASS_S2_S3;
node->node.GROUP0.B2R2_INS |=
diff --git a/drivers/video/b2r2/b2r2_hw.h b/drivers/video/b2r2/b2r2_hw.h
index 0dd5f758eb5..d492168913a 100644
--- a/drivers/video/b2r2/b2r2_hw.h
+++ b/drivers/video/b2r2/b2r2_hw.h
@@ -680,4 +680,28 @@ enum b2r2_plug_page_size {
#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_input_validation.c b/drivers/video/b2r2/b2r2_input_validation.c
index 2604d8f77e0..0de714f1161 100644
--- a/drivers/video/b2r2/b2r2_input_validation.c
+++ b/drivers/video/b2r2/b2r2_input_validation.c
@@ -70,6 +70,8 @@ static bool is_valid_format(enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_32_BIT_ABGR8888:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
case B2R2_BLT_FMT_YUV444_PACKED_PLANAR:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
return true;
default:
@@ -105,9 +107,11 @@ static bool is_valid_pitch_for_fmt(u32 pitch, s32 width, enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_24_BIT_RGB888:
case B2R2_BLT_FMT_24_BIT_ARGB8565:
case B2R2_BLT_FMT_24_BIT_YUV888:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
case B2R2_BLT_FMT_32_BIT_ARGB8888:
case B2R2_BLT_FMT_32_BIT_ABGR8888:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
if (!b2r2_is_aligned(pitch, 4))
return false;
@@ -127,6 +131,7 @@ static bool is_aligned_width_for_fmt(s32 width, enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_24_BIT_RGB888:
case B2R2_BLT_FMT_24_BIT_ARGB8565:
case B2R2_BLT_FMT_24_BIT_YUV888:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
if (!b2r2_is_aligned(width, 4))
return false;
diff --git a/drivers/video/b2r2/b2r2_node_split.c b/drivers/video/b2r2/b2r2_node_split.c
index 90674e0e540..5aa62be8b4b 100644
--- a/drivers/video/b2r2/b2r2_node_split.c
+++ b/drivers/video/b2r2/b2r2_node_split.c
@@ -67,6 +67,33 @@ static const u32 vmx_blt_yuv888_to_rgb[] = {
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,
@@ -270,6 +297,8 @@ int b2r2_node_split_analyze(const struct b2r2_blt_request *req,
switch (req->user_req.src_img.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:
if (!is_rgb_fmt(req->user_req.dst_img.fmt)) {
ret = -ENOSYS;
goto unsupported;
@@ -283,6 +312,8 @@ int b2r2_node_split_analyze(const struct b2r2_blt_request *req,
switch (req->user_req.dst_img.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:
if (!is_rgb_fmt(req->user_req.src_img.fmt)) {
ret = -ENOSYS;
goto unsupported;
@@ -692,7 +723,14 @@ static int analyze_fmt_conv(struct b2r2_node_split_buf *src,
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_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];
@@ -704,29 +742,48 @@ static int analyze_fmt_conv(struct b2r2_node_split_buf *src,
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)
- BUG_ON(1);
+ 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) {
- if (is_rgb_fmt(dst->fmt))
+ 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
- /*
- * not supported, b2r2_node_split_analyze()
- * should have returned ENOSYS.
- */
- BUG_ON(1);
+ } 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)
- BUG_ON(1);
+ 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)) {
@@ -735,7 +792,9 @@ static int analyze_fmt_conv(struct b2r2_node_split_buf *src,
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_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];
@@ -778,7 +837,8 @@ static int analyze_color_fill(struct b2r2_node_split_job *this,
if ((!this->blend) && ((this->flags & B2R2_BLT_FLAG_SOURCE_FILL_RAW) ||
(this->dst.fmt == B2R2_BLT_FMT_32_BIT_ARGB8888) ||
(this->dst.fmt == B2R2_BLT_FMT_32_BIT_ABGR8888) ||
- (this->dst.fmt == B2R2_BLT_FMT_32_BIT_AYUV8888))) {
+ (this->dst.fmt == B2R2_BLT_FMT_32_BIT_AYUV8888) ||
+ (this->dst.fmt == B2R2_BLT_FMT_32_BIT_VUYA8888))) {
this->type = B2R2_DIRECT_FILL;
/* The color format will be the same as the dst fmt */
@@ -2707,6 +2767,7 @@ static enum b2r2_ty get_alpha_range(enum b2r2_blt_fmt 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 */
@@ -2725,6 +2786,8 @@ static u8 get_alpha(enum b2r2_blt_fmt fmt, u32 pixel)
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:
@@ -2754,6 +2817,10 @@ static u32 set_alpha(enum b2r2_blt_fmt fmt, u8 alpha, u32 color)
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;
@@ -2793,6 +2860,7 @@ static bool fmt_has_alpha(enum b2r2_blt_fmt fmt)
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;
@@ -2837,6 +2905,8 @@ 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:
@@ -2942,6 +3012,8 @@ 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:
@@ -2988,11 +3060,13 @@ static int fmt_byte_pitch(enum b2r2_blt_fmt fmt, u32 width)
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:
+ 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:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
return width << 2;
default:
@@ -3026,11 +3100,13 @@ static enum b2r2_native_fmt to_native_fmt(enum b2r2_blt_fmt fmt)
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;
@@ -3125,6 +3201,8 @@ static enum b2r2_fmt_type get_fmt_type(enum b2r2_blt_fmt fmt)
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;
@@ -3256,6 +3334,11 @@ static void set_target(struct b2r2_node *node, u32 addr,
node->node.GROUP1.B2R2_TTY = buf->pitch | to_native_fmt(buf->fmt) |
buf->alpha_range | buf->chroma_selection | buf->hso |
buf->vso | buf->dither | buf->plane_selection;
+
+ if (buf->fmt == B2R2_BLT_FMT_24_BIT_VUY888 ||
+ buf->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888)
+ node->node.GROUP1.B2R2_TTY |= B2R2_TY_ENDIAN_BIG_NOT_LITTLE;
+
node->node.GROUP1.B2R2_TSZ =
((buf->win.width & 0xfff) << B2R2_SZ_WIDTH_SHIFT) |
((buf->win.height & 0xfff) << B2R2_SZ_HEIGHT_SHIFT);
@@ -3306,6 +3389,11 @@ static void set_src(struct b2r2_src_config *src, u32 addr,
src->B2R2_SBA = addr;
src->B2R2_STY = buf->pitch | to_native_fmt(buf->fmt) |
buf->alpha_range | buf->hso | buf->vso;
+
+ if (buf->fmt == B2R2_BLT_FMT_24_BIT_VUY888 ||
+ buf->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888)
+ src->B2R2_STY |= B2R2_TY_ENDIAN_BIG_NOT_LITTLE;
+
src->B2R2_SSZ = ((buf->win.width & 0xfff) << B2R2_SZ_WIDTH_SHIFT) |
((buf->win.height & 0xfff) << B2R2_SZ_HEIGHT_SHIFT);
src->B2R2_SXY = ((buf->win.x & 0xffff) << B2R2_XY_X_SHIFT) |
@@ -3330,6 +3418,11 @@ static void set_src_1(struct b2r2_node *node, u32 addr,
node->node.GROUP3.B2R2_SBA = addr;
node->node.GROUP3.B2R2_STY = buf->pitch | to_native_fmt(buf->fmt) |
buf->alpha_range | buf->hso | buf->vso;
+
+ if (buf->fmt == B2R2_BLT_FMT_24_BIT_VUY888 ||
+ buf->fmt == B2R2_BLT_FMT_32_BIT_VUYA8888)
+ node->node.GROUP3.B2R2_STY |= B2R2_TY_ENDIAN_BIG_NOT_LITTLE;
+
node->node.GROUP3.B2R2_SXY =
((buf->win.x & 0xffff) << B2R2_XY_X_SHIFT) |
((buf->win.y & 0xffff) << B2R2_XY_Y_SHIFT);
diff --git a/drivers/video/b2r2/b2r2_utils.c b/drivers/video/b2r2/b2r2_utils.c
index 44ea06e51fd..ad0e7a42fa1 100644
--- a/drivers/video/b2r2/b2r2_utils.c
+++ b/drivers/video/b2r2/b2r2_utils.c
@@ -101,12 +101,14 @@ int b2r2_get_fmt_bpp(enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_24_BIT_RGB888:
case B2R2_BLT_FMT_24_BIT_ARGB8565:
case B2R2_BLT_FMT_24_BIT_YUV888:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
case B2R2_BLT_FMT_YUV444_PACKED_PLANAR:
return 24;
case B2R2_BLT_FMT_32_BIT_ARGB8888:
case B2R2_BLT_FMT_32_BIT_ABGR8888:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
return 32;
default:
@@ -134,6 +136,8 @@ int b2r2_get_fmt_y_bpp(enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_YUV444_PACKED_PLANAR:
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 8;
default:
@@ -155,9 +159,11 @@ bool b2r2_is_single_plane_fmt(enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_24_BIT_RGB888:
case B2R2_BLT_FMT_24_BIT_ARGB8565:
case B2R2_BLT_FMT_24_BIT_YUV888:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
case B2R2_BLT_FMT_32_BIT_ARGB8888:
case B2R2_BLT_FMT_32_BIT_ABGR8888:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
case B2R2_BLT_FMT_Y_CB_Y_CR:
case B2R2_BLT_FMT_CB_Y_CR_Y:
return true;
@@ -178,9 +184,11 @@ bool b2r2_is_independent_pixel_fmt(enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_24_BIT_RGB888:
case B2R2_BLT_FMT_24_BIT_ARGB8565:
case B2R2_BLT_FMT_24_BIT_YUV888:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
case B2R2_BLT_FMT_32_BIT_ARGB8888:
case B2R2_BLT_FMT_32_BIT_ABGR8888:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
case B2R2_BLT_FMT_YUV444_PACKED_PLANAR:
return true;
@@ -196,6 +204,8 @@ bool b2r2_is_ycbcri_fmt(enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_CB_Y_CR_Y:
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 true;
default:
@@ -270,6 +280,8 @@ bool b2r2_is_ycbcr444_fmt(enum b2r2_blt_fmt fmt)
case B2R2_BLT_FMT_YUV444_PACKED_PLANAR:
case B2R2_BLT_FMT_32_BIT_AYUV8888:
case B2R2_BLT_FMT_24_BIT_YUV888:
+ case B2R2_BLT_FMT_32_BIT_VUYA8888:
+ case B2R2_BLT_FMT_24_BIT_VUY888:
return true;
default:
diff --git a/include/video/b2r2_blt.h b/include/video/b2r2_blt.h
index 1cf5f661598..a992155f0da 100644
--- a/include/video/b2r2_blt.h
+++ b/include/video/b2r2_blt.h
@@ -127,6 +127,10 @@ struct b2r2_blt_rect {
* The buffer shall contain a plane of Y, V, and U data in this order.
* (Same as B2R2_BLT_FMT_YUV422_PACKED_PLANAR except that chroma
* order is swapped.)
+ * @B2R2_BLT_FMT_24_BIT_VUY888: 24 bits per pixel VUY format with colors
+ * stored as V 23:16, U 15:8, and Y 7:0.
+ * @B2R2_BLT_FMT_32_BIT_VUYA8888: 32 bits per pixel VUYA format with colors
+ * stored as V 31:24, U 23:16, Y 15:8, and Alpha 7:0.
*/
enum b2r2_blt_fmt {
B2R2_BLT_FMT_UNUSED = 0,
@@ -155,6 +159,8 @@ enum b2r2_blt_fmt {
B2R2_BLT_FMT_YVU422_PACKED_SEMI_PLANAR = 0x7F00000A,
B2R2_BLT_FMT_YVU420_PACKED_PLANAR = 0x7F00000B,
B2R2_BLT_FMT_YVU422_PACKED_PLANAR = 0x7F00000C,
+ B2R2_BLT_FMT_24_BIT_VUY888 = 0x7F00000D,
+ B2R2_BLT_FMT_32_BIT_VUYA8888 = 0x7F00000E,
};
/**