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
65 subdev = xvip_dma_remote_subdev(&dma->pad, &fmt.pad); in xvip_dma_verify_format()
73 if (dma->fmtinfo->code != fmt.format.code || in xvip_dma_verify_format()
74 dma->format.height != fmt.format.height || in xvip_dma_verify_format()
75 dma->format.width != fmt.format.width || in xvip_dma_verify_format()
76 dma->format.colorspace != fmt.format.colorspace) in xvip_dma_verify_format()
99 struct xvip_dma *dma = pipe->output; in xvip_pipeline_start_stop() local
105 entity = &dma->video.entity; in xvip_pipeline_start_stop()
131 * The pipeline is shared between all DMA engines connect at its input and
132 * output. While the stream state of DMA engines can be controlled
135 * counter that tracks the number of DMA engines that have requested the stream
140 * DMA engines in the pipeline it will enable all entities that belong to the
184 struct xvip_dma *dma; in xvip_pipeline_validate() local
189 dma = to_xvip_dma(media_entity_to_video_device(pad->entity)); in xvip_pipeline_validate()
191 if (dma->pad.flags & MEDIA_PAD_FL_SINK) { in xvip_pipeline_validate()
192 pipe->output = dma; in xvip_pipeline_validate()
234 * @dma: DMA engine at one end of the pipeline
242 struct xvip_dma *dma) in xvip_pipeline_prepare() argument
250 ret = xvip_pipeline_validate(pipe, dma); in xvip_pipeline_prepare()
270 * struct xvip_dma_buffer - Video DMA buffer
272 * @queue: buffer list entry in the DMA engine queued buffers list
273 * @dma: DMA channel that uses the buffer
278 struct xvip_dma *dma; member
286 struct xvip_dma *dma = buf->dma; in xvip_dma_complete() local
288 spin_lock(&dma->queued_lock); in xvip_dma_complete()
290 spin_unlock(&dma->queued_lock); in xvip_dma_complete()
293 buf->buf.sequence = dma->sequence++; in xvip_dma_complete()
295 vb2_set_plane_payload(&buf->buf.vb2_buf, 0, dma->format.sizeimage); in xvip_dma_complete()
304 struct xvip_dma *dma = vb2_get_drv_priv(vq); in xvip_dma_queue_setup() local
308 return sizes[0] < dma->format.sizeimage ? -EINVAL : 0; in xvip_dma_queue_setup()
311 sizes[0] = dma->format.sizeimage; in xvip_dma_queue_setup()
319 struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue); in xvip_dma_buffer_prepare() local
322 buf->dma = dma; in xvip_dma_buffer_prepare()
330 struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue); in xvip_dma_buffer_queue() local
336 if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { in xvip_dma_buffer_queue()
338 dma->xt.dir = DMA_DEV_TO_MEM; in xvip_dma_buffer_queue()
339 dma->xt.src_sgl = false; in xvip_dma_buffer_queue()
340 dma->xt.dst_sgl = true; in xvip_dma_buffer_queue()
341 dma->xt.dst_start = addr; in xvip_dma_buffer_queue()
344 dma->xt.dir = DMA_MEM_TO_DEV; in xvip_dma_buffer_queue()
345 dma->xt.src_sgl = true; in xvip_dma_buffer_queue()
346 dma->xt.dst_sgl = false; in xvip_dma_buffer_queue()
347 dma->xt.src_start = addr; in xvip_dma_buffer_queue()
350 dma->xt.frame_size = 1; in xvip_dma_buffer_queue()
351 dma->sgl.size = dma->format.width * dma->fmtinfo->bpp; in xvip_dma_buffer_queue()
352 dma->sgl.icg = dma->format.bytesperline - dma->sgl.size; in xvip_dma_buffer_queue()
353 dma->xt.numf = dma->format.height; in xvip_dma_buffer_queue()
355 desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags); in xvip_dma_buffer_queue()
357 dev_err(dma->xdev->dev, "Failed to prepare DMA transfer\n"); in xvip_dma_buffer_queue()
364 spin_lock_irq(&dma->queued_lock); in xvip_dma_buffer_queue()
365 list_add_tail(&buf->queue, &dma->queued_bufs); in xvip_dma_buffer_queue()
366 spin_unlock_irq(&dma->queued_lock); in xvip_dma_buffer_queue()
370 if (vb2_is_streaming(&dma->queue)) in xvip_dma_buffer_queue()
371 dma_async_issue_pending(dma->dma); in xvip_dma_buffer_queue()
376 struct xvip_dma *dma = vb2_get_drv_priv(vq); in xvip_dma_start_streaming() local
381 dma->sequence = 0; in xvip_dma_start_streaming()
387 * Use the pipeline object embedded in the first DMA object that starts in xvip_dma_start_streaming()
390 pipe = to_xvip_pipeline(&dma->video) ? : &dma->pipe; in xvip_dma_start_streaming()
392 ret = video_device_pipeline_start(&dma->video, &pipe->pipe); in xvip_dma_start_streaming()
399 ret = xvip_dma_verify_format(dma); in xvip_dma_start_streaming()
403 ret = xvip_pipeline_prepare(pipe, dma); in xvip_dma_start_streaming()
407 /* Start the DMA engine. This must be done before starting the blocks in xvip_dma_start_streaming()
408 * in the pipeline to avoid DMA synchronization issues. in xvip_dma_start_streaming()
410 dma_async_issue_pending(dma->dma); in xvip_dma_start_streaming()
418 video_device_pipeline_stop(&dma->video); in xvip_dma_start_streaming()
422 spin_lock_irq(&dma->queued_lock); in xvip_dma_start_streaming()
423 list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) { in xvip_dma_start_streaming()
427 spin_unlock_irq(&dma->queued_lock); in xvip_dma_start_streaming()
434 struct xvip_dma *dma = vb2_get_drv_priv(vq); in xvip_dma_stop_streaming() local
435 struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video); in xvip_dma_stop_streaming()
441 /* Stop and reset the DMA engine. */ in xvip_dma_stop_streaming()
442 dmaengine_terminate_all(dma->dma); in xvip_dma_stop_streaming()
446 video_device_pipeline_stop(&dma->video); in xvip_dma_stop_streaming()
449 spin_lock_irq(&dma->queued_lock); in xvip_dma_stop_streaming()
450 list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) { in xvip_dma_stop_streaming()
454 spin_unlock_irq(&dma->queued_lock); in xvip_dma_stop_streaming()
473 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_querycap() local
475 cap->capabilities = dma->xdev->v4l2_caps | V4L2_CAP_STREAMING | in xvip_dma_querycap()
479 strscpy(cap->card, dma->video.name, sizeof(cap->card)); in xvip_dma_querycap()
481 dma->xdev->dev->of_node, dma->port); in xvip_dma_querycap()
495 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_enum_format() local
500 f->pixelformat = dma->format.pixelformat; in xvip_dma_enum_format()
509 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_get_format() local
511 format->fmt.pix = dma->format; in xvip_dma_get_format()
517 __xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix, in __xvip_dma_try_format() argument
541 align = lcm(dma->align, info->bpp); in __xvip_dma_try_format()
555 max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align); in __xvip_dma_try_format()
556 bpl = rounddown(pix->bytesperline, dma->align); in __xvip_dma_try_format()
569 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_try_format() local
571 __xvip_dma_try_format(dma, &format->fmt.pix, NULL); in xvip_dma_try_format()
579 struct xvip_dma *dma = to_xvip_dma(vfh->vdev); in xvip_dma_set_format() local
582 __xvip_dma_try_format(dma, &format->fmt.pix, &info); in xvip_dma_set_format()
584 if (vb2_is_busy(&dma->queue)) in xvip_dma_set_format()
587 dma->format = format->fmt.pix; in xvip_dma_set_format()
588 dma->fmtinfo = info; in xvip_dma_set_format()
626 * Xilinx Video DMA Core
629 int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, in xvip_dma_init() argument
635 dma->xdev = xdev; in xvip_dma_init()
636 dma->port = port; in xvip_dma_init()
637 mutex_init(&dma->lock); in xvip_dma_init()
638 mutex_init(&dma->pipe.lock); in xvip_dma_init()
639 INIT_LIST_HEAD(&dma->queued_bufs); in xvip_dma_init()
640 spin_lock_init(&dma->queued_lock); in xvip_dma_init()
642 dma->fmtinfo = xvip_get_format_by_fourcc(V4L2_PIX_FMT_YUYV); in xvip_dma_init()
643 dma->format.pixelformat = dma->fmtinfo->fourcc; in xvip_dma_init()
644 dma->format.colorspace = V4L2_COLORSPACE_SRGB; in xvip_dma_init()
645 dma->format.field = V4L2_FIELD_NONE; in xvip_dma_init()
646 dma->format.width = XVIP_DMA_DEF_WIDTH; in xvip_dma_init()
647 dma->format.height = XVIP_DMA_DEF_HEIGHT; in xvip_dma_init()
648 dma->format.bytesperline = dma->format.width * dma->fmtinfo->bpp; in xvip_dma_init()
649 dma->format.sizeimage = dma->format.bytesperline * dma->format.height; in xvip_dma_init()
652 dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE in xvip_dma_init()
655 ret = media_entity_pads_init(&dma->video.entity, 1, &dma->pad); in xvip_dma_init()
660 dma->video.fops = &xvip_dma_fops; in xvip_dma_init()
661 dma->video.v4l2_dev = &xdev->v4l2_dev; in xvip_dma_init()
662 dma->video.queue = &dma->queue; in xvip_dma_init()
663 snprintf(dma->video.name, sizeof(dma->video.name), "%pOFn %s %u", in xvip_dma_init()
667 dma->video.vfl_type = VFL_TYPE_VIDEO; in xvip_dma_init()
668 dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE in xvip_dma_init()
670 dma->video.release = video_device_release_empty; in xvip_dma_init()
671 dma->video.ioctl_ops = &xvip_dma_ioctl_ops; in xvip_dma_init()
672 dma->video.lock = &dma->lock; in xvip_dma_init()
673 dma->video.device_caps = V4L2_CAP_STREAMING; in xvip_dma_init()
675 dma->video.device_caps |= V4L2_CAP_VIDEO_CAPTURE; in xvip_dma_init()
677 dma->video.device_caps |= V4L2_CAP_VIDEO_OUTPUT; in xvip_dma_init()
679 video_set_drvdata(&dma->video, dma); in xvip_dma_init()
689 dma->queue.type = type; in xvip_dma_init()
690 dma->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in xvip_dma_init()
691 dma->queue.lock = &dma->lock; in xvip_dma_init()
692 dma->queue.drv_priv = dma; in xvip_dma_init()
693 dma->queue.buf_struct_size = sizeof(struct xvip_dma_buffer); in xvip_dma_init()
694 dma->queue.ops = &xvip_dma_queue_qops; in xvip_dma_init()
695 dma->queue.mem_ops = &vb2_dma_contig_memops; in xvip_dma_init()
696 dma->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC in xvip_dma_init()
698 dma->queue.dev = dma->xdev->dev; in xvip_dma_init()
699 ret = vb2_queue_init(&dma->queue); in xvip_dma_init()
701 dev_err(dma->xdev->dev, "failed to initialize VB2 queue\n"); in xvip_dma_init()
705 /* ... and the DMA channel. */ in xvip_dma_init()
707 dma->dma = dma_request_chan(dma->xdev->dev, name); in xvip_dma_init()
708 if (IS_ERR(dma->dma)) { in xvip_dma_init()
709 ret = dev_err_probe(dma->xdev->dev, PTR_ERR(dma->dma), in xvip_dma_init()
714 dma->align = 1 << dma->dma->device->copy_align; in xvip_dma_init()
716 ret = video_register_device(&dma->video, VFL_TYPE_VIDEO, -1); in xvip_dma_init()
718 dev_err(dma->xdev->dev, "failed to register video device\n"); in xvip_dma_init()
725 xvip_dma_cleanup(dma); in xvip_dma_init()
729 void xvip_dma_cleanup(struct xvip_dma *dma) in xvip_dma_cleanup() argument
731 if (video_is_registered(&dma->video)) in xvip_dma_cleanup()
732 video_unregister_device(&dma->video); in xvip_dma_cleanup()
734 if (!IS_ERR_OR_NULL(dma->dma)) in xvip_dma_cleanup()
735 dma_release_channel(dma->dma); in xvip_dma_cleanup()
737 media_entity_cleanup(&dma->video.entity); in xvip_dma_cleanup()
739 mutex_destroy(&dma->lock); in xvip_dma_cleanup()
740 mutex_destroy(&dma->pipe.lock); in xvip_dma_cleanup()