diff mbox series

[1/3] i2c: adv748x: store number of CSI-2 lanes described in device tree

Message ID 20180918014509.6394-2-niklas.soderlund+renesas@ragnatech.se (mailing list archive)
State Not Applicable
Delegated to: Geert Uytterhoeven
Headers show
Series i2c: adv748x: add support for CSI-2 TXA to work in 1-, 2- and 4-lane mode | expand

Commit Message

Niklas Söderlund Sept. 18, 2018, 1:45 a.m. UTC
The adv748x CSI-2 transmitters TXA and TXB can use different number of
lines to transmit data on. In order to be able configure the device
correctly this information need to be parsed from device tree and stored
in each TX private data structure.

TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/i2c/adv748x/adv748x-core.c | 49 ++++++++++++++++++++++++
 drivers/media/i2c/adv748x/adv748x.h      |  1 +
 2 files changed, 50 insertions(+)

Comments

Laurent Pinchart Sept. 18, 2018, 10:16 a.m. UTC | #1
Hi Niklas,

Thank you for the patch.

On Tuesday, 18 September 2018 04:45:07 EEST Niklas Söderlund wrote:
> The adv748x CSI-2 transmitters TXA and TXB can use different number of
> lines to transmit data on. In order to be able configure the device

s/lines/lanes/
s/data on/data/
s/able configure/able to configure/

> correctly this information need to be parsed from device tree and stored
> in each TX private data structure.
> 
> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  drivers/media/i2c/adv748x/adv748x-core.c | 49 ++++++++++++++++++++++++
>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
> b/drivers/media/i2c/adv748x/adv748x-core.c index
> 85c027bdcd56748d..a93f8ea89a228474 100644
> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> @@ -23,6 +23,7 @@
>  #include <media/v4l2-ctrls.h>
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-dv-timings.h>
> +#include <media/v4l2-fwnode.h>
>  #include <media/v4l2-ioctl.h>
> 
>  #include "adv748x.h"
> @@ -561,11 +562,54 @@ void adv748x_subdev_init(struct v4l2_subdev *sd,
> struct adv748x_state *state, sd->entity.ops = &adv748x_media_ops;
>  }
> 
> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
> +				    unsigned int port,
> +				    struct device_node *ep)
> +{
> +	struct v4l2_fwnode_endpoint vep;
> +	unsigned int num_lanes;
> +	int ret;
> +
> +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
> +		return 0;
> +
> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
> +	if (ret)
> +		return ret;
> +
> +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> +
> +	if (vep.base.port == ADV748X_PORT_TXA) {
> +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
> +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",

%u for unsigned int (and below as well).

> +				num_lanes);
> +			return -EINVAL;
> +		}
> +
> +		state->txa.num_lanes = num_lanes;
> +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);

I wonder if the debug message is really needed.

Apart from that,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +	}
> +
> +	if (vep.base.port == ADV748X_PORT_TXB) {
> +		if (num_lanes != 1) {
> +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
> +				num_lanes);
> +			return -EINVAL;
> +		}
> +
> +		state->txb.num_lanes = num_lanes;
> +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
> +	}
> +
> +	return 0;
> +}
> +
>  static int adv748x_parse_dt(struct adv748x_state *state)
>  {
>  	struct device_node *ep_np = NULL;
>  	struct of_endpoint ep;
>  	bool found = false;
> +	int ret;
> 
>  	for_each_endpoint_of_node(state->dev->of_node, ep_np) {
>  		of_graph_parse_endpoint(ep_np, &ep);
> @@ -589,6 +633,11 @@ static int adv748x_parse_dt(struct adv748x_state
> *state) state->endpoints[ep.port] = ep_np;
> 
>  		found = true;
> +
> +		/* Store number of CSI-2 lanes used for TXA and TXB. */
> +		ret = adv748x_parse_csi2_lanes(state, ep.port, ep_np);
> +		if (ret)
> +			return ret;
>  	}
> 
>  	return found ? 0 : -ENODEV;
> diff --git a/drivers/media/i2c/adv748x/adv748x.h
> b/drivers/media/i2c/adv748x/adv748x.h index
> c9016acaba34aff2..88ad06a3045c5427 100644
> --- a/drivers/media/i2c/adv748x/adv748x.h
> +++ b/drivers/media/i2c/adv748x/adv748x.h
> @@ -78,6 +78,7 @@ struct adv748x_csi2 {
>  	struct adv748x_state *state;
>  	struct v4l2_mbus_framefmt format;
>  	unsigned int page;
> +	unsigned int num_lanes;
> 
>  	struct media_pad pads[ADV748X_CSI2_NR_PADS];
>  	struct v4l2_ctrl_handler ctrl_hdl;
Kieran Bingham Sept. 18, 2018, 10:19 a.m. UTC | #2
Hi Niklas,

Thank you for the patch,

On 18/09/18 02:45, Niklas Söderlund wrote:
> The adv748x CSI-2 transmitters TXA and TXB can use different number of
> lines to transmit data on. In order to be able configure the device
> correctly this information need to be parsed from device tree and stored
> in each TX private data structure.
> 
> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> 

Am I right in assuming that it is the CSI device which specifies the
number of lanes in their DT?

Could we make this clear in the commit log (and possibly an extra
comment in the code). At first I was assuming we would have to declare
the number of lanes in the ADV748x TX DT node, but I don't think that's
the case.

> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  drivers/media/i2c/adv748x/adv748x-core.c | 49 ++++++++++++++++++++++++
>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
> index 85c027bdcd56748d..a93f8ea89a228474 100644
> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> @@ -23,6 +23,7 @@
>  #include <media/v4l2-ctrls.h>
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-dv-timings.h>
> +#include <media/v4l2-fwnode.h>
>  #include <media/v4l2-ioctl.h>
>  
>  #include "adv748x.h"
> @@ -561,11 +562,54 @@ void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state,
>  	sd->entity.ops = &adv748x_media_ops;
>  }
>  
> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
> +				    unsigned int port,
> +				    struct device_node *ep)
> +{
> +	struct v4l2_fwnode_endpoint vep;
> +	unsigned int num_lanes;
> +	int ret;
> +
> +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
> +		return 0;
> +
> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
> +	if (ret)
> +		return ret;
> +
> +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> +

If I'm not mistaken we are parsing /someone elses/ DT node here (the CSI
receiver or such).

Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
defined?

Do we need to fall back to some safe defaults at all (1 lane?) ?
Actually - perhaps there is no safe default. I guess if the lanes aren't
configured correctly we're not going to get a good signal at the other end.

> +	if (vep.base.port == ADV748X_PORT_TXA) {
> +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
> +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
> +				num_lanes);
> +			return -EINVAL;
> +		}
> +
> +		state->txa.num_lanes = num_lanes;
> +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
> +	}
> +
> +	if (vep.base.port == ADV748X_PORT_TXB) {
> +		if (num_lanes != 1) {
> +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
> +				num_lanes);
> +			return -EINVAL;
> +		}
> +
> +		state->txb.num_lanes = num_lanes;
> +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
> +	}
> +
> +	return 0;
> +}
> +
>  static int adv748x_parse_dt(struct adv748x_state *state)
>  {
>  	struct device_node *ep_np = NULL;
>  	struct of_endpoint ep;
>  	bool found = false;
> +	int ret;
>  
>  	for_each_endpoint_of_node(state->dev->of_node, ep_np) {
>  		of_graph_parse_endpoint(ep_np, &ep);
> @@ -589,6 +633,11 @@ static int adv748x_parse_dt(struct adv748x_state *state)
>  		state->endpoints[ep.port] = ep_np;
>  
>  		found = true;
> +
> +		/* Store number of CSI-2 lanes used for TXA and TXB. */
> +		ret = adv748x_parse_csi2_lanes(state, ep.port, ep_np);
> +		if (ret)
> +			return ret;
>  	}
>  
>  	return found ? 0 : -ENODEV;
> diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
> index c9016acaba34aff2..88ad06a3045c5427 100644
> --- a/drivers/media/i2c/adv748x/adv748x.h
> +++ b/drivers/media/i2c/adv748x/adv748x.h
> @@ -78,6 +78,7 @@ struct adv748x_csi2 {
>  	struct adv748x_state *state;
>  	struct v4l2_mbus_framefmt format;
>  	unsigned int page;
> +	unsigned int num_lanes;
>  
>  	struct media_pad pads[ADV748X_CSI2_NR_PADS];
>  	struct v4l2_ctrl_handler ctrl_hdl;
>
Laurent Pinchart Sept. 18, 2018, 10:28 a.m. UTC | #3
Hi Kieran,

On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
> On 18/09/18 02:45, Niklas Söderlund wrote:
> > The adv748x CSI-2 transmitters TXA and TXB can use different number of
> > lines to transmit data on. In order to be able configure the device
> > correctly this information need to be parsed from device tree and stored
> > in each TX private data structure.
> > 
> > TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> 
> Am I right in assuming that it is the CSI device which specifies the
> number of lanes in their DT?

Do you mean the CSI-2 receiver ? Both the receiver and the transmitter should 
specify the data lanes in their DT node.

> Could we make this clear in the commit log (and possibly an extra
> comment in the code). At first I was assuming we would have to declare
> the number of lanes in the ADV748x TX DT node, but I don't think that's
> the case.
> 
> > Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> > ---
> > 
> >  drivers/media/i2c/adv748x/adv748x-core.c | 49 ++++++++++++++++++++++++
> >  drivers/media/i2c/adv748x/adv748x.h      |  1 +
> >  2 files changed, 50 insertions(+)
> > 
> > diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
> > b/drivers/media/i2c/adv748x/adv748x-core.c index
> > 85c027bdcd56748d..a93f8ea89a228474 100644
> > --- a/drivers/media/i2c/adv748x/adv748x-core.c
> > +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> > @@ -23,6 +23,7 @@
 >  #include <media/v4l2-ctrls.h>
> >  #include <media/v4l2-device.h>
> >  #include <media/v4l2-dv-timings.h>
> > +#include <media/v4l2-fwnode.h>
> >  #include <media/v4l2-ioctl.h>
> >  
> >  #include "adv748x.h"
> > @@ -561,11 +562,54 @@ void adv748x_subdev_init(struct v4l2_subdev *sd,
> > struct adv748x_state *state,
> >  	sd->entity.ops = &adv748x_media_ops;
> >  }
> > 
> > +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
> > +				    unsigned int port,
> > +				    struct device_node *ep)
> > +{
> > +	struct v4l2_fwnode_endpoint vep;
> > +	unsigned int num_lanes;
> > +	int ret;
> > +
> > +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
> > +		return 0;
> > +
> > +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
> > +	if (ret)
> > +		return ret;
> > +
> > +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> > +
> 
> If I'm not mistaken we are parsing /someone elses/ DT node here (the CSI
> receiver or such).

Aren't we parsing our own endpoint ? The ep argument comes from ep_np in 
adv748x_parse_dt(), and that's the endpoint iterator used with

	for_each_endpoint_of_node(state->dev->of_node, ep_np)

> Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
> defined?
> 
> Do we need to fall back to some safe defaults at all (1 lane?) ?
> Actually - perhaps there is no safe default. I guess if the lanes aren't
> configured correctly we're not going to get a good signal at the other end.

The endpoints should contain a data-lanes property. That's the case in the 
mainline DT sources, but it's not explicitly stated as a mandatory property. I 
think we should update the bindings.

> > +	if (vep.base.port == ADV748X_PORT_TXA) {
> > +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
> > +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
> > +				num_lanes);
> > +			return -EINVAL;
> > +		}
> > +
> > +		state->txa.num_lanes = num_lanes;
> > +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
> > +	}
> > +
> > +	if (vep.base.port == ADV748X_PORT_TXB) {
> > +		if (num_lanes != 1) {
> > +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
> > +				num_lanes);
> > +			return -EINVAL;
> > +		}
> > +
> > +		state->txb.num_lanes = num_lanes;
> > +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static int adv748x_parse_dt(struct adv748x_state *state)
> >  {
> >  	struct device_node *ep_np = NULL;
> >  	struct of_endpoint ep;
> >  	bool found = false;
> > +	int ret;
> > 
> >  	for_each_endpoint_of_node(state->dev->of_node, ep_np) {
> >  		of_graph_parse_endpoint(ep_np, &ep);
> > @@ -589,6 +633,11 @@ static int adv748x_parse_dt(struct adv748x_state
> > *state)
> >  		state->endpoints[ep.port] = ep_np;
> >  		
> >  		found = true;
> > +
> > +		/* Store number of CSI-2 lanes used for TXA and TXB. */
> > +		ret = adv748x_parse_csi2_lanes(state, ep.port, ep_np);
> > +		if (ret)
> > +			return ret;
> >  	}
> >  	
> >  	return found ? 0 : -ENODEV;
> > diff --git a/drivers/media/i2c/adv748x/adv748x.h
> > b/drivers/media/i2c/adv748x/adv748x.h index
> > c9016acaba34aff2..88ad06a3045c5427 100644
> > --- a/drivers/media/i2c/adv748x/adv748x.h
> > +++ b/drivers/media/i2c/adv748x/adv748x.h
> > @@ -78,6 +78,7 @@ struct adv748x_csi2 {
> >  	struct adv748x_state *state;
> >  	struct v4l2_mbus_framefmt format;
> >  	unsigned int page;
> > +	unsigned int num_lanes;
> > 
> >  	struct media_pad pads[ADV748X_CSI2_NR_PADS];
> >  	struct v4l2_ctrl_handler ctrl_hdl;
Kieran Bingham Sept. 18, 2018, 10:37 a.m. UTC | #4
Hi Laurent, Niklas,

On 18/09/18 11:28, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
>> On 18/09/18 02:45, Niklas Söderlund wrote:
>>> The adv748x CSI-2 transmitters TXA and TXB can use different number of
>>> lines to transmit data on. In order to be able configure the device
>>> correctly this information need to be parsed from device tree and stored
>>> in each TX private data structure.
>>>
>>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
>>
>> Am I right in assuming that it is the CSI device which specifies the
>> number of lanes in their DT?
> 
> Do you mean the CSI-2 receiver ? Both the receiver and the transmitter should 
> specify the data lanes in their DT node.

Yes, I should have said CSI-2 receiver.

Aha - so *both* sides of the link have to specify the lanes and
presumably match with each other?

> 
>> Could we make this clear in the commit log (and possibly an extra
>> comment in the code). At first I was assuming we would have to declare
>> the number of lanes in the ADV748x TX DT node, but I don't think that's
>> the case.
>>
>>> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
>>> ---
>>>
>>>  drivers/media/i2c/adv748x/adv748x-core.c | 49 ++++++++++++++++++++++++
>>>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
>>>  2 files changed, 50 insertions(+)
>>>
>>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
>>> b/drivers/media/i2c/adv748x/adv748x-core.c index
>>> 85c027bdcd56748d..a93f8ea89a228474 100644
>>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
>>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
>>> @@ -23,6 +23,7 @@
>  >  #include <media/v4l2-ctrls.h>
>>>  #include <media/v4l2-device.h>
>>>  #include <media/v4l2-dv-timings.h>
>>> +#include <media/v4l2-fwnode.h>
>>>  #include <media/v4l2-ioctl.h>
>>>  
>>>  #include "adv748x.h"
>>> @@ -561,11 +562,54 @@ void adv748x_subdev_init(struct v4l2_subdev *sd,
>>> struct adv748x_state *state,
>>>  	sd->entity.ops = &adv748x_media_ops;
>>>  }
>>>
>>> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
>>> +				    unsigned int port,
>>> +				    struct device_node *ep)
>>> +{
>>> +	struct v4l2_fwnode_endpoint vep;
>>> +	unsigned int num_lanes;
>>> +	int ret;
>>> +
>>> +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
>>> +		return 0;
>>> +
>>> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
>>> +
>>
>> If I'm not mistaken we are parsing /someone elses/ DT node here (the CSI
>> receiver or such).
> 
> Aren't we parsing our own endpoint ? The ep argument comes from ep_np in 
> adv748x_parse_dt(), and that's the endpoint iterator used with
> 
> 	for_each_endpoint_of_node(state->dev->of_node, ep_np)

Bah - my head was polluted with the async subdevice stuff where we were
getting the endpoint of the other device, but of course that's
completely unrelated here.


> 
>> Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
>> defined?
>>
>> Do we need to fall back to some safe defaults at all (1 lane?) ?
>> Actually - perhaps there is no safe default. I guess if the lanes aren't
>> configured correctly we're not going to get a good signal at the other end.
> 
> The endpoints should contain a data-lanes property. That's the case in the 
> mainline DT sources, but it's not explicitly stated as a mandatory property. I 
> think we should update the bindings.

Yes, - as this code change is making the property mandatory - we should
certainly state that in the bindings, unless we can fall back to a
sensible default (perhaps the max supported on that component?)


> 
>>> +	if (vep.base.port == ADV748X_PORT_TXA) {
>>> +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
>>> +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
>>> +				num_lanes);
>>> +			return -EINVAL;
>>> +		}
>>> +
>>> +		state->txa.num_lanes = num_lanes;
>>> +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
>>> +	}
>>> +
>>> +	if (vep.base.port == ADV748X_PORT_TXB) {
>>> +		if (num_lanes != 1) {
>>> +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
>>> +				num_lanes);
>>> +			return -EINVAL;
>>> +		}
>>> +
>>> +		state->txb.num_lanes = num_lanes;
>>> +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>  static int adv748x_parse_dt(struct adv748x_state *state)
>>>  {
>>>  	struct device_node *ep_np = NULL;
>>>  	struct of_endpoint ep;
>>>  	bool found = false;
>>> +	int ret;
>>>
>>>  	for_each_endpoint_of_node(state->dev->of_node, ep_np) {
>>>  		of_graph_parse_endpoint(ep_np, &ep);
>>> @@ -589,6 +633,11 @@ static int adv748x_parse_dt(struct adv748x_state
>>> *state)
>>>  		state->endpoints[ep.port] = ep_np;
>>>  		
>>>  		found = true;
>>> +
>>> +		/* Store number of CSI-2 lanes used for TXA and TXB. */

Potentially : s/Store/Identify the/ ?

>>> +		ret = adv748x_parse_csi2_lanes(state, ep.port, ep_np);
>>> +		if (ret)
>>> +			return ret;
>>>  	}
>>>  	
>>>  	return found ? 0 : -ENODEV;
>>> diff --git a/drivers/media/i2c/adv748x/adv748x.h
>>> b/drivers/media/i2c/adv748x/adv748x.h index
>>> c9016acaba34aff2..88ad06a3045c5427 100644
>>> --- a/drivers/media/i2c/adv748x/adv748x.h
>>> +++ b/drivers/media/i2c/adv748x/adv748x.h
>>> @@ -78,6 +78,7 @@ struct adv748x_csi2 {
>>>  	struct adv748x_state *state;
>>>  	struct v4l2_mbus_framefmt format;
>>>  	unsigned int page;
>>> +	unsigned int num_lanes;
>>>
>>>  	struct media_pad pads[ADV748X_CSI2_NR_PADS];
>>>  	struct v4l2_ctrl_handler ctrl_hdl;
>
Laurent Pinchart Sept. 18, 2018, 10:46 a.m. UTC | #5
Hi Kieran,

On Tuesday, 18 September 2018 13:37:55 EEST Kieran Bingham wrote:
> On 18/09/18 11:28, Laurent Pinchart wrote:
> > On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
> >> On 18/09/18 02:45, Niklas Söderlund wrote:
> >>> The adv748x CSI-2 transmitters TXA and TXB can use different number of
> >>> lines to transmit data on. In order to be able configure the device
> >>> correctly this information need to be parsed from device tree and stored
> >>> in each TX private data structure.
> >>> 
> >>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> >> 
> >> Am I right in assuming that it is the CSI device which specifies the
> >> number of lanes in their DT?
> > 
> > Do you mean the CSI-2 receiver ? Both the receiver and the transmitter
> > should specify the data lanes in their DT node.
> 
> Yes, I should have said CSI-2 receiver.
> 
> Aha - so *both* sides of the link have to specify the lanes and
> presumably match with each other?

Yes, they should certainly match :-)

> >> Could we make this clear in the commit log (and possibly an extra
> >> comment in the code). At first I was assuming we would have to declare
> >> the number of lanes in the ADV748x TX DT node, but I don't think that's
> >> the case.
> >> 
> >>> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> >>> ---
> >>> 
> >>>  drivers/media/i2c/adv748x/adv748x-core.c | 49 ++++++++++++++++++++++++
> >>>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
> >>>  2 files changed, 50 insertions(+)
> >>> 
> >>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
> >>> b/drivers/media/i2c/adv748x/adv748x-core.c index
> >>> 85c027bdcd56748d..a93f8ea89a228474 100644
> >>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> >>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c

[snip]

> >>> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
> >>> +				    unsigned int port,
> >>> +				    struct device_node *ep)
> >>> +{
> >>> +	struct v4l2_fwnode_endpoint vep;
> >>> +	unsigned int num_lanes;
> >>> +	int ret;
> >>> +
> >>> +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
> >>> +		return 0;
> >>> +
> >>> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
> >>> +	if (ret)
> >>> +		return ret;
> >>> +
> >>> +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> >>> +
> >> 
> >> If I'm not mistaken we are parsing /someone elses/ DT node here (the CSI
> >> receiver or such).
> > 
> > Aren't we parsing our own endpoint ? The ep argument comes from ep_np in
> > adv748x_parse_dt(), and that's the endpoint iterator used with
> > 
> > 	for_each_endpoint_of_node(state->dev->of_node, ep_np)
> 
> Bah - my head was polluted with the async subdevice stuff where we were
> getting the endpoint of the other device, but of course that's
> completely unrelated here.
> 
> >> Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
> >> defined?
> >> 
> >> Do we need to fall back to some safe defaults at all (1 lane?) ?
> >> Actually - perhaps there is no safe default. I guess if the lanes aren't
> >> configured correctly we're not going to get a good signal at the other
> >> end.
> > 
> > The endpoints should contain a data-lanes property. That's the case in the
> > mainline DT sources, but it's not explicitly stated as a mandatory
> > property. I think we should update the bindings.
> 
> Yes, - as this code change is making the property mandatory - we should
> certainly state that in the bindings, unless we can fall back to a
> sensible default (perhaps the max supported on that component?)

I'm not sure there's a sensible default, I'd rather specify it explicitly. 
Note that the data-lanes property doesn't just specify the number of lanes, 
but also how they are remapped, when that feature is supported by the CSI-2 
transmitter or receiver.

> >>> +	if (vep.base.port == ADV748X_PORT_TXA) {
> >>> +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
> >>> +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
> >>> +				num_lanes);
> >>> +			return -EINVAL;
> >>> +		}
> >>> +
> >>> +		state->txa.num_lanes = num_lanes;
> >>> +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
> >>> +	}
> >>> +
> >>> +	if (vep.base.port == ADV748X_PORT_TXB) {
> >>> +		if (num_lanes != 1) {
> >>> +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
> >>> +				num_lanes);
> >>> +			return -EINVAL;
> >>> +		}
> >>> +
> >>> +		state->txb.num_lanes = num_lanes;
> >>> +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
> >>> +	}
> >>> +
> >>> +	return 0;
> >>> +}

[snip]
Kieran Bingham Sept. 18, 2018, 10:51 a.m. UTC | #6
Hi Laurent,

On 18/09/18 11:46, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Tuesday, 18 September 2018 13:37:55 EEST Kieran Bingham wrote:
>> On 18/09/18 11:28, Laurent Pinchart wrote:
>>> On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
>>>> On 18/09/18 02:45, Niklas Söderlund wrote:
>>>>> The adv748x CSI-2 transmitters TXA and TXB can use different number of
>>>>> lines to transmit data on. In order to be able configure the device
>>>>> correctly this information need to be parsed from device tree and stored
>>>>> in each TX private data structure.
>>>>>
>>>>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
>>>>
>>>> Am I right in assuming that it is the CSI device which specifies the
>>>> number of lanes in their DT?
>>>
>>> Do you mean the CSI-2 receiver ? Both the receiver and the transmitter
>>> should specify the data lanes in their DT node.
>>
>> Yes, I should have said CSI-2 receiver.
>>
>> Aha - so *both* sides of the link have to specify the lanes and
>> presumably match with each other?
> 
> Yes, they should certainly match :-)

I assumed so :) - do we need to validate that at a framework level?
(or perhaps it already is, all I've only looked at this morning is
e-mails :D )

> 
>>>> Could we make this clear in the commit log (and possibly an extra
>>>> comment in the code). At first I was assuming we would have to declare
>>>> the number of lanes in the ADV748x TX DT node, but I don't think that's
>>>> the case.
>>>>
>>>>> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
>>>>> ---
>>>>>
>>>>>  drivers/media/i2c/adv748x/adv748x-core.c | 49 ++++++++++++++++++++++++
>>>>>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
>>>>>  2 files changed, 50 insertions(+)
>>>>>
>>>>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
>>>>> b/drivers/media/i2c/adv748x/adv748x-core.c index
>>>>> 85c027bdcd56748d..a93f8ea89a228474 100644
>>>>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
>>>>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> 
> [snip]
> 
>>>>> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
>>>>> +				    unsigned int port,
>>>>> +				    struct device_node *ep)
>>>>> +{
>>>>> +	struct v4l2_fwnode_endpoint vep;
>>>>> +	unsigned int num_lanes;
>>>>> +	int ret;
>>>>> +
>>>>> +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
>>>>> +		return 0;
>>>>> +
>>>>> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
>>>>> +	if (ret)
>>>>> +		return ret;
>>>>> +
>>>>> +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
>>>>> +
>>>>
>>>> If I'm not mistaken we are parsing /someone elses/ DT node here (the CSI
>>>> receiver or such).
>>>
>>> Aren't we parsing our own endpoint ? The ep argument comes from ep_np in
>>> adv748x_parse_dt(), and that's the endpoint iterator used with
>>>
>>> 	for_each_endpoint_of_node(state->dev->of_node, ep_np)
>>
>> Bah - my head was polluted with the async subdevice stuff where we were
>> getting the endpoint of the other device, but of course that's
>> completely unrelated here.
>>
>>>> Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
>>>> defined?
>>>>
>>>> Do we need to fall back to some safe defaults at all (1 lane?) ?
>>>> Actually - perhaps there is no safe default. I guess if the lanes aren't
>>>> configured correctly we're not going to get a good signal at the other
>>>> end.
>>>
>>> The endpoints should contain a data-lanes property. That's the case in the
>>> mainline DT sources, but it's not explicitly stated as a mandatory
>>> property. I think we should update the bindings.
>>
>> Yes, - as this code change is making the property mandatory - we should
>> certainly state that in the bindings, unless we can fall back to a
>> sensible default (perhaps the max supported on that component?)
> 
> I'm not sure there's a sensible default, I'd rather specify it explicitly. 
> Note that the data-lanes property doesn't just specify the number of lanes, 
> but also how they are remapped, when that feature is supported by the CSI-2 
> transmitter or receiver.


Ok understood. As I feared - we can't really default - because it has to
match and be defined.

So making the DT property mandatory really is the way to go then.



>>>>> +	if (vep.base.port == ADV748X_PORT_TXA) {
>>>>> +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
>>>>> +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
>>>>> +				num_lanes);
>>>>> +			return -EINVAL;
>>>>> +		}
>>>>> +
>>>>> +		state->txa.num_lanes = num_lanes;
>>>>> +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
>>>>> +	}
>>>>> +
>>>>> +	if (vep.base.port == ADV748X_PORT_TXB) {
>>>>> +		if (num_lanes != 1) {
>>>>> +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
>>>>> +				num_lanes);
>>>>> +			return -EINVAL;
>>>>> +		}
>>>>> +
>>>>> +		state->txb.num_lanes = num_lanes;
>>>>> +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
>>>>> +	}
>>>>> +
>>>>> +	return 0;
>>>>> +}
> 
> [snip]
>
Laurent Pinchart Sept. 18, 2018, 11:13 a.m. UTC | #7
Hi Kieran,

On Tuesday, 18 September 2018 13:51:34 EEST Kieran Bingham wrote:
> On 18/09/18 11:46, Laurent Pinchart wrote:
> > On Tuesday, 18 September 2018 13:37:55 EEST Kieran Bingham wrote:
> >> On 18/09/18 11:28, Laurent Pinchart wrote:
> >>> On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
> >>>> On 18/09/18 02:45, Niklas Söderlund wrote:
> >>>>> The adv748x CSI-2 transmitters TXA and TXB can use different number of
> >>>>> lines to transmit data on. In order to be able configure the device
> >>>>> correctly this information need to be parsed from device tree and
> >>>>> stored in each TX private data structure.
> >>>>> 
> >>>>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> >>>> 
> >>>> Am I right in assuming that it is the CSI device which specifies the
> >>>> number of lanes in their DT?
> >>> 
> >>> Do you mean the CSI-2 receiver ? Both the receiver and the transmitter
> >>> should specify the data lanes in their DT node.
> >> 
> >> Yes, I should have said CSI-2 receiver.
> >> 
> >> Aha - so *both* sides of the link have to specify the lanes and
> >> presumably match with each other?
> > 
> > Yes, they should certainly match :-)
> 
> I assumed so :) - do we need to validate that at a framework level?
> (or perhaps it already is, all I've only looked at this morning is
> e-mails :D )

It's not done yet as far as I know. CC'ing Sakari who may have a comment 
regarding whether this should be added.

> >>>> Could we make this clear in the commit log (and possibly an extra
> >>>> comment in the code). At first I was assuming we would have to declare
> >>>> the number of lanes in the ADV748x TX DT node, but I don't think that's
> >>>> the case.
> >>>> 
> >>>>> Signed-off-by: Niklas Söderlund
> >>>>> <niklas.soderlund+renesas@ragnatech.se>
> >>>>> ---
> >>>>> 
> >>>>>  drivers/media/i2c/adv748x/adv748x-core.c | 49 +++++++++++++++++++++++
> >>>>>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
> >>>>>  2 files changed, 50 insertions(+)
> >>>>> 
> >>>>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
> >>>>> b/drivers/media/i2c/adv748x/adv748x-core.c index
> >>>>> 85c027bdcd56748d..a93f8ea89a228474 100644
> >>>>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> >>>>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> > 
> > [snip]
> > 
> >>>>> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
> >>>>> +				    unsigned int port,
> >>>>> +				    struct device_node *ep)
> >>>>> +{
> >>>>> +	struct v4l2_fwnode_endpoint vep;
> >>>>> +	unsigned int num_lanes;
> >>>>> +	int ret;
> >>>>> +
> >>>>> +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
> >>>>> +		return 0;
> >>>>> +
> >>>>> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
> >>>>> +	if (ret)
> >>>>> +		return ret;
> >>>>> +
> >>>>> +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> >>>>> +
> >>>> 
> >>>> If I'm not mistaken we are parsing /someone elses/ DT node here (the
> >>>> CSI receiver or such).
> >>> 
> >>> Aren't we parsing our own endpoint ? The ep argument comes from ep_np in
> >>> adv748x_parse_dt(), and that's the endpoint iterator used with
> >>> 
> >>> 	for_each_endpoint_of_node(state->dev->of_node, ep_np)
> >> 
> >> Bah - my head was polluted with the async subdevice stuff where we were
> >> getting the endpoint of the other device, but of course that's
> >> completely unrelated here.
> >> 
> >>>> Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
> >>>> defined?
> >>>> 
> >>>> Do we need to fall back to some safe defaults at all (1 lane?) ?
> >>>> Actually - perhaps there is no safe default. I guess if the lanes
> >>>> aren't configured correctly we're not going to get a good signal at the
> >>>> other end.
> >>> 
> >>> The endpoints should contain a data-lanes property. That's the case in
> >>> the mainline DT sources, but it's not explicitly stated as a mandatory
> >>> property. I think we should update the bindings.
> >> 
> >> Yes, - as this code change is making the property mandatory - we should
> >> certainly state that in the bindings, unless we can fall back to a
> >> sensible default (perhaps the max supported on that component?)
> > 
> > I'm not sure there's a sensible default, I'd rather specify it explicitly.
> > Note that the data-lanes property doesn't just specify the number of
> > lanes, but also how they are remapped, when that feature is supported by
> > the CSI-2 transmitter or receiver.
> 
> Ok understood. As I feared - we can't really default - because it has to
> match and be defined.
> 
> So making the DT property mandatory really is the way to go then.
> 
> >>>>> +	if (vep.base.port == ADV748X_PORT_TXA) {
> >>>>> +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
> >>>>> +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
> >>>>> +				num_lanes);
> >>>>> +			return -EINVAL;
> >>>>> +		}
> >>>>> +
> >>>>> +		state->txa.num_lanes = num_lanes;
> >>>>> +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
> >>>>> +	}
> >>>>> +
> >>>>> +	if (vep.base.port == ADV748X_PORT_TXB) {
> >>>>> +		if (num_lanes != 1) {
> >>>>> +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
> >>>>> +				num_lanes);
> >>>>> +			return -EINVAL;
> >>>>> +		}
> >>>>> +
> >>>>> +		state->txb.num_lanes = num_lanes;
> >>>>> +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
> >>>>> +	}
> >>>>> +
> >>>>> +	return 0;
> >>>>> +}
> > 
> > [snip]
Niklas Söderlund Sept. 18, 2018, 7:06 p.m. UTC | #8
Hi Kieran and Laurent,

Thanks for all your comments!

On 2018-09-18 11:51:34 +0100, Kieran Bingham wrote:

[snip]

> > 
> > I'm not sure there's a sensible default, I'd rather specify it explicitly. 
> > Note that the data-lanes property doesn't just specify the number of lanes, 
> > but also how they are remapped, when that feature is supported by the CSI-2 
> > transmitter or receiver.
> 
> 
> Ok understood. As I feared - we can't really default - because it has to
> match and be defined.
> 
> So making the DT property mandatory really is the way to go then.

I will add a patch making the property mandatory.
Sakari Ailus Sept. 20, 2018, 11:43 p.m. UTC | #9
Hi Laurent, Kieran,

On Tue, Sep 18, 2018 at 02:13:29PM +0300, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Tuesday, 18 September 2018 13:51:34 EEST Kieran Bingham wrote:
> > On 18/09/18 11:46, Laurent Pinchart wrote:
> > > On Tuesday, 18 September 2018 13:37:55 EEST Kieran Bingham wrote:
> > >> On 18/09/18 11:28, Laurent Pinchart wrote:
> > >>> On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
> > >>>> On 18/09/18 02:45, Niklas Söderlund wrote:
> > >>>>> The adv748x CSI-2 transmitters TXA and TXB can use different number of
> > >>>>> lines to transmit data on. In order to be able configure the device
> > >>>>> correctly this information need to be parsed from device tree and
> > >>>>> stored in each TX private data structure.
> > >>>>> 
> > >>>>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> > >>>> 
> > >>>> Am I right in assuming that it is the CSI device which specifies the
> > >>>> number of lanes in their DT?
> > >>> 
> > >>> Do you mean the CSI-2 receiver ? Both the receiver and the transmitter
> > >>> should specify the data lanes in their DT node.
> > >> 
> > >> Yes, I should have said CSI-2 receiver.
> > >> 
> > >> Aha - so *both* sides of the link have to specify the lanes and
> > >> presumably match with each other?
> > > 
> > > Yes, they should certainly match :-)
> > 
> > I assumed so :) - do we need to validate that at a framework level?
> > (or perhaps it already is, all I've only looked at this morning is
> > e-mails :D )
> 
> It's not done yet as far as I know. CC'ing Sakari who may have a comment 
> regarding whether this should be added.

There's no validation done currently. The endpoints are parsed separately
at the moment, initiated by the respective device driver.

The latest fwnode set brings a concept of default configuration that also
allows support for setting the default for the number of lanes. This is
known by the driver, but could not be known by the framework checking the
configuration across the endpoints. I guess this could be done at the time
both endpoints have been parsed, as in stored to the async sub-device.

Some checks could indeed be done, but what to do when those checks fail?

That said, I don't think this has really been an issue so far --- if you
get this wrong the devices just won't work. The last fwnode set greatly
improves the quality of the debug information printed, so debugging should
be easier when things go wrong already. And this is already more than we've
had so far.

> 
> > >>>> Could we make this clear in the commit log (and possibly an extra
> > >>>> comment in the code). At first I was assuming we would have to declare
> > >>>> the number of lanes in the ADV748x TX DT node, but I don't think that's
> > >>>> the case.
> > >>>> 
> > >>>>> Signed-off-by: Niklas Söderlund
> > >>>>> <niklas.soderlund+renesas@ragnatech.se>
> > >>>>> ---
> > >>>>> 
> > >>>>>  drivers/media/i2c/adv748x/adv748x-core.c | 49 +++++++++++++++++++++++
> > >>>>>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
> > >>>>>  2 files changed, 50 insertions(+)
> > >>>>> 
> > >>>>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
> > >>>>> b/drivers/media/i2c/adv748x/adv748x-core.c index
> > >>>>> 85c027bdcd56748d..a93f8ea89a228474 100644
> > >>>>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> > >>>>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> > > 
> > > [snip]
> > > 
> > >>>>> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
> > >>>>> +				    unsigned int port,
> > >>>>> +				    struct device_node *ep)
> > >>>>> +{
> > >>>>> +	struct v4l2_fwnode_endpoint vep;
> > >>>>> +	unsigned int num_lanes;
> > >>>>> +	int ret;
> > >>>>> +
> > >>>>> +	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
> > >>>>> +		return 0;
> > >>>>> +
> > >>>>> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
> > >>>>> +	if (ret)
> > >>>>> +		return ret;
> > >>>>> +
> > >>>>> +	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> > >>>>> +
> > >>>> 
> > >>>> If I'm not mistaken we are parsing /someone elses/ DT node here (the
> > >>>> CSI receiver or such).
> > >>> 
> > >>> Aren't we parsing our own endpoint ? The ep argument comes from ep_np in
> > >>> adv748x_parse_dt(), and that's the endpoint iterator used with
> > >>> 
> > >>> 	for_each_endpoint_of_node(state->dev->of_node, ep_np)
> > >> 
> > >> Bah - my head was polluted with the async subdevice stuff where we were
> > >> getting the endpoint of the other device, but of course that's
> > >> completely unrelated here.
> > >> 
> > >>>> Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
> > >>>> defined?
> > >>>> 
> > >>>> Do we need to fall back to some safe defaults at all (1 lane?) ?
> > >>>> Actually - perhaps there is no safe default. I guess if the lanes
> > >>>> aren't configured correctly we're not going to get a good signal at the
> > >>>> other end.
> > >>> 
> > >>> The endpoints should contain a data-lanes property. That's the case in
> > >>> the mainline DT sources, but it's not explicitly stated as a mandatory
> > >>> property. I think we should update the bindings.

Many devices have just a single lane. Do you think this should be mandatory
in that case as well?

Lane mapping is not a very common feature nowadays; to be fair, I don't
know other hardware than omap3isp that supports it. The numbers are still
needed as many devices nowadays support choosing how the lanes are
distributed across the PHYs.

> > >> 
> > >> Yes, - as this code change is making the property mandatory - we should
> > >> certainly state that in the bindings, unless we can fall back to a
> > >> sensible default (perhaps the max supported on that component?)
> > > 
> > > I'm not sure there's a sensible default, I'd rather specify it explicitly.
> > > Note that the data-lanes property doesn't just specify the number of
> > > lanes, but also how they are remapped, when that feature is supported by
> > > the CSI-2 transmitter or receiver.
> > 
> > Ok understood. As I feared - we can't really default - because it has to
> > match and be defined.
> > 
> > So making the DT property mandatory really is the way to go then.

I certainly have no objections to making this mandatory for some devices as
long as it makes sense --- and for devices with just a single data lane
without remapping with the clock lane it does not.

In that case, the driver would just set the number of lanes in the default
configuration to zero, and check the configuration it gets back is valid
--- as usual.

For what it's worth, quite a few parallel interface devices explicitly
state default configurations in their DT bindings. I admit the data-lanes
property is not a great candidate for setting a default for (if a device
has more than a single data lane).

> > 
> > >>>>> +	if (vep.base.port == ADV748X_PORT_TXA) {
> > >>>>> +		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
> > >>>>> +			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
> > >>>>> +				num_lanes);
> > >>>>> +			return -EINVAL;
> > >>>>> +		}
> > >>>>> +
> > >>>>> +		state->txa.num_lanes = num_lanes;
> > >>>>> +		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
> > >>>>> +	}
> > >>>>> +
> > >>>>> +	if (vep.base.port == ADV748X_PORT_TXB) {
> > >>>>> +		if (num_lanes != 1) {
> > >>>>> +			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
> > >>>>> +				num_lanes);
> > >>>>> +			return -EINVAL;
> > >>>>> +		}
> > >>>>> +
> > >>>>> +		state->txb.num_lanes = num_lanes;
> > >>>>> +		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
> > >>>>> +	}
> > >>>>> +
> > >>>>> +	return 0;
> > >>>>> +}
> > > 
> > > [snip]
>
Dave Stevenson Sept. 21, 2018, 9:33 a.m. UTC | #10
Hi All,

On Tue, 18 Sep 2018 at 12:13, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Kieran,
>
> On Tuesday, 18 September 2018 13:51:34 EEST Kieran Bingham wrote:
> > On 18/09/18 11:46, Laurent Pinchart wrote:
> > > On Tuesday, 18 September 2018 13:37:55 EEST Kieran Bingham wrote:
> > >> On 18/09/18 11:28, Laurent Pinchart wrote:
> > >>> On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
> > >>>> On 18/09/18 02:45, Niklas Söderlund wrote:
> > >>>>> The adv748x CSI-2 transmitters TXA and TXB can use different number of
> > >>>>> lines to transmit data on. In order to be able configure the device
> > >>>>> correctly this information need to be parsed from device tree and
> > >>>>> stored in each TX private data structure.
> > >>>>>
> > >>>>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> > >>>>
> > >>>> Am I right in assuming that it is the CSI device which specifies the
> > >>>> number of lanes in their DT?
> > >>>
> > >>> Do you mean the CSI-2 receiver ? Both the receiver and the transmitter
> > >>> should specify the data lanes in their DT node.
> > >>
> > >> Yes, I should have said CSI-2 receiver.
> > >>
> > >> Aha - so *both* sides of the link have to specify the lanes and
> > >> presumably match with each other?
> > >
> > > Yes, they should certainly match :-)
> >
> > I assumed so :) - do we need to validate that at a framework level?
> > (or perhaps it already is, all I've only looked at this morning is
> > e-mails :D )
>
> It's not done yet as far as I know. CC'ing Sakari who may have a comment
> regarding whether this should be added.

(Interested party here due to CSI2 interfacing on the Pi, and I'd like
to try and get adv748x working on the Pi once I can get some hardware)

Do they need to match? DT is supposedly describing the hardware. Where
are you drawing the boundary between the two devices from the
hardware/devicetree perspective?

As an example, the CSI2 receiver can support 4 lanes, whilst the
source only needs 2, or only has 2 connected. As long as the two ends
agree on the value in use (which will typically match the source),
then there is no issue.
It does require the CSI2 receiver driver to validate the remote
endpoint settings to ensure that the source doesn't try to use more
lanes than the receiver can cope with. That isn't a big deal as you
already have the link to the remote end-point. Presumably you're
already checking it to determine settings such as if the source is
using continuous clocks or not, unless you expect that to be
duplicated on both endpoints or your hardware doesn't care.

I'm genuinely interested on views here. On the Pi there will be a
variety of CSI2 devices connected, generally configured using
dtoverlays, and they will have varying requirements on number of
lanes. Standard Pis only have 2 CSI-2 lanes exposed out of a possible
4 for the peripheral. The Compute Module is the exception where one
CSI2 interface has all 4 lanes brought out, the other only supports 2
lanes anyway.
I'm expecting the CSI2 receiver endpoint data-lanes property to match
that exposed by the Pi board, whilst the source endpoint data-lanes
property defines what the source uses. That allows easy validation by
the driver that the configuration can work. Otherwise an overlay would
have to write the number of lanes used on both the CSI endpoints and
potentially configuring it to use more lanes than can be supported.


There is also the oddball one of the TC358743 which dynamically
switches the number of lanes in use based on the data rate required.
That's probably a separate discussion, but is currently dealt with via
g_mbus_config as amended back in Sept 2017 [1].

Cheers,
  Dave

[1] Discussion https://www.spinics.net/lists/linux-media/msg122287.html
and patch https://www.spinics.net/lists/linux-media/msg122435.html

> > >>>> Could we make this clear in the commit log (and possibly an extra
> > >>>> comment in the code). At first I was assuming we would have to declare
> > >>>> the number of lanes in the ADV748x TX DT node, but I don't think that's
> > >>>> the case.
> > >>>>
> > >>>>> Signed-off-by: Niklas Söderlund
> > >>>>> <niklas.soderlund+renesas@ragnatech.se>
> > >>>>> ---
> > >>>>>
> > >>>>>  drivers/media/i2c/adv748x/adv748x-core.c | 49 +++++++++++++++++++++++
> > >>>>>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
> > >>>>>  2 files changed, 50 insertions(+)
> > >>>>>
> > >>>>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c
> > >>>>> b/drivers/media/i2c/adv748x/adv748x-core.c index
> > >>>>> 85c027bdcd56748d..a93f8ea89a228474 100644
> > >>>>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> > >>>>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> > >
> > > [snip]
> > >
> > >>>>> +static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
> > >>>>> +                                   unsigned int port,
> > >>>>> +                                   struct device_node *ep)
> > >>>>> +{
> > >>>>> +       struct v4l2_fwnode_endpoint vep;
> > >>>>> +       unsigned int num_lanes;
> > >>>>> +       int ret;
> > >>>>> +
> > >>>>> +       if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
> > >>>>> +               return 0;
> > >>>>> +
> > >>>>> +       ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
> > >>>>> +       if (ret)
> > >>>>> +               return ret;
> > >>>>> +
> > >>>>> +       num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> > >>>>> +
> > >>>>
> > >>>> If I'm not mistaken we are parsing /someone elses/ DT node here (the
> > >>>> CSI receiver or such).
> > >>>
> > >>> Aren't we parsing our own endpoint ? The ep argument comes from ep_np in
> > >>> adv748x_parse_dt(), and that's the endpoint iterator used with
> > >>>
> > >>>   for_each_endpoint_of_node(state->dev->of_node, ep_np)
> > >>
> > >> Bah - my head was polluted with the async subdevice stuff where we were
> > >> getting the endpoint of the other device, but of course that's
> > >> completely unrelated here.
> > >>
> > >>>> Is it now guaranteed on the mipi_csi2 bus to have the (correct) lanes
> > >>>> defined?
> > >>>>
> > >>>> Do we need to fall back to some safe defaults at all (1 lane?) ?
> > >>>> Actually - perhaps there is no safe default. I guess if the lanes
> > >>>> aren't configured correctly we're not going to get a good signal at the
> > >>>> other end.
> > >>>
> > >>> The endpoints should contain a data-lanes property. That's the case in
> > >>> the mainline DT sources, but it's not explicitly stated as a mandatory
> > >>> property. I think we should update the bindings.
> > >>
> > >> Yes, - as this code change is making the property mandatory - we should
> > >> certainly state that in the bindings, unless we can fall back to a
> > >> sensible default (perhaps the max supported on that component?)
> > >
> > > I'm not sure there's a sensible default, I'd rather specify it explicitly.
> > > Note that the data-lanes property doesn't just specify the number of
> > > lanes, but also how they are remapped, when that feature is supported by
> > > the CSI-2 transmitter or receiver.
> >
> > Ok understood. As I feared - we can't really default - because it has to
> > match and be defined.
> >
> > So making the DT property mandatory really is the way to go then.
> >
> > >>>>> +       if (vep.base.port == ADV748X_PORT_TXA) {
> > >>>>> +               if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
> > >>>>> +                       adv_err(state, "TXA: Invalid number (%d) of lanes\n",
> > >>>>> +                               num_lanes);
> > >>>>> +                       return -EINVAL;
> > >>>>> +               }
> > >>>>> +
> > >>>>> +               state->txa.num_lanes = num_lanes;
> > >>>>> +               adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
> > >>>>> +       }
> > >>>>> +
> > >>>>> +       if (vep.base.port == ADV748X_PORT_TXB) {
> > >>>>> +               if (num_lanes != 1) {
> > >>>>> +                       adv_err(state, "TXB: Invalid number (%d) of lanes\n",
> > >>>>> +                               num_lanes);
> > >>>>> +                       return -EINVAL;
> > >>>>> +               }
> > >>>>> +
> > >>>>> +               state->txb.num_lanes = num_lanes;
> > >>>>> +               adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
> > >>>>> +       }
> > >>>>> +
> > >>>>> +       return 0;
> > >>>>> +}
> > >
> > > [snip]
>
> --
> Regards,
>
> Laurent Pinchart
>
>
>
Laurent Pinchart Sept. 21, 2018, 10:01 a.m. UTC | #11
Hi Dave,

On Friday, 21 September 2018 12:33:39 EEST Dave Stevenson wrote:
> On Tue, 18 Sep 2018 at 12:13, Laurent Pinchart wrote:
> > On Tuesday, 18 September 2018 13:51:34 EEST Kieran Bingham wrote:
> >> On 18/09/18 11:46, Laurent Pinchart wrote:
> >>> On Tuesday, 18 September 2018 13:37:55 EEST Kieran Bingham wrote:
> >>>> On 18/09/18 11:28, Laurent Pinchart wrote:
> >>>>> On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
> >>>>>> On 18/09/18 02:45, Niklas Söderlund wrote:
> >>>>>>> The adv748x CSI-2 transmitters TXA and TXB can use different
> >>>>>>> number of lines to transmit data on. In order to be able configure
> >>>>>>> the device correctly this information need to be parsed from
> >>>>>>> device tree and stored in each TX private data structure.
> >>>>>>> 
> >>>>>>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> >>>>>> 
> >>>>>> Am I right in assuming that it is the CSI device which specifies
> >>>>>> the number of lanes in their DT?
> >>>>> 
> >>>>> Do you mean the CSI-2 receiver ? Both the receiver and the
> >>>>> transmitter should specify the data lanes in their DT node.
> >>>> 
> >>>> Yes, I should have said CSI-2 receiver.
> >>>> 
> >>>> Aha - so *both* sides of the link have to specify the lanes and
> >>>> presumably match with each other?
> >>> 
> >>> Yes, they should certainly match :-)
> >> 
> >> I assumed so :) - do we need to validate that at a framework level?
> >> (or perhaps it already is, all I've only looked at this morning is
> >> e-mails :D )
> > 
> > It's not done yet as far as I know. CC'ing Sakari who may have a comment
> > regarding whether this should be added.
> 
> (Interested party here due to CSI2 interfacing on the Pi, and I'd like
> to try and get adv748x working on the Pi once I can get some hardware)
> 
> Do they need to match? DT is supposedly describing the hardware. Where
> are you drawing the boundary between the two devices from the
> hardware/devicetree perspective?
> 
> As an example, the CSI2 receiver can support 4 lanes, whilst the
> source only needs 2, or only has 2 connected. As long as the two ends
> agree on the value in use (which will typically match the source),
> then there is no issue.
> It does require the CSI2 receiver driver to validate the remote
> endpoint settings to ensure that the source doesn't try to use more
> lanes than the receiver can cope with. That isn't a big deal as you
> already have the link to the remote end-point. Presumably you're
> already checking it to determine settings such as if the source is
> using continuous clocks or not, unless you expect that to be
> duplicated on both endpoints or your hardware doesn't care.

At least for the data-lanes property, the value is meant to describe how lanes 
are physically connected on the board from the transmitter to the receiver. It 
does not tell the maximum of lanes that the device supports, which is 
intrinsic information known to the driver already.

Regarding other parameters, such as the clock mode you mentioned, they should 
usually be queried and negotiated at runtime, especially given that both the 
transmitting and receiving devices may very well support multiple options. We 
usually don't involve DT in those cases. Parsing DT properties of a remote 
node is frowned upon, because those properties are qualified by the compatible 
string of the node they sit in. A driver matching "foo,abc" knows what 
properties are defined for the corresponding DT node, but when that driver 
crosses links to DT node "bar,xyz", it has no a priori knowledge of what to 
expect there.

Following the OF graph through endpoints and ports is still fine, as if a DT 
node uses the OF graph bindings, the nodes it is connected to are assumed to 
use the same bindings. No assumption can usually be made on other properties 
though, including the ones describing the bus configuration. For that reason 
the properties for the CSI-2 source should be parsed by the CSI-2 source 
driver, and the configuration of the source should be queried by the CSI-2 
receiver at runtime using the v4l2_subdev API (which is routinely extended 
with additional configuration information when the need arises).

> I'm genuinely interested on views here. On the Pi there will be a
> variety of CSI2 devices connected, generally configured using
> dtoverlays, and they will have varying requirements on number of
> lanes. Standard Pis only have 2 CSI-2 lanes exposed out of a possible
> 4 for the peripheral. The Compute Module is the exception where one
> CSI2 interface has all 4 lanes brought out, the other only supports 2
> lanes anyway.
> I'm expecting the CSI2 receiver endpoint data-lanes property to match
> that exposed by the Pi board, whilst the source endpoint data-lanes
> property defines what the source uses. That allows easy validation by
> the driver that the configuration can work. Otherwise an overlay would
> have to write the number of lanes used on both the CSI endpoints and
> potentially configuring it to use more lanes than can be supported.

As explained above, we currently expect the latter, with the overlay modifying 
the data-lanes property of the receiver as well. This is partly due to the 
fact that receivers can support data lanes remapping, so the data-lanes 
property of the receiver needs not only to specify the number of lanes, but 
also how they are connected.

If you want to validate the data-lanes property to ensure the overlay doesn't 
try to use more lanes than available, you can do so either against a hardcoded 
value in the receiver driver (when the maximum is fixed for a given compatible 
string), or against a value read from DT (when the maximum depends on the 
board).

> There is also the oddball one of the TC358743 which dynamically
> switches the number of lanes in use based on the data rate required.
> That's probably a separate discussion, but is currently dealt with via
> g_mbus_config as amended back in Sept 2017 [1].

This falls into the case of dynamic configuration discovery and negotiation I 
mentioned above, and we clearly need to make sure the v4l2_subdev API supports 
this use case.

> [1] Discussion https://www.spinics.net/lists/linux-media/msg122287.html
> and patch https://www.spinics.net/lists/linux-media/msg122435.html
> 
> >>>>>> Could we make this clear in the commit log (and possibly an extra
> >>>>>> comment in the code). At first I was assuming we would have to
> >>>>>> declare the number of lanes in the ADV748x TX DT node, but I don't
> >>>>>> think that's the case.
> >>>>>> 
> >>>>>>> Signed-off-by: Niklas Söderlund
> >>>>>>> <niklas.soderlund+renesas@ragnatech.se>
> >>>>>>> ---
> >>>>>>> 
> >>>>>>>  drivers/media/i2c/adv748x/adv748x-core.c | 49 +++++++++++++++++++++
> >>>>>>>  drivers/media/i2c/adv748x/adv748x.h      |  1 +
> >>>>>>>  2 files changed, 50 insertions(+)

[snip]
Sakari Ailus Sept. 21, 2018, 12:03 p.m. UTC | #12
Hi Laurent,

On Fri, Sep 21, 2018 at 01:01:09PM +0300, Laurent Pinchart wrote:
...
> > There is also the oddball one of the TC358743 which dynamically
> > switches the number of lanes in use based on the data rate required.
> > That's probably a separate discussion, but is currently dealt with via
> > g_mbus_config as amended back in Sept 2017 [1].
> 
> This falls into the case of dynamic configuration discovery and negotiation I 
> mentioned above, and we clearly need to make sure the v4l2_subdev API supports 
> this use case.

This could be added to struct v4l2_mbus_frame_desc; Niklas has driver that
uses the framework support here, so this would likely end up merged soon:

<URL:https://git.linuxtv.org/sailus/media_tree.git/tree/include/media/v4l2-subdev.h?h=vc&id=0cbd2b25b37ef5b2e6a14340dbca6d2d2d5af98e>

The CSI-2 bus parameters are missing there currently but nothing prevents
adding them. The semantics of set_frame_desc() needs to be probably defined
better than it currently is.
Dave Stevenson Sept. 21, 2018, 1:38 p.m. UTC | #13
Hi Laurent,

Thanks for the response.

On Fri, 21 Sep 2018 at 11:00, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Dave,
>
> On Friday, 21 September 2018 12:33:39 EEST Dave Stevenson wrote:
> > On Tue, 18 Sep 2018 at 12:13, Laurent Pinchart wrote:
> > > On Tuesday, 18 September 2018 13:51:34 EEST Kieran Bingham wrote:
> > >> On 18/09/18 11:46, Laurent Pinchart wrote:
> > >>> On Tuesday, 18 September 2018 13:37:55 EEST Kieran Bingham wrote:
> > >>>> On 18/09/18 11:28, Laurent Pinchart wrote:
> > >>>>> On Tuesday, 18 September 2018 13:19:39 EEST Kieran Bingham wrote:
> > >>>>>> On 18/09/18 02:45, Niklas Söderlund wrote:
> > >>>>>>> The adv748x CSI-2 transmitters TXA and TXB can use different
> > >>>>>>> number of lines to transmit data on. In order to be able configure
> > >>>>>>> the device correctly this information need to be parsed from
> > >>>>>>> device tree and stored in each TX private data structure.
> > >>>>>>>
> > >>>>>>> TXA supports 1, 2 and 4 lanes while TXB supports 1 lane.
> > >>>>>>
> > >>>>>> Am I right in assuming that it is the CSI device which specifies
> > >>>>>> the number of lanes in their DT?
> > >>>>>
> > >>>>> Do you mean the CSI-2 receiver ? Both the receiver and the
> > >>>>> transmitter should specify the data lanes in their DT node.
> > >>>>
> > >>>> Yes, I should have said CSI-2 receiver.
> > >>>>
> > >>>> Aha - so *both* sides of the link have to specify the lanes and
> > >>>> presumably match with each other?
> > >>>
> > >>> Yes, they should certainly match :-)
> > >>
> > >> I assumed so :) - do we need to validate that at a framework level?
> > >> (or perhaps it already is, all I've only looked at this morning is
> > >> e-mails :D )
> > >
> > > It's not done yet as far as I know. CC'ing Sakari who may have a comment
> > > regarding whether this should be added.
> >
> > (Interested party here due to CSI2 interfacing on the Pi, and I'd like
> > to try and get adv748x working on the Pi once I can get some hardware)
> >
> > Do they need to match? DT is supposedly describing the hardware. Where
> > are you drawing the boundary between the two devices from the
> > hardware/devicetree perspective?
> >
> > As an example, the CSI2 receiver can support 4 lanes, whilst the
> > source only needs 2, or only has 2 connected. As long as the two ends
> > agree on the value in use (which will typically match the source),
> > then there is no issue.
> > It does require the CSI2 receiver driver to validate the remote
> > endpoint settings to ensure that the source doesn't try to use more
> > lanes than the receiver can cope with. That isn't a big deal as you
> > already have the link to the remote end-point. Presumably you're
> > already checking it to determine settings such as if the source is
> > using continuous clocks or not, unless you expect that to be
> > duplicated on both endpoints or your hardware doesn't care.
>
> At least for the data-lanes property, the value is meant to describe how lanes
> are physically connected on the board from the transmitter to the receiver. It
> does not tell the maximum of lanes that the device supports, which is
> intrinsic information known to the driver already.

Where is the driver getting that information from if not DT?
On the Pi we have two instances of the same peripheral, but it is
parameterised such that one instance only has 2 lanes implemented, and
the other has 4 lanes. Also we have some boards with both the 4-lane
instance where only 2 are wired out to the camera connector.

When trying to get the Pi DT bindings accepted I got blocked from
adding a DT parameter that specified the number of lanes implemented
by the peripheral and told to use data-lanes [1]. Now you say the
driver is meant to intrinsically know. I'm confused.

> Regarding other parameters, such as the clock mode you mentioned, they should
> usually be queried and negotiated at runtime, especially given that both the
> transmitting and receiving devices may very well support multiple options. We
> usually don't involve DT in those cases. Parsing DT properties of a remote
> node is frowned upon, because those properties are qualified by the compatible
> string of the node they sit in. A driver matching "foo,abc" knows what
> properties are defined for the corresponding DT node, but when that driver
> crosses links to DT node "bar,xyz", it has no a priori knowledge of what to
> expect there.
>
> Following the OF graph through endpoints and ports is still fine, as if a DT
> node uses the OF graph bindings, the nodes it is connected to are assumed to
> use the same bindings. No assumption can usually be made on other properties
> though, including the ones describing the bus configuration. For that reason
> the properties for the CSI-2 source should be parsed by the CSI-2 source
> driver, and the configuration of the source should be queried by the CSI-2
> receiver at runtime using the v4l2_subdev API (which is routinely extended
> with additional configuration information when the need arises).

You've lost me as to what you are saying is and isn't frowned upon.
data-lanes is in the endpoint, so we're following the OF graph through
the remote-endpoint. Are you saying that it is, or isn't, valid to
assume anything about data-lanes in remote-endpoint?

Do we have a subdev API call that provides this information at
runtime? There are the relatively new fwnode calls, but that is
parsing the endpoint, and you you're saying we're not meant to look at
the remote-endpoint.
Or are you saying that it should be done through the subdev API, but
isn't at the moment? I'd just like to know for definite.

From what you say it appears I need to update my example DT binding
[2] as it should duplicate "clock-noncontinuous;" in both endpoints.
Is that right?

> > I'm genuinely interested on views here. On the Pi there will be a
> > variety of CSI2 devices connected, generally configured using
> > dtoverlays, and they will have varying requirements on number of
> > lanes. Standard Pis only have 2 CSI-2 lanes exposed out of a possible
> > 4 for the peripheral. The Compute Module is the exception where one
> > CSI2 interface has all 4 lanes brought out, the other only supports 2
> > lanes anyway.
> > I'm expecting the CSI2 receiver endpoint data-lanes property to match
> > that exposed by the Pi board, whilst the source endpoint data-lanes
> > property defines what the source uses. That allows easy validation by
> > the driver that the configuration can work. Otherwise an overlay would
> > have to write the number of lanes used on both the CSI endpoints and
> > potentially configuring it to use more lanes than can be supported.
>
> As explained above, we currently expect the latter, with the overlay modifying
> the data-lanes property of the receiver as well. This is partly due to the
> fact that receivers can support data lanes remapping, so the data-lanes
> property of the receiver needs not only to specify the number of lanes, but
> also how they are connected.

So data-lanes can't be used as any form of sanity checking, and
multiple parameters get duplicated between the endpoints. Ack.

> If you want to validate the data-lanes property to ensure the overlay doesn't
> try to use more lanes than available, you can do so either against a hardcoded
> value in the receiver driver (when the maximum is fixed for a given compatible
> string), or against a value read from DT (when the maximum depends on the
> board).

As above, I was told by Sakari to use data-lanes [1].
His comment:
"Please use "data-lanes" endpoint property instead. This is the number of
connected physical lanes and specific to the hardware."

I'd read that as It is the number of physical lanes connected to the
camera connector (not necessarily the camera itself) on that
particular board, otherwise it isn't a max-lanes parameter just a
lanes.
You're saying it should be specific to the board and sensor combination.

> > There is also the oddball one of the TC358743 which dynamically
> > switches the number of lanes in use based on the data rate required.
> > That's probably a separate discussion, but is currently dealt with via
> > g_mbus_config as amended back in Sept 2017 [1].
>
> This falls into the case of dynamic configuration discovery and negotiation I
> mentioned above, and we clearly need to make sure the v4l2_subdev API supports
> this use case.

So it doesn't support it at the moment?
We're relying 100% on both DT entries being matched and consistent,
and can't cope with dynamic reconfig (I see Phillipp's patch for the
workaround with g_mbus_config never got merged).

I thought I'd got a handle on this DT stuff, but obviously not :-(

Thanks,
  Dave

[1] https://www.spinics.net/lists/linux-media/msg117080.html
[2] https://www.spinics.net/lists/linux-media/msg122299.html
Dave Stevenson Sept. 21, 2018, 1:46 p.m. UTC | #14
Hi Sakari

On Fri, 21 Sep 2018 at 13:03, Sakari Ailus <sakari.ailus@iki.fi> wrote:
>
> Hi Laurent,
>
> On Fri, Sep 21, 2018 at 01:01:09PM +0300, Laurent Pinchart wrote:
> ...
> > > There is also the oddball one of the TC358743 which dynamically
> > > switches the number of lanes in use based on the data rate required.
> > > That's probably a separate discussion, but is currently dealt with via
> > > g_mbus_config as amended back in Sept 2017 [1].
> >
> > This falls into the case of dynamic configuration discovery and negotiation I
> > mentioned above, and we clearly need to make sure the v4l2_subdev API supports
> > this use case.
>
> This could be added to struct v4l2_mbus_frame_desc; Niklas has driver that
> uses the framework support here, so this would likely end up merged soon:
>
> <URL:https://git.linuxtv.org/sailus/media_tree.git/tree/include/media/v4l2-subdev.h?h=vc&id=0cbd2b25b37ef5b2e6a14340dbca6d2d2d5af98e>
>
> The CSI-2 bus parameters are missing there currently but nothing prevents
> adding them. The semantics of set_frame_desc() needs to be probably defined
> better than it currently is.

So which parameters are you thinking of putting in there? Just the
number of lanes, or clocking modes and all other parameters for the
CSI interface?
It sounds like this should take over from the receiver's DT
completely, other than for lane reordering.

Of course the $1million question is rough timescales? The last commit
on there appears to be March 2017.
I've had to backburner my CSI2 receiver driver due to other time
pressures, so it sounds like I may as well leave it there until this
all settles down, or start looking at Niklas' driver and what changes
infers.

Thanks,
  Dave
Sakari Ailus Nov. 13, 2018, 9:40 a.m. UTC | #15
Hi Dave,

Apologies for the delay.

On Fri, Sep 21, 2018 at 02:46:23PM +0100, Dave Stevenson wrote:
> Hi Sakari
> 
> On Fri, 21 Sep 2018 at 13:03, Sakari Ailus <sakari.ailus@iki.fi> wrote:
> >
> > Hi Laurent,
> >
> > On Fri, Sep 21, 2018 at 01:01:09PM +0300, Laurent Pinchart wrote:
> > ...
> > > > There is also the oddball one of the TC358743 which dynamically
> > > > switches the number of lanes in use based on the data rate required.
> > > > That's probably a separate discussion, but is currently dealt with via
> > > > g_mbus_config as amended back in Sept 2017 [1].
> > >
> > > This falls into the case of dynamic configuration discovery and negotiation I
> > > mentioned above, and we clearly need to make sure the v4l2_subdev API supports
> > > this use case.
> >
> > This could be added to struct v4l2_mbus_frame_desc; Niklas has driver that
> > uses the framework support here, so this would likely end up merged soon:
> >
> > <URL:https://git.linuxtv.org/sailus/media_tree.git/tree/include/media/v4l2-subdev.h?h=vc&id=0cbd2b25b37ef5b2e6a14340dbca6d2d2d5af98e>
> >
> > The CSI-2 bus parameters are missing there currently but nothing prevents
> > adding them. The semantics of set_frame_desc() needs to be probably defined
> > better than it currently is.
> 
> So which parameters are you thinking of putting in there? Just the
> number of lanes, or clocking modes and all other parameters for the
> CSI interface?

I think it could be the number of active lanes, I don't think other
parameters need to change.

> It sounds like this should take over from the receiver's DT
> completely, other than for lane reordering.

Hmm. Right now I don't have an opinion either way. But I'd like to know
what others think.

The endpoint configuration is currently local to the endpoint only. On
other busses than CSI-2 there are more parameters that may be different on
each side of the endpoint. If the parameters are moved to the frame
descriptor entirely, there's no way to e.g. validate them in probe. At
least one would need to show that this is not an issue, or address it
somehow.

> 
> Of course the $1million question is rough timescales? The last commit
> on there appears to be March 2017.
> I've had to backburner my CSI2 receiver driver due to other time
> pressures, so it sounds like I may as well leave it there until this
> all settles down, or start looking at Niklas' driver and what changes
> infers.

Yes; if you write patches to this, please do that on top of Niklas' set.
diff mbox series

Patch

diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
index 85c027bdcd56748d..a93f8ea89a228474 100644
--- a/drivers/media/i2c/adv748x/adv748x-core.c
+++ b/drivers/media/i2c/adv748x/adv748x-core.c
@@ -23,6 +23,7 @@ 
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-dv-timings.h>
+#include <media/v4l2-fwnode.h>
 #include <media/v4l2-ioctl.h>
 
 #include "adv748x.h"
@@ -561,11 +562,54 @@  void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state,
 	sd->entity.ops = &adv748x_media_ops;
 }
 
+static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
+				    unsigned int port,
+				    struct device_node *ep)
+{
+	struct v4l2_fwnode_endpoint vep;
+	unsigned int num_lanes;
+	int ret;
+
+	if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
+		return 0;
+
+	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
+	if (ret)
+		return ret;
+
+	num_lanes = vep.bus.mipi_csi2.num_data_lanes;
+
+	if (vep.base.port == ADV748X_PORT_TXA) {
+		if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4) {
+			adv_err(state, "TXA: Invalid number (%d) of lanes\n",
+				num_lanes);
+			return -EINVAL;
+		}
+
+		state->txa.num_lanes = num_lanes;
+		adv_dbg(state, "TXA: using %d lanes\n", state->txa.num_lanes);
+	}
+
+	if (vep.base.port == ADV748X_PORT_TXB) {
+		if (num_lanes != 1) {
+			adv_err(state, "TXB: Invalid number (%d) of lanes\n",
+				num_lanes);
+			return -EINVAL;
+		}
+
+		state->txb.num_lanes = num_lanes;
+		adv_dbg(state, "TXB: using %d lanes\n", state->txb.num_lanes);
+	}
+
+	return 0;
+}
+
 static int adv748x_parse_dt(struct adv748x_state *state)
 {
 	struct device_node *ep_np = NULL;
 	struct of_endpoint ep;
 	bool found = false;
+	int ret;
 
 	for_each_endpoint_of_node(state->dev->of_node, ep_np) {
 		of_graph_parse_endpoint(ep_np, &ep);
@@ -589,6 +633,11 @@  static int adv748x_parse_dt(struct adv748x_state *state)
 		state->endpoints[ep.port] = ep_np;
 
 		found = true;
+
+		/* Store number of CSI-2 lanes used for TXA and TXB. */
+		ret = adv748x_parse_csi2_lanes(state, ep.port, ep_np);
+		if (ret)
+			return ret;
 	}
 
 	return found ? 0 : -ENODEV;
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
index c9016acaba34aff2..88ad06a3045c5427 100644
--- a/drivers/media/i2c/adv748x/adv748x.h
+++ b/drivers/media/i2c/adv748x/adv748x.h
@@ -78,6 +78,7 @@  struct adv748x_csi2 {
 	struct adv748x_state *state;
 	struct v4l2_mbus_framefmt format;
 	unsigned int page;
+	unsigned int num_lanes;
 
 	struct media_pad pads[ADV748X_CSI2_NR_PADS];
 	struct v4l2_ctrl_handler ctrl_hdl;