From: Sakari Ailus <sakari.ailus@linux.intel.com>
To: Jai Luthra <jai.luthra@ideasonboard.com>
Cc: "Dave Stevenson" <dave.stevenson@raspberrypi.com>,
"Hans Verkuil" <hans@jjverkuil.nl>,
"Jacopo Mondi" <jacopo.mondi@ideasonboard.com>,
"Laurent Pinchart" <laurent.pinchart@ideasonboard.com>,
linux-media@vger.kernel.org,
Prabhakar <prabhakar.csengg@gmail.com>,
"Kate Hsuan" <hpa@redhat.com>,
"Tommaso Merciai" <tomm.merciai@gmail.com>,
"Benjamin Mugnier" <benjamin.mugnier@foss.st.com>,
"Sylvain Petinot" <sylvain.petinot@foss.st.com>,
"Christophe JAILLET" <christophe.jaillet@wanadoo.fr>,
"Julien Massot" <julien.massot@collabora.com>,
"Naushir Patuck" <naush@raspberrypi.com>,
"Yan, Dongcheng" <dongcheng.yan@intel.com>,
"Stefan Klug" <stefan.klug@ideasonboard.com>,
"Mirela Rabulea" <mirela.rabulea@nxp.com>,
"André Apitzsch" <git@apitzsch.eu>,
"Heimir Thor Sverrisson" <heimir.sverrisson@gmail.com>,
"Kieran Bingham" <kieran.bingham@ideasonboard.com>,
"Mehdi Djait" <mehdi.djait@linux.intel.com>,
"Ricardo Ribalda Delgado" <ribalda@kernel.org>,
"Hans de Goede" <hansg@kernel.org>,
"Tomi Valkeinen" <tomi.valkeinen@ideasonboard.com>,
"David Plowman" <david.plowman@raspberrypi.com>,
"Yu, Ong Hock" <ong.hock.yu@intel.com>,
"Ng, Khai Wen" <khai.wen.ng@intel.com>,
"Rishikesh Donadkar" <r-donadkar@ti.com>
Subject: Re: [PATCH v5 06/10] media: imx219: Fix vertical blanking and exposure for analogue binning
Date: Wed, 10 Jun 2026 12:47:22 +0300 [thread overview]
Message-ID: <aikyqqC_BsYI5D2M@kekkonen.localdomain> (raw)
In-Reply-To: <178091757893.16054.4583389270412251379@freya>
Hi Jai,
On Mon, Jun 08, 2026 at 04:49:38PM +0530, Jai Luthra wrote:
> Quoting Jai Luthra (2026-06-08 16:01:06)
> > Hi Jacopo, Sakari,
> > ++ Dave, Hans and Laurent,
> >
> > Quoting Jacopo Mondi (2026-06-08 12:28:46)
> > > Hi Sakari
> > >
> > > On Mon, Jun 08, 2026 at 12:53:52AM +0300, Sakari Ailus wrote:
> > > > When vertical analogue binning is in use, the minimum frame length in
> > > > lines decreases to around half of the normal. In relation to the sensor's
> > > > output size this means vertical blanking can be negative but that's not an
> > > > issue as control values are signed. Remove the workaround for this
> > >
> > > Didn't we just discussed two weeks ago in media summit how negative
> > > blankings are a bad idea, and of all drivers one could decide to play
> > > with imx219 is probably the worse due it's large use base and the fact
> > > libcamera doesn't support negative blankings ?
> > >
> > > Have I missed something ?
> > >
> >
> > I think it would be helpful if I write down clearly how this sensor
> > operates (to the best of my knowledge) so we can decide on the correct
> > fix:
> >
> > --------------------
> >
> > IMX219 sensor has an active resolution of 3280x2464.
> >
> > The driver currently programs the sensor VT pixel clock as fixed for a
> > given lane configuration.
> >
> > In 2-lane mode it reads 182.4 MPixel/second:
> >
> > #define IMX219_PIXEL_RATE 182400000
> >
> > And the framerate is given by:
> >
> > PIXEL_RATE / (FRAME_LENGTH * LINE_LENGTH)
> >
> > where FRAME_LENGTH and LINE_LENGTH are registers that include the active
> > height and width along with blankings.
> >
> > There are restrictions on the minimum of the LINE_LENGTH register and
> > minimum vertical blanking (32), which cap the framerate for the full resolution
> > mode.
> >
> > MIN_LINE_LENGTH: 0xd78 => 3448 pixels
> > MIN_FRAME_LENGTH: ACTIVE_HEIGHT + MIN_VBLANK (32) = 2464 + 32
> > => 2496 lines
> >
> > The maximum frame rate is
> >
> > 182400000/(2496*3448) => ~ 21.2 frames/second
> >
> > --------------------
> >
> > A user might want to stream a lower resolution with the full field-of-view,
> > let's take 1640x1232 (which is exactly 1/2 of active area) as an example.
> >
> > The sensor hardware can achieve this using two different binning modes:
> >
> > 2x2-binning (regval: 0x1)
> > 2x2-analog-(special)-binning (regval: 0x3)
> >
> > The sensor pipeline looks like:
> >
> > active pixel array ->
> > analogue crop (none) ->
> > 2x2 binning and ADC readout ->
> > output to CSI-2 bus
> >
> > The mode names suggest that binning can happen either before or after ADC,
> > but the datasheet is not very clear about the process. We can infer
> > some details though. See below..
> >
> > --------------------
> >
> > With the "normal" 2x2-binning mode the sensor allows programming
> > FRAME_LENGTH to a lower value. The driver still uses the min blanking of 32
> > lines, but the height is now 1232, half of the 2464 before.
> >
> > MIN_LINE_LENGTH: 0xd78 => 3448 pixels
> > MIN_FRAME_LENGTH: READOUT_HEIGHT + MIN_VBLANK = 1232 + 32
> > => 1264 lines
> >
> > The maximum frame rate is
> >
> > 182400000/(1264*3448) => ~ 41.8 frames/second
> >
> > --------------------
> >
> > With the "special" 2x2-binning mode, the datasheet notes that FRAME_LENGTH
> > register should be in units of 2 Lines instead of 1 Line. This means
> > cutting it down by half once more:
> >
> > MIN_FRAME_LENGTH: (READOUT_HEIGHT + MIN_VBLANK)/2 = (1232 + 32)/2
> > => 632 lines
> >
> > While there is a slightly higher minimum enforced for the line length:
> >
> > MIN_LINE_LENGTH: 0xde8 => 3560 pixels
> >
> > The maximum frame rate is
> >
> > 182400000/(632*3560) => ~ 81.0 frames/second
> >
> > ===================
> >
> > Through the minimum allowed values of the FRAME_LENGTH and LINE_LENGTH
> > registers and maximum possible framerate, I think it is safe to say that:
> >
> > 2x2-binning => Readout half the pixels (do vertical averaging in the
> > analogue domain, before ADC
> > reads out the voltages)
> >
> > 2x2-special-binning => Readout a quarter of the pixels (???)
> >
> > FRAME_LENGTH being 1/4th of normal would seem to suggest that it is a 4x1
> > binning (combining 4 lines instead of blocks of 2x2).. which does not make
> > sense to me.
> >
> > My best guess is that in 2x2-special-binning mode the sensor does *both
> > horizontal and vertical* averaging in the analogue domain, before the ADC
> > reads out the voltages.
> >
> > A higher minimum LINE_LENGTH value for this mode is the best "hard"
> > evidence I have for this guess unfortunately, as the datasheet is quite
> > lacking on this topic.
> >
>
> Found another evidence for this, see "Table 16 Mode Example" in the
> datasheet.
>
> It mentions "H Binning = Analog" for x2 binning mode (with ~4x the FPS)
> And "H Binning = Digital" for x4 binning mode
>
> It doesn't mention a ~2x FPS mode, which I assume is the normal 2x2-binning
> mode, where I again assume that horizontal binning is done digitally.
Most likely 4x vertical binning uses a combination of analogue and digital
binning. The type of the binning in general doesn't matter much, apart from
affecting the minimum line length in pixels and frame length in lines
values.
>
>
> > ====================
> >
> > The APIs before Sakari's series expose HBLANK and VBLANK controls instead
> > of the actual FRAME_LENGTH/LINE_LENGTH registers to the userspace.
> >
> > The minimum value of FRAME_LENGTH is 632 when we are streaming 1640x1232,
> > so the sensor registers would suggest that we have a *negative vertical
> > blanking*. Which as Jacopo and Laurent both point out, does not make any
> > conceptual sense whatsoever.
> >
> > What the driver does today to avoid these negative values is to double the
> > PIXEL_RATE control value to 364800000 when using 2x2-special-binning mode
> > (and thus userspace has no idea the FRAME_LENGTH/VBLANK is in units of
> > 2xLines)
> >
> > As Sakari pointed out, that does not make any sense either. The sensor PLL
> > values are completely unchanged, so the pixel readout must still be
> > happening at the same rate. Moreover, the new raw sensor model will expose
> > FRAME_LENGTH and LINE_LENGTH directly to userspace, and this hack of
> > doubling the PIXEL_RATE breaks those calculations.
> >
> > ===================
> >
> > If we want to support the new raw sensor model (that mandates the new
> > FRAME_LENGTH and LINE_LENGTH controls) for this sensor we have to
> > fix the PIXEL_RATE for sure. I see two options going forward:
> >
> > OPTION 1 (as proposed by Sakari):
> >
> > Fix PIXEL_RATE to 182400000 and allow **negative values** for HBLANK
> > and VBLANK controls when using 2x2-special-binning mode.
> >
> > This will break any userspace tools, many libcamera pipelines included,
> > that never expected those control values to be negative (even though
> > the API has always permitted those)
That's a clear bug, but it only becomes apparent when the sign bit is set.
> >
> > OPTION 2 (something that struck me today morning discussing with Jacopo):
> >
> > Fix PIXEL_RATE to 182400000 but **adjust the HBLANK values** to go
> > lower to compensate, which will diverge from the sensor registers which
> > keep MIN_LINE_LENGTH fixed across both binning modes.
> >
> > This will make the driver quite more complicated, but userspace
> > expectations of non-negative blankings will be met. And it's likely
> > that the sensor is internally doing pre-ADC averaging horizontally as
> > well, or so my best guess is.
> >
>
> Which makes me lean more on OPTION 2 now.
>
> In our case above with 2x2-special-binning mode for 1640x1232, the register
> values are:
>
> LINE_LENGTH = 3560 pixels
> FRAME_LENGTH = 632 lines
>
>
> So OPTION 1 would give us:
>
> HBLANK = 1920, VBLANK = -600
>
> When actually the datasheet's "H Binning = Analog" would suggest to me that
> reality looks more like:
>
> LINE_LENGTH = 1780 pixels
> FRAME_LENGTH = 1264 lines
>
> So OPTION 2 would give us:
>
> HBLANK = 140, VBLANK = 32
This approach has the downsides that 1) it doesn't reflect what the sensor
apparently does and 2) you lose one bit of granularity on line length in
pixels.
The advantage still is that it works around the sign bit issue. The new
controls still have their proper values but conversion between the two
becomes rather complicated. See
<URL:https://git.linuxtv.org/sailus/media_tree.git/commit/?h=metadata&id=366cb25c7d944ef2935668a07471e4576e7088ed>
for instance how it looks like without that.
>
> > Of course, there are other options to just leave this highly used sensor
> > alone, or support embedded data and internal pads without mandating the new
> > FRAME_LENGTH and LINE_LENGTH controls. But I personally would leave that as
> > a last resort.
I agree. Especially because of its wide user base, it'd be really nice to
convert the imx219 to the Common Raw Sensor Model.
--
Regards,
Sakari Ailus
next prev parent reply other threads:[~2026-06-10 9:47 UTC|newest]
Thread overview: 99+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-07 21:53 [PATCH v5 00/10] Metadata series preparation Sakari Ailus
2026-06-07 21:53 ` [PATCH v5 01/10] media: Documentation: Improve pixel rate calculation documentation Sakari Ailus
2026-06-07 21:53 ` [PATCH v5 02/10] media: imx219: Scale the vblank limits according to rate_factor Sakari Ailus
2026-06-08 7:26 ` Laurent Pinchart
2026-06-08 15:29 ` Dave Stevenson
2026-06-08 21:28 ` Laurent Pinchart
2026-06-09 5:58 ` Jai Luthra
2026-06-09 6:01 ` Jai Luthra
2026-06-10 11:48 ` Laurent Pinchart
2026-06-07 21:53 ` [PATCH v5 03/10] media: imx219: Account rate_factor in setting upper exposure limit Sakari Ailus
2026-06-07 22:05 ` sashiko-bot
2026-06-08 9:06 ` Laurent Pinchart
2026-06-08 13:44 ` Sakari Ailus
2026-06-08 15:42 ` Dave Stevenson
2026-06-08 21:38 ` Laurent Pinchart
2026-06-18 10:40 ` Sakari Ailus
2026-07-02 17:04 ` Dave Stevenson
2026-07-03 21:36 ` Sakari Ailus
2026-06-07 21:53 ` [PATCH v5 04/10] media: imx219: Make control handler ops for PIXEL_RATE NULL Sakari Ailus
2026-06-08 7:36 ` Laurent Pinchart
2026-06-08 7:53 ` Jacopo Mondi
2026-06-08 8:03 ` Laurent Pinchart
2026-06-08 8:14 ` Sakari Ailus
2026-06-08 8:24 ` Laurent Pinchart
2026-06-08 10:21 ` Sakari Ailus
2026-06-08 10:27 ` Laurent Pinchart
2026-06-08 13:47 ` Sakari Ailus
2026-06-08 14:42 ` Laurent Pinchart
2026-06-09 6:29 ` Jacopo Mondi
2026-06-09 14:55 ` Hans Verkuil
2026-06-09 15:15 ` Laurent Pinchart
2026-06-09 15:56 ` Dave Stevenson
2026-06-09 16:07 ` Laurent Pinchart
2026-06-09 16:44 ` Dave Stevenson
2026-06-07 21:53 ` [PATCH v5 05/10] media: imx219: Rename "binning" as "bin_hv" in imx219_set_pad_format Sakari Ailus
2026-06-08 15:45 ` Dave Stevenson
2026-06-07 21:53 ` [PATCH v5 06/10] media: imx219: Fix vertical blanking and exposure for analogue binning Sakari Ailus
2026-06-07 22:07 ` sashiko-bot
2026-06-08 6:58 ` Jacopo Mondi
2026-06-08 9:10 ` Laurent Pinchart
2026-06-08 14:07 ` Sakari Ailus
2026-06-08 16:23 ` Jai Luthra
2026-06-08 21:52 ` Laurent Pinchart
2026-06-10 8:27 ` Sakari Ailus
2026-06-10 8:45 ` Jai Luthra
2026-06-08 10:31 ` Jai Luthra
2026-06-08 11:19 ` Jai Luthra
2026-06-10 9:47 ` Sakari Ailus [this message]
2026-06-10 10:29 ` Jai Luthra
2026-06-10 10:57 ` Jai Luthra
2026-06-11 8:58 ` Sakari Ailus
2026-06-08 18:06 ` Dave Stevenson
2026-06-09 16:48 ` Jai Luthra
2026-06-10 10:30 ` Sakari Ailus
2026-06-10 11:59 ` Jai Luthra
2026-06-10 10:13 ` Sakari Ailus
2026-06-10 16:00 ` Jai Luthra
2026-06-08 21:01 ` Laurent Pinchart
2026-06-07 21:53 ` [PATCH v5 07/10] media: Improve enable_streams and disable_streams documentation Sakari Ailus
2026-06-08 9:29 ` Laurent Pinchart
2026-06-08 14:28 ` Sakari Ailus
2026-06-07 21:53 ` [PATCH v5 08/10] media: v4l2-subdev: Move subdev client capabilities into a new struct Sakari Ailus
2026-06-08 9:34 ` Laurent Pinchart
2026-06-08 14:35 ` Sakari Ailus
2026-06-07 21:53 ` [PATCH v5 09/10] media: v4l2-subdev: Add v4l2_subdev_get_fmt_ci() Sakari Ailus
2026-06-08 7:48 ` Laurent Pinchart
2026-06-07 21:53 ` [PATCH v5 10/10] media: v4l2-subdev: Add struct v4l2_subdev_client_info pointer to pad ops Sakari Ailus
2026-06-08 10:16 ` Laurent Pinchart
2026-06-28 14:20 ` Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 00/16] Metadata series preparation Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 01/16] media: Documentation: Improve pixel rate calculation documentation Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 02/16] media: imx219: Account rate_factor in setting upper exposure limit Sakari Ailus
2026-07-02 17:10 ` Dave Stevenson
2026-07-01 12:26 ` [PATCH v6 03/16] media: imx219: Account for rate_factor in control steps Sakari Ailus
2026-07-02 17:09 ` Dave Stevenson
2026-07-01 12:26 ` [PATCH v6 04/16] media: imx219: The horizontal blanking step is 8 Sakari Ailus
2026-07-02 13:57 ` Dave Stevenson
2026-07-01 12:26 ` [PATCH v6 05/16] media: imx219: Rename "binning" as "bin_hv" in imx219_set_pad_format Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 06/16] media: Improve enable_streams and disable_streams documentation Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 07/16] media: v4l2-subdev: Move subdev client capabilities into a new struct Sakari Ailus
2026-07-01 16:17 ` Frank Li
2026-07-01 12:26 ` [PATCH v6 08/16] media: v4l2-subdev: Move op check to sub-device op wrappers Sakari Ailus
2026-07-01 16:37 ` Frank Li
2026-07-04 12:11 ` Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 09/16] media: v4l2-subdev: Always call get_fmt() if set_fmt() is unavailable Sakari Ailus
2026-07-01 16:42 ` Frank Li
2026-07-04 12:15 ` Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 10/16] media: rdacm20: Don't assign set_fmt() Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 11/16] " Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 12/16] media: gc0310: " Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 13/16] media: v4l2-subdev: Add v4l2_subdev_call_ci_state_{active,try} Sakari Ailus
2026-07-01 16:57 ` Frank Li
2026-07-04 12:16 ` Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 14/16] media: mt9m001: Pass sub-device state to set_selection() callback Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 15/16] media: cvs: Drop comments on sub-device operations Sakari Ailus
2026-07-01 12:26 ` [PATCH v6 15/15] media: v4l2-subdev: Add struct v4l2_subdev_client_info pointer to pad ops Sakari Ailus
2026-07-01 17:00 ` Frank Li
2026-07-01 12:26 ` [PATCH v6 16/16] " Sakari Ailus
2026-07-01 17:01 ` Frank Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aikyqqC_BsYI5D2M@kekkonen.localdomain \
--to=sakari.ailus@linux.intel.com \
--cc=benjamin.mugnier@foss.st.com \
--cc=christophe.jaillet@wanadoo.fr \
--cc=dave.stevenson@raspberrypi.com \
--cc=david.plowman@raspberrypi.com \
--cc=dongcheng.yan@intel.com \
--cc=git@apitzsch.eu \
--cc=hans@jjverkuil.nl \
--cc=hansg@kernel.org \
--cc=heimir.sverrisson@gmail.com \
--cc=hpa@redhat.com \
--cc=jacopo.mondi@ideasonboard.com \
--cc=jai.luthra@ideasonboard.com \
--cc=julien.massot@collabora.com \
--cc=khai.wen.ng@intel.com \
--cc=kieran.bingham@ideasonboard.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=mehdi.djait@linux.intel.com \
--cc=mirela.rabulea@nxp.com \
--cc=naush@raspberrypi.com \
--cc=ong.hock.yu@intel.com \
--cc=prabhakar.csengg@gmail.com \
--cc=r-donadkar@ti.com \
--cc=ribalda@kernel.org \
--cc=stefan.klug@ideasonboard.com \
--cc=sylvain.petinot@foss.st.com \
--cc=tomi.valkeinen@ideasonboard.com \
--cc=tomm.merciai@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox