From: Laurent Pinchart Date: Mon, 28 Jul 2025 23:50:09 +0000 (+0300) Subject: media: staging/ipu7: Disallow source multiplexing X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=49cec2b5a316ce2669e17ce1d458a8dfc1157f09;p=users%2Fhch%2Fmisc.git media: staging/ipu7: Disallow source multiplexing The IPU7 ISYS driver can't capture multiple streams on the same video device. Disallow source multiplexing in the routes of the internal subdev to reflect that limitation. As a result we can hardcode the source stream to 0, simplifying the driver. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- diff --git a/drivers/staging/media/ipu7/ipu7-isys-queue.c b/drivers/staging/media/ipu7/ipu7-isys-queue.c index 7046c29141f8..434d9d9c7158 100644 --- a/drivers/staging/media/ipu7/ipu7-isys-queue.c +++ b/drivers/staging/media/ipu7/ipu7-isys-queue.c @@ -442,14 +442,13 @@ static int ipu7_isys_link_fmt_validate(struct ipu7_isys_queue *aq) media_pad_remote_pad_first(av->vdev.entity.pads); struct v4l2_mbus_framefmt format; struct v4l2_subdev *sd; - u32 r_stream, code; + u32 r_stream = 0, code; int ret; if (!remote_pad) return -ENOTCONN; sd = media_entity_to_v4l2_subdev(remote_pad->entity); - r_stream = ipu7_isys_get_src_stream_by_src_pad(sd, remote_pad->index); ret = ipu7_isys_get_stream_pad_fmt(sd, remote_pad->index, r_stream, &format); diff --git a/drivers/staging/media/ipu7/ipu7-isys-subdev.c b/drivers/staging/media/ipu7/ipu7-isys-subdev.c index 98b6ef6a2f21..67a776033d5b 100644 --- a/drivers/staging/media/ipu7/ipu7-isys-subdev.c +++ b/drivers/staging/media/ipu7/ipu7-isys-subdev.c @@ -194,13 +194,22 @@ static int subdev_set_routing(struct v4l2_subdev *sd, .code = MEDIA_BUS_FMT_SGRBG10_1X10, .field = V4L2_FIELD_NONE, }; + struct v4l2_subdev_route *route; int ret; ret = v4l2_subdev_routing_validate(sd, routing, - V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); + V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 | + V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING); if (ret) return ret; + /* + * The device doesn't support source multiplexing, set all source + * streams to 0 to simplify stream handling through the driver. + */ + for_each_active_route(routing, route) + route->source_stream = 0; + return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &fmt); } @@ -222,30 +231,6 @@ int ipu7_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream, return fmt ? 0 : -EINVAL; } -u32 ipu7_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad) -{ - struct v4l2_subdev_state *state; - struct v4l2_subdev_route *routes; - u32 source_stream = 0; - unsigned int i; - - state = v4l2_subdev_lock_and_get_active_state(sd); - if (!state) - return 0; - - routes = state->routing.routes; - for (i = 0; i < state->routing.num_routes; i++) { - if (routes[i].source_pad == pad) { - source_stream = routes[i].source_stream; - break; - } - } - - v4l2_subdev_unlock_state(state); - - return source_stream; -} - static int ipu7_isys_subdev_init_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *state) { diff --git a/drivers/staging/media/ipu7/ipu7-isys-subdev.h b/drivers/staging/media/ipu7/ipu7-isys-subdev.h index 1057ec39ae39..faa50031cf24 100644 --- a/drivers/staging/media/ipu7/ipu7-isys-subdev.h +++ b/drivers/staging/media/ipu7/ipu7-isys-subdev.h @@ -37,7 +37,6 @@ int ipu7_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_mbus_code_enum *code); -u32 ipu7_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad); int ipu7_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream, struct v4l2_mbus_framefmt *format); int ipu7_isys_subdev_set_routing(struct v4l2_subdev *sd, diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.c b/drivers/staging/media/ipu7/ipu7-isys-video.c index 6b31c766bc58..75edd121b0bf 100644 --- a/drivers/staging/media/ipu7/ipu7-isys-video.c +++ b/drivers/staging/media/ipu7/ipu7-isys-video.c @@ -291,7 +291,7 @@ static int link_validate(struct media_link *link) struct v4l2_mbus_framefmt *s_fmt; struct v4l2_subdev *s_sd; struct media_pad *s_pad; - u32 s_stream, code; + u32 s_stream = 0, code; int ret = -EPIPE; if (!link->source->entity) @@ -307,7 +307,6 @@ static int link_validate(struct media_link *link) link->sink->entity->name); s_pad = media_pad_remote_pad_first(&av->pad); - s_stream = ipu7_isys_get_src_stream_by_src_pad(s_sd, s_pad->index); v4l2_subdev_lock_state(s_state); @@ -370,10 +369,9 @@ static int ipu7_isys_fw_pin_cfg(struct ipu7_isys_video *av, struct device *dev = &isys->adev->auxdev.dev; struct v4l2_mbus_framefmt fmt; int output_pins; - u32 src_stream; + u32 src_stream = 0; int ret; - src_stream = ipu7_isys_get_src_stream_by_src_pad(sd, src_pad->index); ret = ipu7_isys_get_stream_pad_fmt(sd, src_pad->index, src_stream, &fmt); if (ret < 0) { @@ -781,32 +779,6 @@ ipu7_isys_query_stream_by_source(struct ipu7_isys *isys, int source, u8 vc) return stream; } -static u32 get_remote_pad_stream(struct media_pad *r_pad) -{ - struct v4l2_subdev_state *state; - struct v4l2_subdev *sd; - u32 stream_id = 0; - unsigned int i; - - sd = media_entity_to_v4l2_subdev(r_pad->entity); - state = v4l2_subdev_lock_and_get_active_state(sd); - if (!state) - return 0; - - for (i = 0; i < state->stream_configs.num_configs; i++) { - struct v4l2_subdev_stream_config *cfg = - &state->stream_configs.configs[i]; - if (cfg->pad == r_pad->index) { - stream_id = cfg->stream; - break; - } - } - - v4l2_subdev_unlock_state(state); - - return stream_id; -} - int ipu7_isys_video_set_streaming(struct ipu7_isys_video *av, int state, struct ipu7_isys_buffer_list *bl) { @@ -814,7 +786,7 @@ int ipu7_isys_video_set_streaming(struct ipu7_isys_video *av, int state, struct device *dev = &av->isys->adev->auxdev.dev; struct media_pad *r_pad; struct v4l2_subdev *sd; - u32 r_stream; + u32 r_stream = 0; int ret = 0; dev_dbg(dev, "set stream: %d\n", state); @@ -824,7 +796,6 @@ int ipu7_isys_video_set_streaming(struct ipu7_isys_video *av, int state, sd = &stream->asd->sd; r_pad = media_pad_remote_pad_first(&av->pad); - r_stream = get_remote_pad_stream(r_pad); if (!state) { stop_streaming_firmware(av);