All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com,
	Jacopo Mondi <jacopo+renesas@jmondi.org>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	niklas.soderlund+renesas@ragnatech.se,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Hans Verkuil <hverkuil-cisco@xs4all.nl>,
	Kishon Vijay Abraham <kishon@ti.com>,
	satish.nagireddy@getcruise.com, Tomasz Figa <tfiga@chromium.org>
Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Subject: [PATCH v15 11/19] media: subdev: use streams in v4l2_subdev_link_validate()
Date: Mon,  3 Oct 2022 15:18:44 +0300	[thread overview]
Message-ID: <20221003121852.616745-12-tomi.valkeinen@ideasonboard.com> (raw)
In-Reply-To: <20221003121852.616745-1-tomi.valkeinen@ideasonboard.com>

Update v4l2_subdev_link_validate() to use routing and streams for
validation.

Instead of just looking at the format on the pad on both ends of the
link, the routing tables are used to collect all the streams going from
the source to the sink over the link, and the streams' formats on both
ends of the link are verified.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 182 +++++++++++++++++++++++---
 1 file changed, 162 insertions(+), 20 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index be778e619694..1cea6ec750c0 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -1014,7 +1014,7 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);
 
 static int
-v4l2_subdev_link_validate_get_format(struct media_pad *pad,
+v4l2_subdev_link_validate_get_format(struct media_pad *pad, u32 stream,
 				     struct v4l2_subdev_format *fmt)
 {
 	if (is_media_entity_v4l2_subdev(pad->entity)) {
@@ -1023,7 +1023,11 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 
 		fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
 		fmt->pad = pad->index;
-		return v4l2_subdev_call_state_active(sd, pad, get_fmt, fmt);
+		fmt->stream = stream;
+
+		return v4l2_subdev_call(sd, pad, get_fmt,
+					v4l2_subdev_get_locked_active_state(sd),
+					fmt);
 	}
 
 	WARN(pad->entity->function != MEDIA_ENT_F_IO_V4L,
@@ -1033,31 +1037,169 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 	return -EINVAL;
 }
 
+#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
+
+static void __v4l2_link_validate_get_streams(struct media_pad *pad,
+					     u64 *streams_mask)
+{
+	struct v4l2_subdev_route *route;
+	struct v4l2_subdev_state *state;
+	struct v4l2_subdev *subdev;
+
+	subdev = media_entity_to_v4l2_subdev(pad->entity);
+
+	*streams_mask = 0;
+
+	state = v4l2_subdev_get_locked_active_state(subdev);
+	if (WARN_ON(!state))
+		return;
+
+	for_each_active_route(&state->routing, route) {
+		u32 route_pad;
+		u32 route_stream;
+
+		if (pad->flags & MEDIA_PAD_FL_SOURCE) {
+			route_pad = route->source_pad;
+			route_stream = route->source_stream;
+		} else {
+			route_pad = route->sink_pad;
+			route_stream = route->sink_stream;
+		}
+
+		if (route_pad != pad->index)
+			continue;
+
+		*streams_mask |= BIT_ULL(route_stream);
+	}
+}
+
+#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
+
+static void v4l2_link_validate_get_streams(struct media_pad *pad,
+					   u64 *streams_mask)
+{
+	struct v4l2_subdev *subdev = media_entity_to_v4l2_subdev(pad->entity);
+
+	if (!(subdev->flags & V4L2_SUBDEV_FL_STREAMS)) {
+		/* Non-streams subdevs have an implicit stream 0 */
+		*streams_mask = BIT_ULL(0);
+		return;
+	}
+
+#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
+	__v4l2_link_validate_get_streams(pad, streams_mask);
+#else
+	/* This shouldn't happen */
+	*streams_mask = 0;
+#endif
+}
+
+static int v4l2_subdev_link_validate_locked(struct media_link *link)
+{
+	struct v4l2_subdev *sink_subdev =
+		media_entity_to_v4l2_subdev(link->sink->entity);
+	struct device *dev = sink_subdev->entity.graph_obj.mdev->dev;
+	u64 source_streams_mask;
+	u64 sink_streams_mask;
+	u64 dangling_sink_streams;
+	u32 stream;
+	int ret;
+
+	dev_dbg(dev, "validating link \"%s\":%u -> \"%s\":%u\n",
+		link->source->entity->name, link->source->index,
+		link->sink->entity->name, link->sink->index);
+
+	v4l2_link_validate_get_streams(link->source, &source_streams_mask);
+	v4l2_link_validate_get_streams(link->sink, &sink_streams_mask);
+
+	/*
+	 * It is ok to have more source streams than sink streams as extra
+	 * source streams can just be ignored by the receiver, but having extra
+	 * sink streams is an error as streams must have a source.
+	 */
+	dangling_sink_streams = (source_streams_mask ^ sink_streams_mask) &
+				sink_streams_mask;
+	if (dangling_sink_streams) {
+		dev_err(dev, "Dangling sink streams: mask %#llx\n",
+			dangling_sink_streams);
+		return -EINVAL;
+	}
+
+	/* Validate source and sink stream formats */
+
+	for_each_set_bit(stream, (void *)&sink_streams_mask, 64) {
+		struct v4l2_subdev_format sink_fmt, source_fmt;
+
+		dev_dbg(dev, "validating stream \"%s\":%u:%u -> \"%s\":%u:%u\n",
+			link->source->entity->name, link->source->index, stream,
+			link->sink->entity->name, link->sink->index, stream);
+
+		ret = v4l2_subdev_link_validate_get_format(link->source, stream,
+							   &source_fmt);
+		if (ret < 0) {
+			dev_dbg(dev,
+				"Failed to get format for \"%s\":%u:%u (but that's ok)\n",
+				link->source->entity->name, link->source->index,
+				stream);
+			continue;
+		}
+
+		ret = v4l2_subdev_link_validate_get_format(link->sink, stream,
+							   &sink_fmt);
+		if (ret < 0) {
+			dev_dbg(dev,
+				"Failed to get format for \"%s\":%u:%u (but that's ok)\n",
+				link->sink->entity->name, link->sink->index,
+				stream);
+			continue;
+		}
+
+		/* TODO: add stream number to link_validate() */
+		ret = v4l2_subdev_call(sink_subdev, pad, link_validate, link,
+				       &source_fmt, &sink_fmt);
+		if (!ret)
+			continue;
+
+		if (ret != -ENOIOCTLCMD)
+			return ret;
+
+		ret = v4l2_subdev_link_validate_default(sink_subdev, link,
+							&source_fmt, &sink_fmt);
+
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 int v4l2_subdev_link_validate(struct media_link *link)
 {
-	struct v4l2_subdev *sink;
-	struct v4l2_subdev_format sink_fmt, source_fmt;
-	int rval;
+	struct v4l2_subdev *source_sd, *sink_sd;
+	struct v4l2_subdev_state *source_state, *sink_state;
+	int ret;
 
-	rval = v4l2_subdev_link_validate_get_format(
-		link->source, &source_fmt);
-	if (rval < 0)
-		return 0;
+	sink_sd = media_entity_to_v4l2_subdev(link->sink->entity);
+	source_sd = media_entity_to_v4l2_subdev(link->source->entity);
 
-	rval = v4l2_subdev_link_validate_get_format(
-		link->sink, &sink_fmt);
-	if (rval < 0)
-		return 0;
+	sink_state = v4l2_subdev_get_unlocked_active_state(sink_sd);
+	source_state = v4l2_subdev_get_unlocked_active_state(source_sd);
 
-	sink = media_entity_to_v4l2_subdev(link->sink->entity);
+	if (sink_state)
+		v4l2_subdev_lock_state(sink_state);
 
-	rval = v4l2_subdev_call(sink, pad, link_validate, link,
-				&source_fmt, &sink_fmt);
-	if (rval != -ENOIOCTLCMD)
-		return rval;
+	if (source_state)
+		v4l2_subdev_lock_state(source_state);
 
-	return v4l2_subdev_link_validate_default(
-		sink, link, &source_fmt, &sink_fmt);
+	ret = v4l2_subdev_link_validate_locked(link);
+
+	if (sink_state)
+		v4l2_subdev_unlock_state(sink_state);
+
+	if (source_state)
+		v4l2_subdev_unlock_state(source_state);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate);
 
-- 
2.34.1


  parent reply	other threads:[~2022-10-03 12:19 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-03 12:18 [PATCH v15 00/19] v4l: routing and streams support Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 01/19] media: v4l2-subdev: Sort includes Tomi Valkeinen
2022-10-03 16:53   ` Laurent Pinchart
2022-10-03 12:18 ` [PATCH v15 02/19] media: add V4L2_SUBDEV_FL_STREAMS Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 03/19] media: add V4L2_SUBDEV_CAP_STREAMS Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 04/19] media: Documentation: Add GS_ROUTING documentation Tomi Valkeinen
2022-10-03 14:31   ` Hans Verkuil
2022-10-12 10:01     ` Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 05/19] media: subdev: Add [GS]_ROUTING subdev ioctls and operations Tomi Valkeinen
2022-10-03 14:26   ` Hans Verkuil
2022-10-03 22:01     ` Sakari Ailus
2022-10-04  8:43       ` Hans Verkuil
2022-10-04 10:05         ` Sakari Ailus
2022-10-12  8:15           ` Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 06/19] media: subdev: add v4l2_subdev_has_pad_interdep() Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 07/19] media: subdev: add v4l2_subdev_set_routing helper() Tomi Valkeinen
2022-10-12  6:22   ` Yunke Cao
2022-10-12  6:58     ` Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 08/19] media: subdev: Add for_each_active_route() macro Tomi Valkeinen
2022-10-09  5:38   ` Dafna Hirschfeld
2022-10-12  6:15     ` Tomi Valkeinen
2022-10-13  7:41       ` Sakari Ailus
2022-10-03 12:18 ` [PATCH v15 09/19] media: Documentation: add multiplexed streams documentation Tomi Valkeinen
2022-10-11 10:47   ` [PATCH 1/1] media: Documentation: Interaction between routes, formats and selections Sakari Ailus
2022-10-12 10:30     ` Tomi Valkeinen
2022-12-07 10:38       ` Sakari Ailus
2022-10-03 12:18 ` [PATCH v15 10/19] media: subdev: add stream based configuration Tomi Valkeinen
2022-10-09  6:24   ` Dafna Hirschfeld
2022-10-12  6:36     ` Tomi Valkeinen
2022-10-03 12:18 ` Tomi Valkeinen [this message]
2022-10-14 10:54   ` [PATCH v15 11/19] media: subdev: use streams in v4l2_subdev_link_validate() Sakari Ailus
2022-10-14 11:10     ` Tomi Valkeinen
2022-10-16 22:37       ` Sakari Ailus
2022-10-27 10:43         ` Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 12/19] media: subdev: add "opposite" stream helper funcs Tomi Valkeinen
2022-10-09  7:06   ` Dafna Hirschfeld
2022-10-12  6:46     ` Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 13/19] media: subdev: add streams to v4l2_subdev_get_fmt() helper function Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 14/19] media: subdev: add v4l2_subdev_set_routing_with_fmt() helper Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 15/19] media: subdev: add v4l2_subdev_routing_validate() helper Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 16/19] media: v4l2-subdev: Add v4l2_subdev_state_xlate_streams() helper Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 17/19] media: v4l2-subdev: Add subdev .(enable|disable)_streams() operations Tomi Valkeinen
2022-10-10 16:53   ` Dafna Hirschfeld
2022-10-12  5:59     ` Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 18/19] media: v4l2-subdev: Add v4l2_subdev_s_stream_helper() function Tomi Valkeinen
2022-10-03 12:18 ` [PATCH v15 19/19] media: Add stream to frame descriptor Tomi Valkeinen

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=20221003121852.616745-12-tomi.valkeinen@ideasonboard.com \
    --to=tomi.valkeinen@ideasonboard.com \
    --cc=hverkuil-cisco@xs4all.nl \
    --cc=jacopo+renesas@jmondi.org \
    --cc=kishon@ti.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=niklas.soderlund+renesas@ragnatech.se \
    --cc=sakari.ailus@linux.intel.com \
    --cc=satish.nagireddy@getcruise.com \
    --cc=tfiga@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.