Commit a1299df6 authored by Tomi Valkeinen's avatar Tomi Valkeinen Committed by Mauro Carvalho Chehab

media: subdev: Add V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING

A common case with subdev routing is that on the subdevice just before
the DMA engines (video nodes), no multiplexing is allowed on the source
pads, as the DMA engine can only handle a single stream.

In some other situations one might also want to do the same check on the
sink side.

Add new routing validation flags to check these:
V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING and
V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING.
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: default avatarJacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 698a619a
...@@ -1708,7 +1708,8 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd, ...@@ -1708,7 +1708,8 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
unsigned int i, j; unsigned int i, j;
int ret = -EINVAL; int ret = -EINVAL;
if (disallow & V4L2_SUBDEV_ROUTING_NO_STREAM_MIX) { if (disallow & (V4L2_SUBDEV_ROUTING_NO_STREAM_MIX |
V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING)) {
remote_pads = kcalloc(sd->entity.num_pads, sizeof(*remote_pads), remote_pads = kcalloc(sd->entity.num_pads, sizeof(*remote_pads),
GFP_KERNEL); GFP_KERNEL);
if (!remote_pads) if (!remote_pads)
...@@ -1748,8 +1749,6 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd, ...@@ -1748,8 +1749,6 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
i, "sink"); i, "sink");
goto out; goto out;
} }
remote_pads[route->sink_pad] = route->source_pad;
} }
/* /*
...@@ -1764,7 +1763,38 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd, ...@@ -1764,7 +1763,38 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
i, "source"); i, "source");
goto out; goto out;
} }
}
/*
* V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING: Pads on the sink
* side can not do stream multiplexing, i.e. there can be only
* a single stream in a sink pad.
*/
if (disallow & V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING) {
if (remote_pads[route->sink_pad] != U32_MAX) {
dev_dbg(sd->dev,
"route %u attempts to multiplex on %s pad %u\n",
i, "sink", route->sink_pad);
goto out;
}
}
/*
* V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING: Pads on the
* source side can not do stream multiplexing, i.e. there can
* be only a single stream in a source pad.
*/
if (disallow & V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING) {
if (remote_pads[route->source_pad] != U32_MAX) {
dev_dbg(sd->dev,
"route %u attempts to multiplex on %s pad %u\n",
i, "source", route->source_pad);
goto out;
}
}
if (remote_pads) {
remote_pads[route->sink_pad] = route->source_pad;
remote_pads[route->source_pad] = route->sink_pad; remote_pads[route->source_pad] = route->sink_pad;
} }
......
...@@ -1651,6 +1651,10 @@ u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state, ...@@ -1651,6 +1651,10 @@ u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state,
* all streams from a sink pad must be routed to a single source pad * all streams from a sink pad must be routed to a single source pad
* @V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX: * @V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX:
* all streams on a source pad must originate from a single sink pad * all streams on a source pad must originate from a single sink pad
* @V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING:
* source pads shall not contain multiplexed streams
* @V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING:
* sink pads shall not contain multiplexed streams
* @V4L2_SUBDEV_ROUTING_ONLY_1_TO_1: * @V4L2_SUBDEV_ROUTING_ONLY_1_TO_1:
* only non-overlapping 1-to-1 stream routing is allowed (a combination of * only non-overlapping 1-to-1 stream routing is allowed (a combination of
* @V4L2_SUBDEV_ROUTING_NO_1_TO_N and @V4L2_SUBDEV_ROUTING_NO_N_TO_1) * @V4L2_SUBDEV_ROUTING_NO_1_TO_N and @V4L2_SUBDEV_ROUTING_NO_N_TO_1)
...@@ -1659,18 +1663,25 @@ u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state, ...@@ -1659,18 +1663,25 @@ u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state,
* that source pad shall not get routes from any other sink pad * that source pad shall not get routes from any other sink pad
* (a combination of @V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX and * (a combination of @V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX and
* @V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX) * @V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX)
* @V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING:
* no multiplexed streams allowed on either source or sink sides.
*/ */
enum v4l2_subdev_routing_restriction { enum v4l2_subdev_routing_restriction {
V4L2_SUBDEV_ROUTING_NO_1_TO_N = BIT(0), V4L2_SUBDEV_ROUTING_NO_1_TO_N = BIT(0),
V4L2_SUBDEV_ROUTING_NO_N_TO_1 = BIT(1), V4L2_SUBDEV_ROUTING_NO_N_TO_1 = BIT(1),
V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX = BIT(2), V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX = BIT(2),
V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX = BIT(3), V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX = BIT(3),
V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING = BIT(4),
V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING = BIT(5),
V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 = V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 =
V4L2_SUBDEV_ROUTING_NO_1_TO_N | V4L2_SUBDEV_ROUTING_NO_1_TO_N |
V4L2_SUBDEV_ROUTING_NO_N_TO_1, V4L2_SUBDEV_ROUTING_NO_N_TO_1,
V4L2_SUBDEV_ROUTING_NO_STREAM_MIX = V4L2_SUBDEV_ROUTING_NO_STREAM_MIX =
V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX | V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX |
V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX, V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX,
V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING =
V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING |
V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING,
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment