Lines Matching full:dma
3 * Xilinx Video DMA
12 #include <linux/dma/xilinx_dma.h>
23 #include <media/videobuf2-dma-contig.h>
25 #include "xilinx-dma.h"
57 static int xvip_dma_verify_format(struct xvip_dma *dma) in xvip_dma_verify_format() argument
63 subdev = xvip_dma_remote_subdev(&dma->pad, &fmt.pad); in xvip_dma_verify_format()
72 if (dma->fmtinfo->code != fmt.format.code || in xvip_dma_verify_format()
73 dma->format.height != fmt.format.height || in xvip_dma_verify_format()
74 dma->format.width != fmt.format.width || in xvip_dma_verify_format()
75 dma->format.colorspace != fmt.format.colorspace) in xvip_dma_verify_format()
98 struct xvip_dma *dma = pipe->output; in xvip_pipeline_start_stop() local
104 entity = &dma->video.entity; in xvip_pipeline_start_stop()
130 * The pipeline is shared between all DMA engines connect at its input and
131 * output. While the stream state of DMA engines can be controlled
134 * counter that tracks the number of DMA engines that have requested the stream
139 * DMA engines in the pipeline it will enable all entities that belong to the
195 struct xvip_dma *dma; in xvip_pipeline_validate() local
200 dma = to_xvip_dma(media_entity_to_video_device(entity)); in xvip_pipeline_validate()
202 if (dma->pad.flags & MEDIA_PAD_FL_SINK) { in xvip_pipeline_validate()
203 pipe->output = dma; in xvip_pipeline_validate()
249 * @dma: DMA engine at one end of the pipeline
257 struct xvip_dma *dma) in xvip_pipeline_prepare() argument
265 ret = xvip_pipeline_validate(pipe, dma); in xvip_pipeline_prepare()
285 * struct xvip_dma_buffer - Video DMA buffer
287 * @queue: buffer list entry in the DMA engine queued buffers list
288 * @dma: DMA channel that uses the buffer
293 struct xvip_dma *dma; member
301 struct xvip_dma *dma = buf->dma; in xvip_dma_complete() local
303 spin_lock(&dma->queued_lock); in xvip_dma_complete()
305 spin_unlock(&dma->queued_lock); in xvip_dma_complete()
308 buf->buf.sequence = dma->sequence++; in xvip_dma_complete()
310 vb2_set_plane_payload(&buf->buf.vb2_buf, 0, dma->format.sizeimage); in xvip_dma_complete()
319 struct xvip_dma *dma = vb2_get_drv_priv(vq); in xvip_dma_queue_setup() local
323 return sizes[0] < dma->format.sizeimage ? -EINVAL : 0; in xvip_dma_queue_setup()
326 sizes[0] = dma->format.sizeimage; in xvip_dma_queue_setup()
334 struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue); in xvip_dma_buffer_prepare() local
337 buf->dma = dma; in xvip_dma_buffer_prepare()
345 struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue); in xvip_dma_buffer_queue() local
351 if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { in xvip_dma_buffer_queue()
353 dma->xt.dir = DMA_DEV_TO_MEM; in xvip_dma_buffer_queue()
354 dma->xt.src_sgl = false; in xvip_dma_buffer_queue()
355 dma->xt.dst_sgl = true; in xvip_dma_buffer_queue()
356 dma->xt.dst_start = addr; in xvip_dma_buffer_queue()
359 dma->xt.dir = DMA_MEM_TO_DEV; in xvip_dma_buffer_queue()
360 dma->xt.src_sgl = true; in xvip_dma_buffer_queue()
361 dma->xt.dst_sgl = false; in xvip_dma_buffer_queue()
362 dma->xt.src_start = addr; in xvip_dma_buffer_queue()
365 dma->xt.frame_size = 1; in xvip_dma_buffer_queue()
366 dma->sgl[0].size = dma->format.width * dma->fmtinfo->bpp; in xvip_dma_buffer_queue()
367 dma->sgl[0].icg = dma->format.bytesperline - dma->sgl[0].size; in xvip_dma_buffer_queue()
368 dma->xt.numf = dma->format.height; in xvip_dma_buffer_queue()
370 desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags); in xvip_dma_buffer_queue()
372 dev_err(dma->xdev->dev, "Failed to prepare DMA transfer\n"); in xvip_dma_buffer_queue()
379 spin_lock_irq(&dma->queued_lock); in xvip_dma_buffer_queue()
380 list_add_tail(&buf->queue, &dma->queued_bufs); in xvip_dma_buffer_queue()
381 spin_unlock_irq(&dma->queued_lock); in xvip_dma_buffer_queue()
385 if (vb2_is_streaming(&dma->queue)) in xvip_dma_buffer_queue()
386 dma_async_issue_pending(dma->dma); in xvip_dma_buffer_queue()
391 struct xvip_dma *dma = vb2_get_drv_priv(vq); in xvip_dma_start_streaming() local
396 dma->sequence = 0; in xvip_dma_start_streaming()
402 * Use the pipeline object embedded in the first DMA object that starts in xvip_dma_start_streaming()
405 pipe = to_xvip_pipeline(&dma->video) ? : &dma->pipe; in xvip_dma_start_streaming()
407 ret = video_device_pipeline_start(&dma->video, &pipe->pipe); in xvip_dma_start_streaming()
414 ret = xvip_dma_verify_format(dma); in xvip_dma_start_streaming()
418 ret = xvip_pipeline_prepare(pipe, dma); in xvip_dma_start_streaming()
422 /* Start the DMA engine. This must be done before starting the blocks in xvip_dma_start_streaming()
423 * in the pipeline to avoid DMA synchronization issues. in xvip_dma_start_streaming()
425 dma_async_issue_pending(dma->dma); in xvip_dma_start_streaming()
433 video_device_pipeline_stop(&dma->video); in xvip_dma_start_streaming()
437 spin_lock_irq(&dma->queued_lock); in xvip_dma_start_streaming()
438 list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) { in xvip_dma_start_streaming()
442 spin_unlock_irq(&dma->queued_lock); in xvip_dma_start_streaming()
449 struct xvip_dma *dma = vb2_get_drv_priv(vq); in xvip_dma_stop_streaming() local
450 struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video); in xvip_dma_stop_streaming()
456 /* Stop and reset the DMA engine. */ in xvip_dma_stop_streaming()
457 dmaengine_terminate_all(dma->dma); in xvip_dma_stop_streaming()
461 video_device_pipeline_stop(&dma->video); in xvip_dma_stop_streaming()
464 spin_lock_irq(&dma->queued_lock); in xvip_dma_stop_streaming()
465 list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) { in xvip_dma_stop_streaming()
469 spin_unlock_irq(&dma->queued_lock); in xvip_dma_stop_streaming()
490 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_querycap() local
492 cap->capabilities = dma->xdev->v4l2_caps | V4L2_CAP_STREAMING | in xvip_dma_querycap()
496 strscpy(cap->card, dma->video.name, sizeof(cap->card)); in xvip_dma_querycap()
498 dma->xdev->dev->of_node, dma->port); in xvip_dma_querycap()
512 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_enum_format() local
517 f->pixelformat = dma->format.pixelformat; in xvip_dma_enum_format()
526 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_get_format() local
528 format->fmt.pix = dma->format; in xvip_dma_get_format()
534 __xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix, in __xvip_dma_try_format() argument
558 align = lcm(dma->align, info->bpp); in __xvip_dma_try_format()
572 max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align); in __xvip_dma_try_format()
573 bpl = rounddown(pix->bytesperline, dma->align); in __xvip_dma_try_format()
586 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_try_format() local
588 __xvip_dma_try_format(dma, &format->fmt.pix, NULL); in xvip_dma_try_format()
596 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_set_format() local
599 __xvip_dma_try_format(dma, &format->fmt.pix, &info); in xvip_dma_set_format()
601 if (vb2_is_busy(&dma->queue)) in xvip_dma_set_format()
604 dma->format = format->fmt.pix; in xvip_dma_set_format()
605 dma->fmtinfo = info; in xvip_dma_set_format()
643 * Xilinx Video DMA Core
646 int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, in xvip_dma_init() argument
652 dma->xdev = xdev; in xvip_dma_init()
653 dma->port = port; in xvip_dma_init()
654 mutex_init(&dma->lock); in xvip_dma_init()
655 mutex_init(&dma->pipe.lock); in xvip_dma_init()
656 INIT_LIST_HEAD(&dma->queued_bufs); in xvip_dma_init()
657 spin_lock_init(&dma->queued_lock); in xvip_dma_init()
659 dma->fmtinfo = xvip_get_format_by_fourcc(V4L2_PIX_FMT_YUYV); in xvip_dma_init()
660 dma->format.pixelformat = dma->fmtinfo->fourcc; in xvip_dma_init()
661 dma->format.colorspace = V4L2_COLORSPACE_SRGB; in xvip_dma_init()
662 dma->format.field = V4L2_FIELD_NONE; in xvip_dma_init()
663 dma->format.width = XVIP_DMA_DEF_WIDTH; in xvip_dma_init()
664 dma->format.height = XVIP_DMA_DEF_HEIGHT; in xvip_dma_init()
665 dma->format.bytesperline = dma->format.width * dma->fmtinfo->bpp; in xvip_dma_init()
666 dma->format.sizeimage = dma->format.bytesperline * dma->format.height; in xvip_dma_init()
669 dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE in xvip_dma_init()
672 ret = media_entity_pads_init(&dma->video.entity, 1, &dma->pad); in xvip_dma_init()
677 dma->video.fops = &xvip_dma_fops; in xvip_dma_init()
678 dma->video.v4l2_dev = &xdev->v4l2_dev; in xvip_dma_init()
679 dma->video.queue = &dma->queue; in xvip_dma_init()
680 snprintf(dma->video.name, sizeof(dma->video.name), "%pOFn %s %u", in xvip_dma_init()
684 dma->video.vfl_type = VFL_TYPE_VIDEO; in xvip_dma_init()
685 dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE in xvip_dma_init()
687 dma->video.release = video_device_release_empty; in xvip_dma_init()
688 dma->video.ioctl_ops = &xvip_dma_ioctl_ops; in xvip_dma_init()
689 dma->video.lock = &dma->lock; in xvip_dma_init()
690 dma->video.device_caps = V4L2_CAP_STREAMING; in xvip_dma_init()
692 dma->video.device_caps |= V4L2_CAP_VIDEO_CAPTURE; in xvip_dma_init()
694 dma->video.device_caps |= V4L2_CAP_VIDEO_OUTPUT; in xvip_dma_init()
696 video_set_drvdata(&dma->video, dma); in xvip_dma_init()
706 dma->queue.type = type; in xvip_dma_init()
707 dma->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in xvip_dma_init()
708 dma->queue.lock = &dma->lock; in xvip_dma_init()
709 dma->queue.drv_priv = dma; in xvip_dma_init()
710 dma->queue.buf_struct_size = sizeof(struct xvip_dma_buffer); in xvip_dma_init()
711 dma->queue.ops = &xvip_dma_queue_qops; in xvip_dma_init()
712 dma->queue.mem_ops = &vb2_dma_contig_memops; in xvip_dma_init()
713 dma->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC in xvip_dma_init()
715 dma->queue.dev = dma->xdev->dev; in xvip_dma_init()
716 ret = vb2_queue_init(&dma->queue); in xvip_dma_init()
718 dev_err(dma->xdev->dev, "failed to initialize VB2 queue\n"); in xvip_dma_init()
722 /* ... and the DMA channel. */ in xvip_dma_init()
724 dma->dma = dma_request_chan(dma->xdev->dev, name); in xvip_dma_init()
725 if (IS_ERR(dma->dma)) { in xvip_dma_init()
726 ret = PTR_ERR(dma->dma); in xvip_dma_init()
728 dev_err(dma->xdev->dev, "no VDMA channel found\n"); in xvip_dma_init()
732 dma->align = 1 << dma->dma->device->copy_align; in xvip_dma_init()
734 ret = video_register_device(&dma->video, VFL_TYPE_VIDEO, -1); in xvip_dma_init()
736 dev_err(dma->xdev->dev, "failed to register video device\n"); in xvip_dma_init()
743 xvip_dma_cleanup(dma); in xvip_dma_init()
747 void xvip_dma_cleanup(struct xvip_dma *dma) in xvip_dma_cleanup() argument
749 if (video_is_registered(&dma->video)) in xvip_dma_cleanup()
750 video_unregister_device(&dma->video); in xvip_dma_cleanup()
752 if (!IS_ERR_OR_NULL(dma->dma)) in xvip_dma_cleanup()
753 dma_release_channel(dma->dma); in xvip_dma_cleanup()
755 media_entity_cleanup(&dma->video.entity); in xvip_dma_cleanup()
757 mutex_destroy(&dma->lock); in xvip_dma_cleanup()
758 mutex_destroy(&dma->pipe.lock); in xvip_dma_cleanup()