Thread (8 messages) 8 messages, 2 authors, 2015-03-04

Re: [PATCH v5 6/8] v4l: xilinx: Add Xilinx Video IP core

From: Hans Verkuil <hidden>
Date: 2015-03-04 09:30:40
Also in: linux-media

On 03/03/15 23:15, Laurent Pinchart wrote:
Hi Hans,

Thank you for the review.

On Tuesday 03 March 2015 12:28:24 Hans Verkuil wrote:
quoted
Hi Laurent,

Thanks for this patch. I do have a few comments, see below. Note that I am
OK with the new DT format description.

On 03/02/2015 02:48 AM, Laurent Pinchart wrote:
quoted
Xilinx platforms have no hardwired video capture or video processing
interface. Users create capture and memory to memory processing
pipelines in the FPGA fabric to suit their particular needs, by
instantiating video IP cores from a large library.

The Xilinx Video IP core is a framework that models a video pipeline
described in the device tree and expose the pipeline to userspace
through the media controller and V4L2 APIs.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hyun Kwon <redacted>
Signed-off-by: Radhey Shyam Pandey <redacted>
Signed-off-by: Michal Simek <redacted>

---
<snip>
quoted
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c
b/drivers/media/platform/xilinx/xilinx-dma.c new file mode 100644
index 0000000..afed6c3
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -0,0 +1,753 @@
[snip]
quoted
quoted
+static void xvip_dma_complete(void *param)
+{
+	struct xvip_dma_buffer *buf = param;
+	struct xvip_dma *dma = buf->dma;
+
+	spin_lock(&dma->queued_lock);
+	list_del(&buf->queue);
+	spin_unlock(&dma->queued_lock);
+
+	buf->buf.v4l2_buf.sequence = dma->sequence++;
buf->buf.v4l2_buf.field isn't set. I think you only support progressive
formats at the moment, so this should be set to V4L2_FIELD_NONE.
Agreed, that was an oversight. I'll fix it.
quoted
quoted
+	v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp);
+	vb2_set_plane_payload(&buf->buf, 0, dma->format.sizeimage);
+	vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
+}
+
+static int
+xvip_dma_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+		     unsigned int *nbuffers, unsigned int *nplanes,
+		     unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+
+	*nplanes = 1;
+
+	sizes[0] = dma->format.sizeimage;
I would suggest that you add support for vb2_ioctl_create_bufs by changing
this code to:

	if (fmt && fmt->fmt.pix.sizeimage < dma->format.sizeimage)
                return -EINVAL;
	sizes[0] = fmt ? fmt->fmt.pix.sizeimage : dma->format.sizeimage;
Looks good, I'll fix that.
quoted
quoted
+	alloc_ctxs[0] = dma->alloc_ctx;
+
+	return 0;
+}
[snip]
quoted
quoted
+static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int
count) +{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+	struct xvip_dma_buffer *buf, *nbuf;
+	struct xvip_pipeline *pipe;
+	int ret;
+
+	dma->sequence = 0;
+
+	/*
+	 * Start streaming on the pipeline. No link touching an entity in the
+	 * pipeline can be activated or deactivated once streaming is 
started.
quoted
quoted
+	 *
+	 * Use the pipeline object embedded in the first DMA object that 
starts
quoted
quoted
+	 * streaming.
+	 */
+	pipe = dma->video.entity.pipe
+	     ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe;
+
+	ret = media_entity_pipeline_start(&dma->video.entity, &pipe->pipe);
+	if (ret < 0)
+		goto error;
+
+	/* Verify that the configured format matches the output of the
+	 * connected subdev.
+	 */
+	ret = xvip_dma_verify_format(dma);
+	if (ret < 0)
+		goto error_stop;
+
+	ret = xvip_pipeline_prepare(pipe, dma);
+	if (ret < 0)
+		goto error_stop;
+
+	/* Start the DMA engine. This must be done before starting the blocks
+	 * in the pipeline to avoid DMA synchronization issues.
+	 */
+	dma_async_issue_pending(dma->dma);
Question: can the DMA engine be started without any buffers queued?
Yes. In that case the dma_async_issue_pending() call will be a no-op, as there 
will be no pending DMA transfer queued.
quoted
The vb2_queue struct has a min_buffers_needed field that can be set to a
non-zero value. In that case start_streaming won't be called until at least
that many buffers have been queued. Many DMA engines need that so this was
added to the vb2 core to avoid having to hack around this in the driver.
I don't see a need for that here. I actually think the min_buffers_needed 
field shouldn't be set, even if it could be set to 1, to avoid reporting 
VIDIOC_STREAMON errors at VIDIOC_QBUF time. The alternative would be to move 
the validation code to a custom .video_streamon handler, but that seems 
pointless to me.
Would it make sense to add a validate_streamon op to vb2? For devices like
this that need to validate the pipeline it makes sense that the validation
happens on VIDIOC_STREAMON. The actual DMA engine start stays with the
start_streaming op.

It would be easy to add to vb2.
quoted
quoted
+
+	/* Start the pipeline. */
+	xvip_pipeline_set_stream(pipe, true);
+
+	return 0;
+
+error_stop:
+	media_entity_pipeline_stop(&dma->video.entity);
+
+error:
+	/* Give back all queued buffers to videobuf2. */
+	spin_lock_irq(&dma->queued_lock);
+	list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) {
+		vb2_buffer_done(&buf->buf, VB2_BUF_STATE_QUEUED);
+		list_del(&buf->queue);
+	}
+	spin_unlock_irq(&dma->queued_lock);
+
+	return ret;
+}
[snip]
quoted
quoted
+/* ----------------------------------------------------------------------
+ * V4L2 file operations
+ */
+
+static const struct v4l2_file_operations xvip_dma_fops = {
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl	= video_ioctl2,
+	.open		= v4l2_fh_open,
+	.release	= vb2_fop_release,
+	.poll		= vb2_fop_poll,
+	.mmap		= vb2_fop_mmap,
I would also add:

	.read = vb2_fop_read,
	.write = vb2_fop_write,

and add VB2_READ or VB2_WRITE to dma->queue.io_modes.

You get it for free, it doesn't take any additional resources, so why not?
My usual comment : because I'd rather not have users using the read() API with 
this driver :-) The usual argument of "but then it would be easy to just cat 
/dev/video? to check whether the device works" doesn't apply here as the 
pipeline needs to be configured from userspace through V4L2 subdev pad ops 
anyway, so users can as well use a proper V4L2 command line test tool.
Good point. But perhaps it is a good idea to add a comment why VB2_READ/WRITE
isn't supported, if only to prevent me from asking this again in the future :-)
quoted
However, to make that work correctly you need this patch:

https://patchwork.linuxtv.org/patch/28478/

It would make sense if you just add that patch to your xilinx tree.
I'll take this patch. It's still useful, but not for this driver.

Regards,

	Hans
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help