linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hans Verkuil <hverkuil@xs4all.nl>
To: "Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>,
	"Laurent Pinchart" <laurent.pinchart@ideasonboard.com>,
	linux-media@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org,
	tomoharu.fukawa.eb@renesas.com,
	Kieran Bingham <kieran.bingham@ideasonboard.com>
Subject: Re: [PATCH v12 28/33] rcar-vin: parse Gen3 OF and setup media graph
Date: Fri, 9 Mar 2018 16:45:38 +0100	[thread overview]
Message-ID: <cb19f23a-7bfb-539c-5135-c185d56c78d7@xs4all.nl> (raw)
In-Reply-To: <20180307220511.9826-29-niklas.soderlund+renesas@ragnatech.se>

On 07/03/18 23:05, Niklas Söderlund wrote:
> The parsing and registering CSI-2 subdevices with the v4l2 async
> framework is a collaborative effort shared between the VIN instances
> which are part of the group. When the last VIN in the group is probed it
> asks all other VINs to parse its share of OF and record the async
> subdevices it finds in the notifier belonging to the last probed VIN.
> 
> Once all CSI-2 subdevices in this notifier are bound proceed to register
> all VIN video devices of the group and crate media device links between
> all CSI-2 and VIN entities according to the SoC specific routing
> configuration.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/media/platform/rcar-vin/rcar-core.c | 246 +++++++++++++++++++++++++++-
>  drivers/media/platform/rcar-vin/rcar-vin.h  |  12 +-
>  2 files changed, 254 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
> index fd4478095ac4e5b1..52fad495533bc427 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -27,6 +27,23 @@
>  
>  #include "rcar-vin.h"
>  
> +/*
> + * The companion CSI-2 receiver driver (rcar-csi2) is known
> + * and we know it has one source pad (pad 0) and four sink
> + * pads (pad 1-4). So to translate a pad on the remote
> + * CSI-2 receiver to/from the VIN internal channel number simply
> + * subtract/add one from the pad/channel number.
> + */
> +#define rvin_group_csi_pad_to_channel(pad) ((pad) - 1)
> +#define rvin_group_csi_channel_to_pad(channel) ((channel) + 1)
> +
> +/*
> + * Not all VINs are created equal, master VINs control the
> + * routing for other VIN's. We can figure out which VIN is
> + * master by looking at a VINs id.
> + */
> +#define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4)
> +
>  /* -----------------------------------------------------------------------------
>   * Gen3 CSI2 Group Allocator
>   */
> @@ -409,6 +426,216 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
>  	return 0;
>  }
>  
> +/* -----------------------------------------------------------------------------
> + * Group async notifier
> + */
> +
> +static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
> +{
> +	struct rvin_dev *vin = notifier_to_vin(notifier);
> +	const struct rvin_group_route *route;
> +	unsigned int i;
> +	int ret;
> +
> +	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
> +	if (ret) {
> +		vin_err(vin, "Failed to register subdev nodes\n");
> +		return ret;
> +	}
> +
> +	/* Register all video nodes for the group. */
> +	for (i = 0; i < RCAR_VIN_NUM; i++) {
> +		if (vin->group->vin[i]) {
> +			ret = rvin_v4l2_register(vin->group->vin[i]);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
> +	/* Create all media device links between VINs and CSI-2's. */
> +	mutex_lock(&vin->group->lock);
> +	for (route = vin->info->routes; route->mask; route++) {
> +		struct media_pad *source_pad, *sink_pad;
> +		struct media_entity *source, *sink;
> +		unsigned int source_idx;
> +
> +		/* Check that VIN is part of the group. */
> +		if (!vin->group->vin[route->vin])
> +			continue;
> +
> +		/* Check that VIN' master is part of the group. */
> +		if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
> +			continue;
> +
> +		/* Check that CSI-2 is part of the group. */
> +		if (!vin->group->csi[route->csi].subdev)
> +			continue;
> +
> +		source = &vin->group->csi[route->csi].subdev->entity;
> +		source_idx = rvin_group_csi_channel_to_pad(route->channel);
> +		source_pad = &source->pads[source_idx];
> +
> +		sink = &vin->group->vin[route->vin]->vdev.entity;
> +		sink_pad = &sink->pads[0];
> +
> +		/* Skip if link already exists. */
> +		if (media_entity_find_link(source_pad, sink_pad))
> +			continue;
> +
> +		ret = media_create_pad_link(source, source_idx, sink, 0, 0);
> +		if (ret) {
> +			vin_err(vin, "Error adding link from %s to %s\n",
> +				source->name, sink->name);
> +			break;
> +		}
> +	}
> +	mutex_unlock(&vin->group->lock);
> +
> +	return ret;
> +}
> +
> +static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
> +				     struct v4l2_subdev *subdev,
> +				     struct v4l2_async_subdev *asd)
> +{
> +	struct rvin_dev *vin = notifier_to_vin(notifier);
> +	unsigned int i;
> +
> +	for (i = 0; i < RCAR_VIN_NUM; i++)
> +		if (vin->group->vin[i])
> +			rvin_v4l2_unregister(vin->group->vin[i]);
> +
> +	mutex_lock(&vin->group->lock);
> +
> +	for (i = 0; i < RVIN_CSI_MAX; i++) {
> +		if (vin->group->csi[i].fwnode != asd->match.fwnode)
> +			continue;
> +		vin->group->csi[i].subdev = NULL;
> +		vin_dbg(vin, "Unbind CSI-2 %s from slot %u\n", subdev->name, i);
> +		break;
> +	}
> +
> +	mutex_unlock(&vin->group->lock);
> +}
> +
> +static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
> +				   struct v4l2_subdev *subdev,
> +				   struct v4l2_async_subdev *asd)
> +{
> +	struct rvin_dev *vin = notifier_to_vin(notifier);
> +	unsigned int i;
> +
> +	mutex_lock(&vin->group->lock);
> +
> +	for (i = 0; i < RVIN_CSI_MAX; i++) {
> +		if (vin->group->csi[i].fwnode != asd->match.fwnode)
> +			continue;
> +		vin->group->csi[i].subdev = subdev;
> +		vin_dbg(vin, "Bound CSI-2 %s to slot %u\n", subdev->name, i);
> +		break;
> +	}
> +
> +	mutex_unlock(&vin->group->lock);
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
> +	.bound = rvin_group_notify_bound,
> +	.unbind = rvin_group_notify_unbind,
> +	.complete = rvin_group_notify_complete,
> +};
> +
> +static int rvin_mc_parse_of_endpoint(struct device *dev,
> +				     struct v4l2_fwnode_endpoint *vep,
> +				     struct v4l2_async_subdev *asd)
> +{
> +	struct rvin_dev *vin = dev_get_drvdata(dev);
> +
> +	if (vep->base.port != 1 || vep->base.id >= RVIN_CSI_MAX)
> +		return -EINVAL;
> +
> +	if (!of_device_is_available(to_of_node(asd->match.fwnode))) {
> +
> +		vin_dbg(vin, "OF device %pOF disabled, ignoring\n",
> +			to_of_node(asd->match.fwnode));
> +		return -ENOTCONN;
> +
> +	}
> +
> +	if (vin->group->csi[vep->base.id].fwnode) {
> +		vin_dbg(vin, "OF device %pOF already handled\n",
> +			to_of_node(asd->match.fwnode));
> +		return -ENOTCONN;
> +	}
> +
> +	vin->group->csi[vep->base.id].fwnode = asd->match.fwnode;
> +
> +	vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
> +		to_of_node(asd->match.fwnode), vep->base.id);
> +
> +	return 0;
> +}
> +
> +static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
> +{
> +	unsigned int count = 0;
> +	unsigned int i;
> +	int ret;
> +
> +	mutex_lock(&vin->group->lock);
> +
> +	/* If there already is a notifier something has gone wrong, bail out. */
> +	if (WARN_ON(vin->group->notifier)) {
> +		mutex_unlock(&vin->group->lock);
> +		return -EINVAL;
> +	}
> +
> +	/* If not all VIN's are registered don't register the notifier. */
> +	for (i = 0; i < RCAR_VIN_NUM; i++)
> +		if (vin->group->vin[i])
> +			count++;
> +
> +	if (vin->group->count != count) {
> +		mutex_unlock(&vin->group->lock);
> +		return 0;
> +	}
> +
> +	/*
> +	 * Have all VIN's look for subdevices. Some subdevices will overlap
> +	 * but the parser function can handle it, so each subdevice will
> +	 * only be registered once with the notifier.
> +	 */
> +
> +	vin->group->notifier = &vin->notifier;
> +
> +	for (i = 0; i < RCAR_VIN_NUM; i++) {
> +		if (!vin->group->vin[i])
> +			continue;
> +
> +		ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
> +				vin->group->vin[i]->dev, vin->group->notifier,
> +				sizeof(struct v4l2_async_subdev), 1,
> +				rvin_mc_parse_of_endpoint);
> +		if (ret) {
> +			mutex_unlock(&vin->group->lock);
> +			return ret;
> +		}
> +	}
> +
> +	mutex_unlock(&vin->group->lock);
> +
> +	vin->group->notifier->ops = &rvin_group_notify_ops;
> +
> +	ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
> +	if (ret < 0) {
> +		vin_err(vin, "Notifier registration failed\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  static int rvin_mc_init(struct rvin_dev *vin)
>  {
>  	int ret;
> @@ -422,7 +649,15 @@ static int rvin_mc_init(struct rvin_dev *vin)
>  	if (ret)
>  		return ret;
>  
> -	return rvin_group_get(vin);
> +	ret = rvin_group_get(vin);
> +	if (ret)
> +		return ret;
> +
> +	ret = rvin_mc_parse_of_graph(vin);
> +	if (ret)
> +		rvin_group_put(vin);
> +
> +	return ret;
>  }
>  
>  /* -----------------------------------------------------------------------------
> @@ -542,10 +777,15 @@ static int rcar_vin_remove(struct platform_device *pdev)
>  	v4l2_async_notifier_unregister(&vin->notifier);
>  	v4l2_async_notifier_cleanup(&vin->notifier);
>  
> -	if (vin->info->use_mc)
> +	if (vin->info->use_mc) {
> +		mutex_lock(&vin->group->lock);
> +		if (vin->group->notifier == &vin->notifier)
> +			vin->group->notifier = NULL;
> +		mutex_unlock(&vin->group->lock);
>  		rvin_group_put(vin);
> -	else
> +	} else {
>  		v4l2_ctrl_handler_free(&vin->ctrl_handler);
> +	}
>  
>  	rvin_dma_unregister(vin);
>  
> diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
> index 9a68a5909fe07ec7..631dd382c9ccb114 100644
> --- a/drivers/media/platform/rcar-vin/rcar-vin.h
> +++ b/drivers/media/platform/rcar-vin/rcar-vin.h
> @@ -223,9 +223,13 @@ struct rvin_dev {
>   *
>   * @mdev:		media device which represents the group
>   *
> - * @lock:		protects the count and vin members
> + * @lock:		protects the count, notifier, vin and csi members
>   * @count:		number of enabled VIN instances found in DT
> + * @notifier:		pointer to the notifier of a VIN which handles the
> + *			groups async sub-devices.
>   * @vin:		VIN instances which are part of the group
> + * @csi:		array of pairs of fwnode and subdev pointers
> + *			to all CSI-2 subdevices.
>   */
>  struct rvin_group {
>  	struct kref refcount;
> @@ -234,7 +238,13 @@ struct rvin_group {
>  
>  	struct mutex lock;
>  	unsigned int count;
> +	struct v4l2_async_notifier *notifier;
>  	struct rvin_dev *vin[RCAR_VIN_NUM];
> +
> +	struct {
> +		struct fwnode_handle *fwnode;
> +		struct v4l2_subdev *subdev;
> +	} csi[RVIN_CSI_MAX];
>  };
>  
>  int rvin_dma_register(struct rvin_dev *vin, int irq);
> 

  reply	other threads:[~2018-03-09 15:45 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-07 22:04 [PATCH v12 00/33] rcar-vin: Add Gen3 with media controller Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 01/33] dt-bindings: media: rcar_vin: Reverse SoC part number list Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 02/33] dt-bindings: media: rcar_vin: add device tree support for r8a774[35] Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 03/33] rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 04/33] rcar-vin: rename poorly named initialize and cleanup functions Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 05/33] rcar-vin: unregister video device on driver removal Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 06/33] rcar-vin: move subdevice handling to async callbacks Niklas Söderlund
2018-03-09 15:16   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 07/33] rcar-vin: move model information to own struct Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 08/33] rcar-vin: move max width and height information to chip information Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 09/33] rcar-vin: move functions regarding scaling Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 10/33] rcar-vin: all Gen2 boards can scale simplify logic Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 11/33] rcar-vin: set a default field to fallback on Niklas Söderlund
2018-03-09 15:25   ` Hans Verkuil
2018-03-09 16:17     ` Niklas Söderlund
2018-03-09 16:28       ` Hans Verkuil
2018-03-09 17:07         ` Niklas Söderlund
2018-03-09 17:13           ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 12/33] rcar-vin: fix handling of single field frames (top, bottom and alternate fields) Niklas Söderlund
2018-03-09 15:28   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 13/33] rcar-vin: update bytesperline and sizeimage calculation Niklas Söderlund
2018-03-09 15:29   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 14/33] rcar-vin: align pixelformat check Niklas Söderlund
2018-03-09 15:30   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 15/33] rcar-vin: break out format alignment and checking Niklas Söderlund
2018-03-09 15:30   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 16/33] rcar-vin: simplify how formats are set and reset Niklas Söderlund
2018-03-09 15:34   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 17/33] rcar-vin: cache video standard Niklas Söderlund
2018-03-09 15:39   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 18/33] rcar-vin: move media bus configuration to struct rvin_dev Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 19/33] rcar-vin: enable Gen3 hardware configuration Niklas Söderlund
2018-03-07 22:04 ` [PATCH v12 20/33] rcar-vin: add function to manipulate Gen3 chsel value Niklas Söderlund
2018-03-09 15:40   ` Hans Verkuil
2018-03-07 22:04 ` [PATCH v12 21/33] rcar-vin: add flag to switch to media controller mode Niklas Söderlund
2018-03-07 22:05 ` [PATCH v12 22/33] rcar-vin: use different v4l2 operations in " Niklas Söderlund
2018-03-07 22:05 ` [PATCH v12 23/33] rcar-vin: force default colorspace for media centric mode Niklas Söderlund
2018-03-09 15:41   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 24/33] rcar-vin: prepare for media controller mode initialization Niklas Söderlund
2018-03-07 22:05 ` [PATCH v12 25/33] rcar-vin: add group allocator functions Niklas Söderlund
2018-03-09 15:42   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 26/33] rcar-vin: change name of video device Niklas Söderlund
2018-03-09 15:43   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 27/33] rcar-vin: add chsel information to rvin_info Niklas Söderlund
2018-03-09 15:43   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 28/33] rcar-vin: parse Gen3 OF and setup media graph Niklas Söderlund
2018-03-09 15:45   ` Hans Verkuil [this message]
2018-03-07 22:05 ` [PATCH v12 29/33] rcar-vin: add link notify for Gen3 Niklas Söderlund
2018-03-09 15:46   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 30/33] rcar-vin: extend {start,stop}_streaming to work with media controller Niklas Söderlund
2018-03-09 15:47   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 31/33] rcar-vin: enable support for r8a7795 Niklas Söderlund
2018-03-09 15:47   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 32/33] rcar-vin: enable support for r8a7796 Niklas Söderlund
2018-03-09 15:48   ` Hans Verkuil
2018-03-07 22:05 ` [PATCH v12 33/33] rcar-vin: enable support for r8a77970 Niklas Söderlund
2018-03-09 15:48   ` Hans Verkuil

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=cb19f23a-7bfb-539c-5135-c185d56c78d7@xs4all.nl \
    --to=hverkuil@xs4all.nl \
    --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 \
    --cc=tomoharu.fukawa.eb@renesas.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;
as well as URLs for NNTP newsgroup(s).