Commit 89013969 authored by Milen Mitkov's avatar Milen Mitkov Committed by Hans Verkuil

media: camss: sm8250: Pipeline starting and stopping for multiple virtual channels

Use the multistream series function video_device_pipeline_alloc_start
to allows multiple clients of the same pipeline.

If the VFE entity is used by another instance of the pipeline,
the pipeline won't be stopped. This allows for stopping and starting
streams at any point without disrupting the other running streams.

To prepare and start multiple virtual channels each CSID source pad
corresponding to a virtual channel must be linked to the corresponding
IFE entity. CSID pad 1 (1st source pad) corresponds to virtual
channel 0, CSID pad 2 corresponds to virtual channel 1 and so on.
Each of these must be linked to corresponding IFE RDI port.
E.g. to enable vc 0 on CSID0:

media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'

To enable vc1 on CSID0:

media-ctl -l '"msm_csid0":2->"msm_vfe0_rdi1":0[1]'

And so on. Note that on SM8250 each CSID is connected, at the
hardware level, to only one IFE. Thus, you must link CSID0
with IFE0, you can't link it with IFE1.

Example: the following media controller setup expects multiplexed
sensor data on CSIPHY2. Data will be passed on to CSID0, which will
demux it to 2 streams - for RDI0 and RD1 ports of IFE0:

media-ctl -v -d /dev/media0 -V '"imx577 '22-001a'":0[fmt:SRGGB10/3840x2160 field:none]'
media-ctl -V '"msm_csiphy2":0[fmt:SRGGB10/3840x2160]'
media-ctl -V '"msm_csid0":0[fmt:SRGGB10/3840x2160]'
media-ctl -V '"msm_csid0":1[fmt:SRGGB10/3840x2160]'
media-ctl -V '"msm_csid0":2[fmt:SRGGB10/3840x2160]'
media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/3840x2160]'
media-ctl -V '"msm_vfe0_rdi1":0[fmt:SRGGB10/3840x2160]'
media-ctl -l '"msm_csiphy2":1->"msm_csid0":0[1]'
media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
media-ctl -l '"msm_csid0":2->"msm_vfe0_rdi1":0[1]'

Note: CSID's entity pad 0 is a sink pad, pads 1..4 are source pads
To start streaming a v4l2 client must open the corresponding
/dev/videoN node. For example, with yavta:

yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 3840x2160 -F /dev/video0
yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 3840x2160 -F /dev/video1

Note that IFEs (vfe0, vfe1) on SM8250 have 3 RDI ports and a single
PIX port and IFELites (vfe2, vfe3) have 4 RDI ports and no PIX port.
Signed-off-by: default avatarMilen Mitkov <quic_mmitkov@quicinc.com>
Reviewed-by: default avatarRobert Foss <robert.foss@linaro.org>
Tested-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: default avatarRobert Foss <robert.foss@linaro.org>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 1c4abf02
...@@ -351,6 +351,7 @@ static int video_get_subdev_format(struct camss_video *video, ...@@ -351,6 +351,7 @@ static int video_get_subdev_format(struct camss_video *video,
if (subdev == NULL) if (subdev == NULL)
return -EPIPE; return -EPIPE;
memset(&fmt, 0, sizeof(fmt));
fmt.pad = pad; fmt.pad = pad;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
...@@ -493,9 +494,11 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count) ...@@ -493,9 +494,11 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
struct v4l2_subdev *subdev; struct v4l2_subdev *subdev;
int ret; int ret;
ret = video_device_pipeline_start(vdev, &video->pipe); ret = video_device_pipeline_alloc_start(vdev);
if (ret < 0) if (ret < 0) {
dev_err(video->camss->dev, "Failed to start media pipeline: %d\n", ret);
goto flush_buffers; goto flush_buffers;
}
ret = video_check_format(video); ret = video_check_format(video);
if (ret < 0) if (ret < 0)
...@@ -537,6 +540,7 @@ static void video_stop_streaming(struct vb2_queue *q) ...@@ -537,6 +540,7 @@ static void video_stop_streaming(struct vb2_queue *q)
struct media_entity *entity; struct media_entity *entity;
struct media_pad *pad; struct media_pad *pad;
struct v4l2_subdev *subdev; struct v4l2_subdev *subdev;
int ret;
entity = &vdev->entity; entity = &vdev->entity;
while (1) { while (1) {
...@@ -551,7 +555,18 @@ static void video_stop_streaming(struct vb2_queue *q) ...@@ -551,7 +555,18 @@ static void video_stop_streaming(struct vb2_queue *q)
entity = pad->entity; entity = pad->entity;
subdev = media_entity_to_v4l2_subdev(entity); subdev = media_entity_to_v4l2_subdev(entity);
v4l2_subdev_call(subdev, video, s_stream, 0); ret = v4l2_subdev_call(subdev, video, s_stream, 0);
if (entity->use_count > 1) {
/* Don't stop if other instances of the pipeline are still running */
dev_dbg(video->camss->dev, "Video pipeline still used, don't stop streaming.\n");
return;
}
if (ret) {
dev_err(video->camss->dev, "Video pipeline stop failed: %d\n", ret);
return;
}
} }
video_device_pipeline_stop(vdev); video_device_pipeline_stop(vdev);
......
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