Re: [PATCH 3/3] media: i2c: imx219: Add support 640x480

From: Dave Stevenson
Date: Mon Mar 02 2020 - 07:50:48 EST


Hi Lad.

Thanks for the patch.

On Fri, 28 Feb 2020 at 16:55, Lad Prabhakar <prabhakar.csengg@xxxxxxxxx> wrote:
>
> This patch adds support to 640x480 cropped resolution for the sensor

I was a little hesitant to add cropped modes without good reason.
Processing them through an ISP with something like lens shading
compensation requires the ISP to know the crop, so ideally it should
be reflected through the selection API (probably read-only - I'm not
sure you can modify the register set totally dynamically for
cropping).
I know we have the 1080p mode in there already which is cropped, but
that was mainly as it is the only way to get 30fps 1080p over two
CSI-2 lanes. I wonder if there is a better way of reflecting this.

> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
> ---
> drivers/media/i2c/imx219.c | 70 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 70 insertions(+)
>
> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> index 1388c9bc00bb..232ebf41063a 100644
> --- a/drivers/media/i2c/imx219.c
> +++ b/drivers/media/i2c/imx219.c
> @@ -54,6 +54,7 @@
> #define IMX219_VTS_15FPS 0x0dc6
> #define IMX219_VTS_30FPS_1080P 0x06e3
> #define IMX219_VTS_30FPS_BINNED 0x06e3
> +#define IMX219_VTS_30FPS_640x480 0x0239
> #define IMX219_VTS_MAX 0xffff
>
> #define IMX219_VBLANK_MIN 4
> @@ -329,6 +330,65 @@ static const struct imx219_reg mode_1640_1232_regs[] = {
> {0x0163, 0x78},
> };
>
> +static const struct imx219_reg mode_640_480_regs[] = {

Can I ask where these register settings came from? They differ from
references I have in a few odd ways.

There's also a comment at the top of mode arrays declaring the
supported modes and where they came from. Could you update that
please?

> + {0x0100, 0x00},
> + {0x30eb, 0x0c},
> + {0x30eb, 0x05},
> + {0x300a, 0xff},
> + {0x300b, 0xff},
> + {0x30eb, 0x05},
> + {0x30eb, 0x09},

Datasheet section 3-4 says these are to access manufacturer specific
registers, but the access sequence should be
0x30eb 0x05
0x30eb 0x0c
0x300a 0xff
0x300b 0xff
0x30eb 0x05
0x30eb 0x09
Is there a reason your first two writes are reversed compared to this
published order?

> + {0x0114, 0x01},
> + {0x0128, 0x01},

DPHY_CTRL RW MIPI Global timing setting
0:auto mode, 1:manual mode

All the other modes have this as auto mode. Why does this mode need
manual settings, and is something else configuring those manual
values?

> + {0x012a, 0x18},
> + {0x012b, 0x00},
> + {0x0162, 0x0d},
> + {0x0163, 0xe7},

All the other modes have set line length to 0x0d78 (3448 decimal)
rather than your 0xd37 (3559).
Is there any specific reason for this? If we need a different value,
then we also need to vary IMX219_PPL_DEFAULT and V4L2_CID_HBLANK
depending on mode. Or probably better would be to make it variable,
but that has a load of other implications.

> + {0x0164, 0x03},
> + {0x0165, 0xe8},
> + {0x0166, 0x08},
> + {0x0167, 0xe7},
> + {0x0168, 0x02},
> + {0x0169, 0xf0},
> + {0x016a, 0x06},
> + {0x016b, 0xaf},
> + {0x016c, 0x02},
> + {0x016d, 0x80},
> + {0x016e, 0x01},
> + {0x016f, 0xe0},
> + {0x0170, 0x01},
> + {0x0171, 0x01},
> + {0x0172, 0x00},

0x0172 is IMAGE_ORIENTATION_A, which is handled via V4L2_CID_HFLIP /
V4L2_CID_VFLIP, not in the mode table.

> + {0x0174, 0x03},
> + {0x0175, 0x03},
> + {0x0301, 0x05},
> + {0x0303, 0x01},
> + {0x0304, 0x03},
> + {0x0305, 0x03},
> + {0x0306, 0x00},
> + {0x0307, 0x39},
> + {0x0309, 0x08},

"OPPXCK_DIV. Ouptut pixel clock divider value, default 0x0A."
This looks like it is a change that should be part of the support for
8bit formats.
Have you tested this mode with 10bit readout? Are the data rates correct?

> + {0x030b, 0x01},
> + {0x030c, 0x00},
> + {0x030d, 0x72},
> + {0x0624, 0x06},
> + {0x0625, 0x68},
> + {0x0626, 0x04},
> + {0x0627, 0xd0},
> + {0x455e, 0x00},
> + {0x471e, 0x4b},
> + {0x4767, 0x0f},
> + {0x4750, 0x14},
> + {0x4540, 0x00},
> + {0x47b4, 0x14},
> + {0x4713, 0x30},
> + {0x478b, 0x10},
> + {0x478f, 0x10},
> + {0x4793, 0x10},
> + {0x4797, 0x0e},
> + {0x479b, 0x0e},
> +};
> +
> static const char * const imx219_test_pattern_menu[] = {
> "Disabled",
> "Color Bars",
> @@ -414,6 +474,16 @@ static const struct imx219_mode supported_modes[] = {
> .regs = mode_1640_1232_regs,
> },
> },
> + {
> + /* 640x480 30fps mode */
>
> + .width = 640,
> + .height = 480,
> + .vts_def = IMX219_VTS_30FPS_640x480,

I've just run this mode on a Pi and I get a default of about 84fps via
v4l2-ctl to /dev/null. Is the default frame rate expected to be 30fps?
In which case I think the value of IMX219_VTS_30FPS_640x480 is wrong
(I'd expect 0x6e3 again, same as the other modes), or the comments and
define names are wrong. One or other ought to be fixed.

My calculations say that with:
- VBLANK set to 89
- a pixel rate of 182400000 (based on IMX219_PIXEL_RATE)
- HBLANK fixed at 2808
- frame being 640x480
The overall frame size is therefore (640+2808) * (480+89) = 1961912
pixel clocks. That would at first glance appear to give a frame rate
of 92fps. Testing with an alternate tool is giving me timings for
90fps but with a few dropped frames (the dropped frames would explain
v4l2-ctl reading slightly low).

If I amend OPPXCK_DIV to be 0xA (the same as the other modes), then it
doesn't appear to change.
However hold off on investigating the specifics for now - I appear to
be unable to select the 10bit/pixel formats, so I suspect something is
up with patch 2 that added the 8bit support (I was about to review
that anyway).

Dave

> + .reg_list = {
> + .num_of_regs = ARRAY_SIZE(mode_640_480_regs),
> + .regs = mode_640_480_regs,
> + },
> + },
> };
>
> struct imx219 {
> --
> 2.20.1
>