All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jacopo Mondi <jacopo@jmondi.org>
To: Kieran Bingham <kieran.bingham@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	Jacopo Mondi <jacopo+renesas@jmondi.org>,
	niklas.soderlund+renesas@ragnatech.se,
	linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org
Subject: Re: [PATCH v2 6/6] media: adv748x: Implement TX link_setup callback
Date: Thu, 10 Jan 2019 09:58:43 +0100	[thread overview]
Message-ID: <20190110085843.cju2gjrr4vm3acby@uno.localdomain> (raw)
In-Reply-To: <221dd6e0-bf90-5215-eaad-004eac59838d@ideasonboard.com>

[-- Attachment #1: Type: text/plain, Size: 7315 bytes --]

On Wed, Jan 09, 2019 at 02:15:33PM +0000, Kieran Bingham wrote:
> On 09/01/2019 00:15, Laurent Pinchart wrote:
> > Hello,
> >
> > On Monday, 7 January 2019 14:36:28 EET Kieran Bingham wrote:
> >> On 06/01/2019 15:54, Jacopo Mondi wrote:
> >>> When the adv748x driver is informed about a link being created from HDMI
> >>> or AFE to a CSI-2 TX output, the 'link_setup()' callback is invoked. Make
> >>> sure to implement proper routing management at link setup time, to route
> >>> the selected video stream to the desired TX output.
> >>
> >> Overall this looks like the right approach - but I feel like the
> >> handling of the io10 register might need some consideration, because
> >> it's value depends on the condition of both CSI2 transmitters, not just
> >> the currently parsed link.
> >>
> >> I had a go at some pseudo - uncompiled/untested code inline as a suggestion.
> >>
> >> If you think it's better - feel free to rework it in ... or not as you
> >> see fit.
> >>
> >>> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> >>> ---
> >>>
> >>>  drivers/media/i2c/adv748x/adv748x-core.c | 57 +++++++++++++++++++++++-
> >>>  drivers/media/i2c/adv748x/adv748x.h      |  2 +
> >>>  2 files changed, 58 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
> >>> b/drivers/media/i2c/adv748x/adv748x-core.c index
> >>> 200e00f93546..a586bf393558 100644
> >>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> >>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> >>> @@ -335,6 +335,60 @@ int adv748x_tx_power(struct adv748x_csi2 *tx, bool
> >>> on)
> >>>  /* ----------------------------------------------------------------------
> >>>   * Media Operations
> >>>   */
> >>> +static int adv748x_link_setup(struct media_entity *entity,
> >>> +			      const struct media_pad *local,
> >>> +			      const struct media_pad *remote, u32 flags)
> >>> +{
> >>> +	struct v4l2_subdev *rsd = media_entity_to_v4l2_subdev(remote->entity);
> >>> +	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
> >>> +	struct adv748x_state *state = v4l2_get_subdevdata(sd);
> >>> +	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
> >>> +	bool enable = flags & MEDIA_LNK_FL_ENABLED;
> >>> +	u8 io10;
> >>> +
> >>> +	/* Refuse to enable multiple links to the same TX at the same time. */
> >>> +	if (enable && tx->src)
> >>> +		return -EINVAL;
> >>> +
> >>> +	/* Set or clear the source (HDMI or AFE) and the current TX. */
> >>> +	if (rsd == &state->afe.sd)
> >>> +		state->afe.tx = enable ? tx : NULL;
> >>> +	else
> >>> +		state->hdmi.tx = enable ? tx : NULL;
> >>> +
> >>> +	tx->src = enable ? rsd : NULL;
> >>> +
> >>> +	if (!enable)
> >>> +		return 0;
> >>
> >> Don't we potentially want to take any action on disable to power down
> >> links below ?
> >>
> >>> +
> >>> +	/* Change video stream routing, according to the newly enabled link. */
> >>> +	io10 = io_read(state, ADV748X_IO_10);
> >>> +	if (rsd == &state->afe.sd) {
> >>> +		/*
> >>> +		 * Set AFE->TXA routing and power off TXB if AFE goes to TXA.
> >>> +		 * if AFE goes to TXB, we need both TXA and TXB powered on.
> >>> +		 */
> >>> +		io10 &= ~ADV748X_IO_10_CSI1_EN;
> >>> +		io10 &= ~ADV748X_IO_10_CSI4_IN_SEL_AFE;
> >>> +		if (is_txa(tx))
> >>> +			io10 |= ADV748X_IO_10_CSI4_IN_SEL_AFE;
> >>
> >> Shouldn't the CSI4 be enabled here too? or are we assuming it's already
> >> (/always) enabled?
> >> 		io10 |= ADV748X_IO_10_CSI4_EN;
> >>
> >>> +		else
> >>> +			io10 |= ADV748X_IO_10_CSI4_EN |
> >>> +				ADV748X_IO_10_CSI1_EN;
> >>> +	} else {
> >>> +		/* Clear AFE->TXA routing and power up TXA. */
> >>> +		io10 &= ~ADV748X_IO_10_CSI4_IN_SEL_AFE;
> >>> +		io10 |= ADV748X_IO_10_CSI4_EN;
> >>
> >> But if we assume it's already enabled ... do we need this?
> >> Perhaps it might be better to be explicit on this?
> >>
> >>> +	}
> >>> +	io_write(state, ADV748X_IO_10, io10);
> >>
> >> Would it be any cleaner to use io_clrset() here?
> >>
> >> Hrm ... also it feels like this register really should be set depending
> >> upon the complete state of ... &state->...
> >>
> >> So perhaps it deserves it's own function which should be called after
> >> csi_registered() callback and any link change.
> >>
> >> /me has a quick go at some psuedo codeishness...:
> >>
> >> int adv74x_io_10(struct adv748x_state *state);
> >> 	u8 bits = 0;
> >> 	u8 mask = ADV748X_IO_10_CSI1_EN
> >>
> >> 		| ADV748X_IO_10_CSI4_EN
> >> 		| ADV748X_IO_10_CSI4_IN_SEL_AFE;
> >>
> >> 	if (state->afe.tx) {
> >> 		/* AFE Requires TXA enabled, even when output to TXB */
> >> 		bits |= ADV748X_IO_10_CSI4_EN;
> >>
> >> 		if (is_txa(state->afe.tx))
> >> 			bits |= ADV748X_IO_10_CSI4_IN_SEL_AFE
> >> 		else
> >> 			bits |= ADV748X_IO_10_CSI1_EN;
> >> 	}
> >>
> >> 	if (state->hdmi.tx) {
> >> 		bits |= ADV748X_IO_10_CSI4_EN;
> >> 	}
> >>
> >> 	return io_clrset(state, ADV748X_IO_10, mask, bits);
> >> }
> >>
> >> How does that look ? (is it even correct first?)
> >>
> >>> +
> >>> +	return 0;
> >>> +}
> >>> +
> >>> +static const struct media_entity_operations adv748x_tx_media_ops = {
> >>> +	.link_setup	= adv748x_link_setup,
> >>> +	.link_validate	= v4l2_subdev_link_validate,
> >>> +};
> >>>
> >>>  static const struct media_entity_operations adv748x_media_ops = {
> >>>  	.link_validate = v4l2_subdev_link_validate,
> >>> @@ -516,7 +570,8 @@ void adv748x_subdev_init(struct v4l2_subdev *sd,
> >>> struct adv748x_state *state,
> >>>  		state->client->addr, ident);
> >>>
> >>>  	sd->entity.function = function;
> >>> -	sd->entity.ops = &adv748x_media_ops;
> >>> +	sd->entity.ops = is_tx(adv748x_sd_to_csi2(sd)) ?
> >>> +			 &adv748x_tx_media_ops : &adv748x_media_ops;
> >>
> >> Aha - yes that's a neat solution to ensure that only the TX links
> >> generate link_setup calls :)
> >
> > Another option would be to bail out from adv748x_link_setup() if the entity is
> > not a TX*.
> >
>
> I suggested this in v1 - but Jacopo objected with the following:
>
> > Checking for is_txa() and is_txb() would require to call
> > 'adv_sd_to_csi2(sd)' before having made sure the 'sd' actually
> > represent a csi2_tx. I would keep it as it is.
>

That was at the time where the .link_setup() callback was called for
TXs and non-TXs. What you proposed was to call:

#define adv748x_sd_to_csi2(sd) container_of(sd, struct adv748x_csi2, sd)

on variables that we don't have any guarantee that are of type 'struct
adv748x_csi2'. I still think it is dangerous and should be avoided and
I worked it around in v1 as:

+	if ((sd != &state->txa.sd && sd != &state->txb.sd) ||

> Now I look at the implementation here, I see this is precisely what it
> is doing anyway .... still converting through adv748x_sd_to_csi2(sd) on
> an unknown pointer type
>  (which I still believe is a valid thing to do in this instance)

It's not unknown, .link_setup() is only registered for TXs. If it gets
called, we know we're dealing with a TX.

>
> So yes, I think this would be simpler having the check at the top of the
> adv748x_link_setup() call, and thus then there is no need to add a
> second adv_media_ops structure.

That was what I did in v1, didn't I ?

The current implementation looks better imho, but if the both of you
prefer something similar to v1 I will consider that.

Thanks
   j
>
>
> >>>  }
> >
> > [snip]
> >
>
> --
> Regards
> --
> Kieran

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2019-01-10  8:58 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-06 15:54 [PATCH v2 0/6] media: adv748x: Implement dynamic routing support Jacopo Mondi
2019-01-06 15:54 ` [PATCH v2 1/6] media: adv748x: Add is_txb() Jacopo Mondi
2019-01-07  9:49   ` Kieran Bingham
2019-01-07 10:05     ` Jacopo Mondi
2019-01-07 10:38       ` Kieran Bingham
2019-01-09  0:04         ` Laurent Pinchart
2019-01-06 15:54 ` [PATCH v2 2/6] media: adv748x: Rename reset procedures Jacopo Mondi
2019-01-07  9:59   ` Kieran Bingham
2019-01-06 15:54 ` [PATCH v2 3/6] media: adv748x: csi2: Link AFE with TXA and TXB Jacopo Mondi
2019-01-07 10:35   ` Kieran Bingham
2019-01-09  0:11   ` Laurent Pinchart
2019-01-06 15:54 ` [PATCH v2 4/6] media: adv748x: Store the source subdevice in TX Jacopo Mondi
2019-01-07 10:41   ` Kieran Bingham
2019-01-06 15:54 ` [PATCH v2 5/6] media: adv748x: Store the TX sink in HDMI/AFE Jacopo Mondi
2019-01-07 10:45   ` Kieran Bingham
2019-01-06 15:54 ` [PATCH v2 6/6] media: adv748x: Implement TX link_setup callback Jacopo Mondi
2019-01-07 12:36   ` Kieran Bingham
2019-01-09  0:15     ` Laurent Pinchart
2019-01-09 14:15       ` Kieran Bingham
2019-01-10  8:58         ` Jacopo Mondi [this message]
2019-01-10 10:05           ` Kieran Bingham
2019-01-10  8:51       ` Jacopo Mondi
2019-01-10  9:27         ` Laurent Pinchart
2019-01-09 14:17     ` Kieran Bingham
2019-01-10 10:01     ` Jacopo Mondi
2019-01-10 13:40     ` Jacopo Mondi

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=20190110085843.cju2gjrr4vm3acby@uno.localdomain \
    --to=jacopo@jmondi.org \
    --cc=jacopo+renesas@jmondi.org \
    --cc=kieran.bingham@ideasonboard.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=niklas.soderlund+renesas@ragnatech.se \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.