MIPI CSI: image height width restriction

Is there any restriction on height and width setting of image to be captured CSI 0 module for RAW8 and RAW10 bit bayer image ?

we have integrated ov4689 camera with csi0 interface and camera provides 8 bit and 10 bit raw bayer pattern(BGGR) image.

we have observed that even though camera AND MIPI CSI both are configured for 2532x1266 resolution but image captured(stored in RAM by VI module) is of resolution of 2496x1266 for 8 bit image and 2528x1266 for 10bit image.

other observation is for 8 bit image, we get image width in multiple of 192 pixels in RAM.

Pratik –

Can you confirm what the VI_CSI_SURFACEx_STRIDE registers are set to?

Line strides in VI need to be 64-byte aligned. So if you’re programming for 2532 bytes of stride, then the lower bits will get truncated, and that could explain the 2496 bytes received in RAW8 mode.

joshua

thanks jwise. as per your explanation, now we understand the logic.

register VI_CSI_SURFACEx_STRIDE is handled by vi2.c driver (drivers/media/platform/soc_camera/tegra_camera/vi2.c). and driver writes bytes_per_line value and it does not check if it is 64 byte aligned or not.
for 8 bit raw bayer format, bytes_per_line = width and for 10bit format bytes_per_line = (width*2)

hi jwise,

one more query, is there any restriction on height as well ?

Pratik –

Huh, interesting, I looked at vi2.c, and I see:

static s32 vi2_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
{
        s32 bytes_per_line = soc_mbus_bytes_per_line(width, mf);

        if (bytes_per_line % 64)
                bytes_per_line = bytes_per_line + (64 - (bytes_per_line % 64));

        return bytes_per_line;
}

which seems to round up. Is it not doing that correctly? If not, I can try and file a bug for you.

I don’t know of any restrictions on height (I think there is some maximum, but I suspect that you are unlikely to hit it; I think the maximum is 8k or something).

joshua

Hi joshua,

we are using L4T release 21.4 and we can not find function vi2_bytes_per_line in our vi2.c file.

can you confirm which version of L4T kernel are you using ?

Good question – this came from a random build that I had lying around my work laptop :-)

Um, I’ll follow up internally to see when this came into existence. ‘git log’ says it happened around January, but indeed, the r21.4 vi2.c looks nothing like what I’m seeing. I’ll ask our software team to try to understand what’s going on here, and hopefully I’ll follow up with you later today.

Ok, I have an answer! Apparently the version that I see does have a bug fix that didn’t make it back to L4T yet (it was supposed to intercept a future L4T release).

Move to L4T is being tracked internally as nvbug 1694764.

In the mean time, you probably will want to modify the surface stride calculations to round up. Sorry for the inconvenience!

thank jwise for clarification.

we can modify the surface stride calculation to round up but our camera will provide image as per the original resolution(without roundup) that means in v4l2 buffer we will have some blank data in one line.

we will put restriction in our camera driver to allow resolution(width) in multiple of 64 bytes only so that we can get whole v4l2 buffer filled with actual data received from camera.

Hi PartikPatel,
Can you please verify the attached patch that adding line alignment check?

drivers/media/platform/soc_camera/tegra_camera/vi2.c | 14 +++++++++++±-
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/soc_camera/tegra_camera/vi2.c b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
index 6a75e8e…4d17cda 100644
— a/drivers/media/platform/soc_camera/tegra_camera/vi2.c
+++ b/drivers/media/platform/soc_camera/tegra_camera/vi2.c
@@ -808,12 +808,22 @@ static int vi2_capture_setup(struct tegra_camera_dev *cam)
return -ENODEV;
}

+static s32 vi2_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
+{

  • s32 bytes_per_line = soc_mbus_bytes_per_line(width, mf);
  • if (bytes_per_line % 64)
  •   bytes_per_line = bytes_per_line + (64 - (bytes_per_line % 64));
    
  • return bytes_per_line;
    +}

static int vi2_capture_buffer_setup(struct tegra_camera_dev *cam,
struct tegra_camera_buffer *buf)
{
struct soc_camera_device *icd = buf->icd;

  • int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
  •   	icd->current_fmt->host_fmt);
    
  • int bytes_per_line = vi2_bytes_per_line(icd->user_width,
  •   				icd->current_fmt->host_fmt);
    
    struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc;
    struct tegra_camera_platform_data *pdata = ssdesc->drv_priv;
    int port = pdata->port;

glo,

we already tried above changes and my comments of post dated 10/15/2015 are based on over testing. with this change, tegra width is aligned to 64 bytes but our camera is outputting data as per original (before alignment) resolution.

that is why we are putting restriction in our camera driver to allow width only of 64 byte alignment. so we get v4l2 buffer completely filled with actual camera data.