Video For Linux (V4L) issue for onboard OV5693

I found V4L doesn’t work for TX2 with latest L4T 32.2.1 and L4T 32.3.1 installed using SDK Manager.
The images are scrambled.
This doesn’t happen to TX1 and Xavier.

“v4l2-ctl --all” produced wrong "Bytes Per Line of 5376 for TX2 instead of 5184(2592x2)for TX1 and Xavier.

I’m not sure if it’s caused by wrong kernel driver or DTB.

Try apply this patch and add below to the v4l2-ctl capute command line.
–set-ctrl preferred_stride=256 preferred_stride=256

diff --git a/drivers/media/platform/tegra/camera/vi/channel.c b/drivers/media/platform/tegra/camera/vi/channel.c
index 6a2777e..c2a28d0 100644
--- a/drivers/media/platform/tegra/camera/vi/channel.c
+++ b/drivers/media/platform/tegra/camera/vi/channel.c
@@ -254,6 +254,10 @@ static void tegra_channel_update_format(struct tegra_channel *chan,
        chan->format.pixelformat = fourcc;
        chan->format.bytesperline = preferred_stride ?: bytesperline;

+       dev_dbg(&chan->video->dev,
+                       "%s: Resolution= %dx%d bytesperline=%d\n",
+                       __func__, width, height, chan->format.bytesperline);
+
        tegra_channel_fmt_align(chan, chan->fmtinfo,
                                &chan->format.width,
                                &chan->format.height,
@@ -332,7 +336,8 @@ static void tegra_channel_fmts_bitmap_init(struct tegra_channel *chan)
        tegra_channel_update_format(chan, chan->format.width,
                                chan->format.height,
                                chan->fmtinfo->fourcc,
-                               &chan->fmtinfo->bpp, 0);
+                               &chan->fmtinfo->bpp,
+                               chan->preferred_stride);

        if (chan->total_ports > 1)
                update_gang_mode(chan);
@@ -1125,7 +1130,8 @@ tegra_channel_s_dv_timings(struct file *file, void *fh,

        if (!ret)
                tegra_channel_update_format(chan, bt->width, bt->height,
-                       chan->fmtinfo->fourcc, &chan->fmtinfo->bpp, 0);
+                       chan->fmtinfo->fourcc, &chan->fmtinfo->bpp,
+                       chan->preferred_stride);

        if (chan->total_ports > 1)
                update_gang_mode(chan);
@@ -1226,6 +1232,14 @@ int tegra_channel_s_ctrl(struct v4l2_ctrl *ctrl)
        case TEGRA_CAMERA_CID_LOW_LATENCY:
                chan->low_latency = ctrl->val;
                break;
+       case TEGRA_CAMERA_CID_VI_PREFERRED_STRIDE:
+               chan->preferred_stride = ctrl->val;
+               tegra_channel_update_format(chan, chan->format.width,
+                               chan->format.height,
+                               chan->format.pixelformat,
+                               &chan->fmtinfo->bpp,
+                               chan->preferred_stride);
+               break;
        default:
                dev_err(&chan->video->dev, "%s: Invalid ctrl %u\n",
                        __func__, ctrl->id);
@@ -1360,6 +1374,16 @@ static const struct v4l2_ctrl_config common_custom_ctrls[] = {
                .max = 1,
                .step = 1,
        },
+       {
+               .ops = &channel_ctrl_ops,
+               .id = TEGRA_CAMERA_CID_VI_PREFERRED_STRIDE,
+               .name = "Preferred Stride",
+               .type = V4L2_CTRL_TYPE_INTEGER,
+               .min = 0,
+               .max = 65535,
+               .step = 1,
+               .def = 0,
+       },
 };

 #define GET_TEGRA_CAMERA_CTRL(id, c)                                   \
@@ -1913,6 +1937,10 @@ __tegra_channel_set_format(struct tegra_channel *chan,
        if (!ret) {
                chan->format = *pix;
                chan->fmtinfo = vfmt;
+
+               if (chan->preferred_stride)
+                       pix->bytesperline = chan->preferred_stride;
+
                tegra_channel_update_format(chan, pix->width,
                        pix->height, vfmt->fourcc, &vfmt->bpp,
                        pix->bytesperline);
@@ -2294,7 +2322,8 @@ int tegra_channel_init(struct tegra_channel *chan)
        tegra_channel_update_format(chan, TEGRA_DEF_WIDTH,
                                TEGRA_DEF_HEIGHT,
                                chan->fmtinfo->fourcc,
-                               &chan->fmtinfo->bpp, 0);
+                               &chan->fmtinfo->bpp,
+                               chan->preferred_stride);

        chan->buffer_offset[0] = 0;
        /* Init bpl factor to 1, will be overidden based on interlace_type */
diff --git a/include/media/mc_common.h b/include/media/mc_common.h
index 01b0345..891cfe8 100644
--- a/include/media/mc_common.h
+++ b/include/media/mc_common.h
@@ -208,6 +208,7 @@ struct tegra_channel {

        void __iomem *csibase[TEGRA_CSI_BLOCKS];
        unsigned int stride_align;
+       unsigned int preferred_stride;
        unsigned int width_align;
        unsigned int height_align;
        unsigned int size_align;
diff --git a/include/media/tegra-v4l2-camera.h b/include/media/tegra-v4l2-camera.h
index cb63198..1c91672 100644
--- a/include/media/tegra-v4l2-camera.h
+++ b/include/media/tegra-v4l2-camera.h
@@ -53,6 +53,7 @@
 #define TEGRA_CAMERA_CID_SENSOR_CONTROL_PROPERTIES (TEGRA_CAMERA_CID_BASE+107)
 #define TEGRA_CAMERA_CID_SENSOR_DV_TIMINGS         (TEGRA_CAMERA_CID_BASE+108)
 #define TEGRA_CAMERA_CID_LOW_LATENCY         (TEGRA_CAMERA_CID_BASE+109)
+#define TEGRA_CAMERA_CID_VI_PREFERRED_STRIDE (TEGRA_CAMERA_CID_BASE+110)

 /**
  * This is temporary with the current v4l2 infrastructure

@ShabeCCC,
Thanks for quick response.
I made changes on the 3 files in 32.3.1 kernel source, rebuilt kernel image, enabled kernel debug and ran:

$ v4l2-ctl --stream-mmap --stream-count=1 --set-ctrl preferred_stride=256 --stream-to 2592x1944.bin

$ dmesg | grep video4linux
[ 2327.738793] video4linux video0: tegra_channel_update_format: Resolution= 2592x1944 bytesperline=256

$ v4l2-ctl --stream-mmap --stream-count=1 --set-ctrl preferred_stride=2592 --stream-to 2592x1944.bin

$ dmesg | grep video4linux
[ 2708.143802] video4linux video0: tegra_channel_update_format: Resolution= 2592x1944 bytesperline=2592

$ v4l2-ctl --stream-mmap --stream-count=1 --set-ctrl preferred_stride=5184 --stream-to 2592x1944.bin
nvidia@tx2-32-3-1:~$ dmesg | grep video4linux
[ 2742.354451] video4linux video0: tegra_channel_update_format: Resolution= 2592x1944 bytesperline=5184
[ 2742.509719] video4linux video0: free_ring_buffers: capture init latency is 136 ms

i.e., Byte Per Line is “–set-ctrl preferred_stride” value. The captured image is still scrambled for preferred_stride 256, 2592 and 5184.

I’m wondering why TX1 and Xavier can produce correct images for L4T 32.3.1.

Have a try add “–stream-skip=16” to make sure the if the sensor output bad frame at beginning.

OV5693 worked for TX2 after I changed number of columns from 2592 to 2688.