AnsweredAssumed Answered

IMX6UL CSI Camera in RGB Mode

Question asked by Nick Hunn on Mar 9, 2020
Latest reply on Mar 11, 2020 by Nick Hunn

Hi, I'm trying to get the ov5640 camera working in RGB565 on the IMX6UL. I currently have the camera working correctly in YUYV mode using the ov5640_v2 driver.

 

The problem that we have is that this doesn't go well with our RGB565 LCD, the transformation seems to be done in software and causes some CPU usage problems when we mirror the camera to the screen. (approximately 240% to mirror the whole camera). Converting seemed fairly straight forward but I'm having a bug where only the top half of the image is shown, and it seems to flicker between the bottom and top half of the image every frame (Possibly twice a frame, it's hard to tell).

Do you have any suggestions to fix this problem? Or achieve a similar outcome differently.

 

The changes I made are a follows:

diff --git a/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c b/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
index 193cbd5ec0f7..461ec8660000 100644
--- a/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
+++ b/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
@@ -48,7 +48,7 @@ static void csi_buf_work_func(struct work_struct *work)
         task.input.paddr = cam->vf_bufs[1];
     task.input.width = cam->crop_current.width;
     task.input.height = cam->crop_current.height;
-    task.input.format = IPU_PIX_FMT_UYVY;
+    task.input.format = IPU_PIX_FMT_RGB565;
 
     task.output.paddr = offset;
     task.output.width = cam->overlay_fb->var.xres;
@@ -241,7 +241,7 @@ static int csi_enc_setup(cam_data *cam)
         goto out_1;
     }
 
-    pixel_fmt = IPU_PIX_FMT_UYVY;
+    pixel_fmt = IPU_PIX_FMT_RGB565;
     err = ipu_init_channel_buffer(
         cam->ipu, chan, IPU_OUTPUT_BUFFER, pixel_fmt,
         cam->crop_current.width, cam->crop_current.height,
diff --git a/drivers/media/platform/mxc/capture/mx6s_capture.c b/drivers/media/platform/mxc/capture/mx6s_capture.c
index f57817ab2647..6584b29bbd25 100644
--- a/drivers/media/platform/mxc/capture/mx6s_capture.c
+++ b/drivers/media/platform/mxc/capture/mx6s_capture.c
@@ -273,6 +273,12 @@ static struct mx6s_fmt formats[] = {
         .pixelformat    = V4L2_PIX_FMT_SBGGR8,
         .mbus_code    = MEDIA_BUS_FMT_SBGGR8_1X8,
         .bpp        = 1,
+    }, {
+        .name        = "RGB565 (RGB565)",
+        .fourcc        = V4L2_PIX_FMT_RGB565,
+        .pixelformat    = V4L2_PIX_FMT_RGB565,
+        .mbus_code    = MEDIA_BUS_FMT_RGB565_2X8_LE,
+        .bpp        = 2,
     }
 };
 
@@ -842,6 +848,7 @@ static int mx6s_configure_csi(struct mx6s_csi_dev *csi_dev)
     }
 
     switch (csi_dev->fmt->pixelformat) {
+    case V4L2_PIX_FMT_RGB565:
     case V4L2_PIX_FMT_YUV32:
     case V4L2_PIX_FMT_SBGGR8:
         width = pix->width;
diff --git a/drivers/media/platform/mxc/capture/ov5640_v2.c b/drivers/media/platform/mxc/capture/ov5640_v2.c
index 7fdccda06568..2adf4a831366 100644
--- a/drivers/media/platform/mxc/capture/ov5640_v2.c
+++ b/drivers/media/platform/mxc/capture/ov5640_v2.c
@@ -145,8 +145,8 @@ static struct reg_value ov5640_global_init_setting[] = {
     {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
     {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
     {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
-    {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
-    {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
+    {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x6f, 0, 0},
+    {0x501f, 0x01, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
     {0x3008, 0x02, 0, 0},
 };
 
@@ -182,8 +182,8 @@ static struct reg_value ov5640_init_setting_30fps_VGA[] = {
     {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
     {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
     {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
-    {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
-    {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+    {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x6f, 0, 0},
+    {0x501f, 0x01, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
     {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
     {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
     {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
@@ -627,7 +627,7 @@ static struct i2c_driver ov5640_i2c_driver = {
 };
 
 static const struct ov5640_datafmt ov5640_colour_fmts[] = {
-    {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
+    { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
 };
 
 static struct ov5640 *to_ov5640(const struct i2c_client *client)
@@ -1822,7 +1822,7 @@ static int ov5640_probe(struct i2c_client *client,
 
     ov5640_data.io_init = ov5640_reset;
     ov5640_data.i2c_client = client;
-    ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+    ov5640_data.pix.pixelformat = V4L2_PIX_FMT_RGB565;
     ov5640_data.pix.width = 640;
     ov5640_data.pix.height = 480;
     ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |

Outcomes