Linux Media Controller development
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Tommaso Merciai <tomm.merciai@gmail.com>
Cc: Hans de Goede <hdegoede@redhat.com>,
	Sakari Ailus <sakari.ailus@linux.intel.com>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Andy Shevchenko <andy@kernel.org>, Kate Hsuan <hpa@redhat.com>,
	linux-media@vger.kernel.org
Subject: Re: [PATCH v2 1/5] media: Add MIPI CCI register access helper functions
Date: Fri, 16 Jun 2023 17:17:06 +0300	[thread overview]
Message-ID: <20230616141706.GF14547@pendragon.ideasonboard.com> (raw)
In-Reply-To: <ZIxubbZ6IY9MBqvN@tom-HP-ZBook-Fury-15-G7-Mobile-Workstation>

Hi Tommaso,

On Fri, Jun 16, 2023 at 04:15:09PM +0200, Tommaso Merciai wrote:
> On Fri, Jun 16, 2023 at 04:41:24PM +0300, Laurent Pinchart wrote:
> > On Fri, Jun 16, 2023 at 12:20:16AM +0200, Tommaso Merciai wrote:
> > > On Thu, Jun 15, 2023 at 07:52:36PM +0300, Laurent Pinchart wrote:
> > > > On Thu, Jun 15, 2023 at 06:15:43PM +0200, Tommaso Merciai wrote:
> > > > > On Thu, Jun 15, 2023 at 02:00:46PM +0200, Hans de Goede wrote:
> > > > > > On 6/15/23 13:54, Tommaso Merciai wrote:
> > > > > > > On Thu, Jun 15, 2023 at 01:26:25PM +0200, Tommaso Merciai wrote:
> > > > > > >> On Thu, Jun 15, 2023 at 01:10:40PM +0200, Hans de Goede wrote:
> > > > > > >>> On 6/15/23 12:05, Tommaso Merciai wrote:
> > > > > > >>>> Hi Hans, Laurent, Sakari,
> > > > > > >>>>
> > > > > > >>>> Can I cherry-pick this patch and use these new functions also
> > > > > > >>>> for cci regs of the alvium driver?
> > > > > > >>>
> > > > > > >>> Yes that sounds like a good plan.
> > > > > > >>>
> > > > > > >>>> Are on going to be merge?
> > > > > > >>>
> > > > > > >>> Yes this will hopefully get merged upstream soon.
> > > > > > >>
> > > > > > >> Thanks for the info!
> > > > > > >>
> > > > > > >> I want to ask you your opinion about this:
> > > > > > >>
> > > > > > >> Into alvium driver actually I'm using the following defines
> > > > > > >> manipulations:
> > > > > > >>
> > > > > > >> #define REG_BCRM_REG_ADDR_R				REG_BCRM_CCI_16BIT(0x0014)
> > > > > > >>
> > > > > > >> #define REG_BCRM_FEATURE_INQUIRY_R			REG_BCRM_V4L2_64BIT(0x0008)
> > > > > > >> #define REG_BCRM_DEVICE_FIRMWARE_VERSION_R		REG_BCRM_V4L2_64BIT(0x0010)
> > > > > > >>
> > > > > > >> My plan is to use your cci API for cci register in this way defines
> > > > > > >> became like:
> > > > > > >>
> > > > > > >> #define REG_BCRM_REG_ADDR_R				CCI_REG16(0x0014)
> > > > > > >>
> > > > > > >> And leave v4l2 regs are it are right now:
> > > > > > >>
> > > > > > >> #define REG_BCRM_FEATURE_INQUIRY_R			REG_BCRM_V4L2_64BIT(0x0008)
> > > > > > >> #define REG_BCRM_DEVICE_FIRMWARE_VERSION_R		REG_BCRM_V4L2_64BIT(0x0010)
> > > > > > >>
> > > > > > >> What do you think about?
> > > > > > > 
> > > > > > > Or maybe is worth don't use v4l2 bit for v4l2 regs, I think is implicit
> > > > > > > that what regs that are not CCI are v4l2, then we return wit the
> > > > > > > following defines:
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > #define REG_BCRM_REG_ADDR_R                           CCI_REG16(0x0014)
> > > > > > > ^CCI regs
> > > > > > > 
> > > > > > > #define REG_BCRM_FEATURE_INQUIRY_R                    0x0008 
> > > > > > > #define REG_BCRM_DEVICE_FIRMWARE_VERSION_R            0x0010
> > > > > > > ^v4l2 regs
> > > > > > 
> > > > > > I'm not sure what you mean with "V4L2" registers ? I guess you mean
> > > > > > registers which cannot be accessed through the CCI helper functions,
> > > > > > but starting with v2 this is no longer true. There now is a CCI_REG64()
> > > > > > so you can simply use that.
> > > > > 
> > > > > I'm playing a bit with v3 of your cci api :)
> > > > > 
> > > > > My problem is the following, bcrm regs are not real regs but are offset
> > > > > from bcrm address (this is not fixed, it depends on the camera).
> > > > > 
> > > > > Then the workflow is:
> > > > > 
> > > > >  - read bcrm_address (base address)
> > > > >  - then sum this to the offset (regs)
> > > > > 
> > > > > Myabe this clarify:
> > > > > 
> > > > > static int alvium_read(struct alvium_dev *alvium, u32 reg, u64 *val)
> > > > 
> > > > I would add a int *err argument to your read and write wrappers.
> > > 
> > > 
> > > Thanks for your hint!
> > > What about using:
> > > 
> > > static int alvium_write(struct alvium_dev *alvium, u32 reg, u64 val)
> > > {
> > > 	if (reg & REG_BCRM_V4L2) {
> > > 		reg &= ~REG_BCRM_V4L2;
> > > 		reg += alvium->bcrm_addr;
> > > 	}
> > > 
> > > 	return cci_write(alvium->regmap, reg, val, NULL);
> > > }
> > > 
> > > Then:
> > > 
> > > 	ret = alvium_write(alvium, reg, val);
> > > 	if (ret) {
> > > 		dev_err(dev, "Fail to write reg\n");
> > > 		return ret;
> > > 	}
> > > 
> > > 
> > > I prefer to use this format if for you is ok.
> > > Let me know.
> > 
> > This is fine when you have to write a single register only, but it makes
> > things more complicated when writing multiple registers. Consider this:
> > 
> > 	int ret;
> > 
> > 	ret = alvium_write(alvium, REG_A, val);
> > 	if (ret)
> > 		return ret;
> > 
> > 	ret = alvium_write(alvium, REG_B, val);
> > 	if (ret)
> > 		return ret;
> > 
> > 	ret = alvium_write(alvium, REG_C, val);
> > 	if (ret)
> > 		return ret;
> > 
> > 	ret = alvium_write(alvium, REG_D, val);
> > 	if (ret)
> > 		return ret;
> > 
> > 	return 0;
> > 
> > and compare it to
> > 
> > 	int ret = 0;
> > 
> > 	alvium_write(alvium, REG_A, val, &ret);
> > 	alvium_write(alvium, REG_B, val, &ret);
> > 	alvium_write(alvium, REG_C, val, &ret);
> > 	alvium_write(alvium, REG_D, val, &ret);
> > 
> > 	return ret;
> 
> Is worth to add is also in alvium_write_hshake right?

I'd say it's worth everywhere you can have multiple writes.

> > > > > {
> > > > > 	int ret;
> > > > > 
> > > > > 	if (reg & REG_BCRM_V4L2)
> > > > > 		reg += alvium->bcrm_addr;
> > > > > 
> > > > 
> > > > You should also clear the REG_BCRM_V4L2 bit here:
> > > > 
> > > >  	if (reg & REG_BCRM_V4L2) {
> > > > 		reg &= ~REG_BCRM_V4L2;
> > > >  		reg += alvium->bcrm_addr;
> > > > 	}
> > > > 
> > > > > 	cci_read(alvium->regmap, reg, val, &ret);
> > > > > 	if (ret)
> > > > > 		return ret;
> > > > > 
> > > > > 	return 0;
> > > > 
> > > > Just
> > > > 
> > > > 	return cci_read(alvium->regmap, reg, val, err);
> > > > 
> > > > Same for alvium_write()..
> > > > 
> > > > > }
> > > > > 
> > > > > int alvium_write(struct alvium_dev *alvium, u32 reg, u64 val)
> > > > > {
> > > > > 	int ret;
> > > > > 
> > > > > 	if (reg & REG_BCRM_V4L2)
> > > > > 		reg += alvium->bcrm_addr;
> > > > > 
> > > > > 	cci_write(alvium->regmap, reg, val, &ret);
> > > > > 	if (ret)
> > > > > 		return ret;
> > > > > 
> > > > > 	return 0;
> > > > > }
> > > > > 
> > > > > Where for example:
> > > > > 
> > > > > #define REG_BCRM_V4L2		BIT(31)
> > > > > #define REG_BCRM_V4L2_64BIT(n)	(REG_BCRM_V4L2 | CCI_REG64(n))
> > > > > 
> > > > > #define REG_BCRM_WRITE_HANDSHAKE_RW REG_BCRM_V4L2_8BIT(0x0418)
> > > > > 
> > > > > 
> > > > > But I'm not sure that I'm in the right direction. 
> > > > 
> > > > This looks good to me.
> > > > 
> > > > The fact that both Hans' helpers and part of the Alvium camera registers
> > > > are named CCI is not a complete coincidence, but it doesn't mean they're
> > > > identical. I would thus keep the REG_BCRM_CCI_* macros for clarity,
> > > > simply defining them as CCI_* wrappers:
> > > > 
> > > > #define REG_BCRM_V4L2_8BIT(n)		CCI_REG8(n)
> > > > ...
> > > > 
> > > > > In real I need first to get the real address then sum the bcrm_address
> > > > > if this is a bcrm regs(offset) then re-incapsule the address into the
> > > > > right CCI_REG# defines.
> > > > > 
> > > > > Then I'm not completely sure that cci fits my use case.
> > > > > What do you think about?
> > > > > 
> > > > > Btw really great work! :)
> > > > > 
> > > > > > > ?
> > > > > > > 
> > > > > > >>> Note I'm about to send out a v3 addressing some small
> > > > > > >>> remarks on this v2. I'll Cc you on that.
> > > > > > >>
> > > > > > >> Thanks, in this way I can test that and let you know my feedback.
> > > > > > >>
> > > > > > >>>> Let me know.
> > > > > > >>>> Thanks! :)
> > > > > > >>>>
> > > > > > >>>> On Thu, Jun 15, 2023 at 12:21:00PM +0300, Laurent Pinchart wrote:
> > > > > > >>>>> On Thu, Jun 15, 2023 at 11:11:20AM +0200, Hans de Goede wrote:
> > > > > > >>>>>> On 6/14/23 23:48, Sakari Ailus wrote:
> > > > > > >>>>>>> On Thu, Jun 15, 2023 at 12:34:29AM +0300, Laurent Pinchart wrote:
> > > > > > >>>>>>>> On Wed, Jun 14, 2023 at 08:39:56PM +0000, Sakari Ailus wrote:
> > > > > > >>>>>>>>> On Wed, Jun 14, 2023 at 09:23:39PM +0200, Hans de Goede wrote:
> > > > > > >>>>>>>>>> The CSI2 specification specifies a standard method to access camera sensor
> > > > > > >>>>>>>>>> registers called "Camera Control Interface (CCI)".
> > > > > > >>>>>>>>>>
> > > > > > >>>>>>>>>> This uses either 8 or 16 bit (big-endian wire order) register addresses
> > > > > > >>>>>>>>>> and supports 8, 16, 24 or 32 bit (big-endian wire order) register widths.
> > > > > > >>>>>>>>>>
> > > > > > >>>>>>>>>> Currently a lot of Linux camera sensor drivers all have their own custom
> > > > > > >>>>>>>>>> helpers for this, often copy and pasted from other drivers.
> > > > > > >>>>>>>>>>
> > > > > > >>>>>>>>>> Add a set of generic helpers for this so that all sensor drivers can
> > > > > > >>>>>>>>>> switch to a single common implementation.
> > > > > > >>>>>>>>>>
> > > > > > >>>>>>>>>> These helpers take an extra optional "int *err" function parameter,
> > > > > > >>>>>>>>>> this can be used to chain a bunch of register accesses together with
> > > > > > >>>>>>>>>> only a single error check at the end, rather then needing to error
> > > > > > >>>>>>>>>> check each individual register access. The first failing call will
> > > > > > >>>>>>>>>> set the contents of err to a non 0 value and all other calls will
> > > > > > >>>>>>>>>> then become no-ops.
> > > > > > >>>>>>>>>>
> > > > > > >>>>>>>>>> Link: https://lore.kernel.org/linux-media/59aefa7f-7bf9-6736-6040-39551329cd0a@redhat.com/
> > > > > > >>>>>>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> > > > > > >>>>>>>>>> ---
> > > > > > >>>>>>>>>> Changes in v2:
> > > > > > >>>>>>>>>> - Drop cci_reg_type enum
> > > > > > >>>>>>>>>> - Make having an encoded reg-width mandatory rather then using 0 to encode
> > > > > > >>>>>>>>>>   8 bit width making reg-addresses without an encoded width default to
> > > > > > >>>>>>>>>>   a width of 8
> > > > > > >>>>>>>>>> - Add support for 64 bit wide registers
> > > > > > >>>>>>>>
> > > > > > >>>>>>>> I'm in two minds about this. This means that the read and write
> > > > > > >>>>>>>> functions take a u64 argument, which will be less efficient on 32-bit
> > > > > > >>>>>>>> platforms. I think it would be possible, with some macro magic, to
> > > > > > >>>>>>>> accept different argument sizes, but maybe that's a micro-optimization
> > > > > > >>>>>>>> that would actually result in worse code. 
> > > > > > >>>>>>>>
> > > > > > >>>>>>>> 64-bit support could be useful, but as far as I can tell, it's not used
> > > > > > >>>>>>>> in this series, so maybe we could leave this for later ?
> > > > > > >>>>>>>
> > > > > > >>>>>>> I prefer to have it now, I just told Tommaso working on the Alvium driver
> > > > > > >>>>>>> to use this, and he needs 64-bit access. :-)
> > > > > > >>>>>>>
> > > > > > >>>>>>> You could also easily have 32-bit and 64-bit variant of the functions, with
> > > > > > >>>>>>> C11 _Generic(). Introducing it now would be easier than later.
> > > > > > >>>>>>
> > > > > > >>>>>> I took a quick look at C11 _Generic() and that looks at the type
> > > > > > >>>>>> of "things" so in this case it would look at type of the val argument.
> > > > > > >>>>>>
> > > > > > >>>>>> Problem is that that can still be e.g. an int when doing a
> > > > > > >>>>>> read/write from a 64 bit registers.
> > > > > > >>>>>>
> > > > > > >>>>>> So we would then need to handle the 64 bit width case in the 32
> > > > > > >>>>>> bit versions of the functions too.
> > > > > > >>>>>>
> > > > > > >>>>>> And likewise I can see someone passing a long on a 64 bit
> > > > > > >>>>>> arch while doing a cci_write() to a non 64 bit register.
> > > > > > >>>>>>
> > > > > > >>>>>> So this would basically mean copy and pasting cci_read()
> > > > > > >>>>>> + cci_write() 2x with the only difference being one
> > > > > > >>>>>> variant taking a 32 bit val argument and the other a
> > > > > > >>>>>> 64 bit val argument.
> > > > > > >>>>>>
> > > > > > >>>>>> This seems like premature optimization to me.
> > > > > > >>>>>>
> > > > > > >>>>>> As mentioned in my reply to Laurent if we want to
> > > > > > >>>>>> optimize things we really should look at avoiding
> > > > > > >>>>>> unnecessary i2c transfers, or packing multiple
> > > > > > >>>>>> writes into a single i2c transfer for writes to
> > > > > > >>>>>> subsequent registers. That is where significant
> > > > > > >>>>>> speedups can be made.
> > > > > > >>>>>
> > > > > > >>>>> This is something I'd really like to see, but it's way more work.
> > > > > > >>>>>
> > > > > > >>>>> There's an important need of applying changes atomically, which is often
> > > > > > >>>>> not possible to strictly guarantee over I2C. Userspace ends up writing
> > > > > > >>>>> V4L2 controls as quickly as it can after the start of a frame, hoping
> > > > > > >>>>> they will all reach the sensor before the end of the frame. Some
> > > > > > >>>>> platforms have camera-specific I2C controllers that have the ability to
> > > > > > >>>>> buffer I2C transfers and issue them based on a hardware trigger. How to
> > > > > > >>>>> fit this in thé kernel I2C API will be an interesting exercise.

-- 
Regards,

Laurent Pinchart

  reply	other threads:[~2023-06-16 14:17 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-14 19:23 [PATCH v2 0/5] media: Add MIPI CCI register access helper functions Hans de Goede
2023-06-14 19:23 ` [PATCH v2 1/5] " Hans de Goede
2023-06-14 20:09   ` Andy Shevchenko
2023-06-14 20:39   ` Sakari Ailus
2023-06-14 21:34     ` Laurent Pinchart
2023-06-14 21:48       ` Sakari Ailus
2023-06-14 22:11         ` Laurent Pinchart
2023-06-15  9:11         ` Hans de Goede
2023-06-15  9:21           ` Laurent Pinchart
2023-06-15 10:05             ` Tommaso Merciai
2023-06-15 11:10               ` Hans de Goede
2023-06-15 11:26                 ` Tommaso Merciai
2023-06-15 11:54                   ` Tommaso Merciai
2023-06-15 12:00                     ` Hans de Goede
2023-06-15 16:15                       ` Tommaso Merciai
2023-06-15 16:52                         ` Laurent Pinchart
2023-06-15 22:20                           ` Tommaso Merciai
2023-06-16 13:41                             ` Laurent Pinchart
2023-06-16 14:08                               ` Tommaso Merciai
2023-06-16 14:15                               ` Tommaso Merciai
2023-06-16 14:17                                 ` Laurent Pinchart [this message]
2023-06-16 14:56                                   ` Tommaso Merciai
2023-06-16 15:07                                     ` Laurent Pinchart
2023-06-16 16:34                                       ` Tommaso Merciai
2023-06-16 16:54                         ` Hans de Goede
2023-06-19  8:13                           ` Tommaso Merciai
2023-06-19  8:46                             ` Hans de Goede
2023-06-15 10:08           ` Sakari Ailus
2023-06-15  8:56       ` Hans de Goede
2023-06-14 22:21     ` Andy Shevchenko
2023-06-14 22:24       ` Andy Shevchenko
2023-06-15  8:45     ` Hans de Goede
2023-06-15  9:54       ` Sakari Ailus
2023-06-15 10:15         ` Hans de Goede
2023-06-15 10:35           ` Andy Shevchenko
2023-06-15 11:41           ` Sakari Ailus
2023-06-15 12:05             ` Hans de Goede
2023-06-15 13:19               ` Sakari Ailus
2023-06-15 13:28                 ` Sakari Ailus
2023-06-15 13:52                 ` Hans de Goede
2023-06-15 13:23             ` Andy Shevchenko
2023-06-14 19:23 ` [PATCH v2 2/5] media: ov5693: Convert to new CCI register access helpers Hans de Goede
2023-06-14 20:13   ` Andy Shevchenko
2023-06-15  9:16     ` Hans de Goede
2023-06-14 21:54   ` Laurent Pinchart
2023-06-14 19:23 ` [PATCH v2 3/5] media: imx290: " Hans de Goede
2023-06-14 22:04   ` Laurent Pinchart
2023-06-14 19:23 ` [PATCH v2 4/5] media: atomisp: ov2680: " Hans de Goede
2023-06-14 20:15   ` Andy Shevchenko
2023-06-15  9:02     ` Hans de Goede
2023-06-15 10:16       ` Andy Shevchenko
2023-06-14 19:23 ` [PATCH v2 5/5] media: Remove ov_16bit_addr_reg_helpers.h Hans de Goede
2023-06-14 20:17   ` Andy Shevchenko

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=20230616141706.GF14547@pendragon.ideasonboard.com \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=andy@kernel.org \
    --cc=hdegoede@redhat.com \
    --cc=hpa@redhat.com \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=sakari.ailus@linux.intel.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