Lines Matching +full:device +full:- +full:width

1 // SPDX-License-Identifier: GPL-2.0
20 #include <media/v4l2-device.h>
21 #include <media/v4l2-ioctl.h>
22 #include <media/v4l2-mem2mem.h>
24 #include "sun8i-di.h"
35 return readl(dev->base + reg); in deinterlace_read()
41 writel(value, dev->base + reg); in deinterlace_write()
47 writel(readl(dev->base + reg) | bits, dev->base + reg); in deinterlace_set_bits()
53 u32 val = readl(dev->base + reg); in deinterlace_clr_set_bits()
58 writel(val, dev->base + reg); in deinterlace_clr_set_bits()
64 struct deinterlace_dev *dev = ctx->dev; in deinterlace_device_run()
65 u32 size, stride, width, height, val; in deinterlace_device_run() local
71 src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in deinterlace_device_run()
72 dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in deinterlace_device_run()
79 if (ctx->field) { in deinterlace_device_run()
81 ctx->flag1_buf_dma); in deinterlace_device_run()
83 ctx->flag2_buf_dma); in deinterlace_device_run()
86 ctx->flag2_buf_dma); in deinterlace_device_run()
88 ctx->flag1_buf_dma); in deinterlace_device_run()
92 width = ctx->src_fmt.width; in deinterlace_device_run()
93 height = ctx->src_fmt.height; in deinterlace_device_run()
94 stride = ctx->src_fmt.bytesperline; in deinterlace_device_run()
97 addr = vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0); in deinterlace_device_run()
106 DEINTERLACE_SIZE(width, height)); in deinterlace_device_run()
108 DEINTERLACE_SIZE(width / 2, height / 2)); in deinterlace_device_run()
112 switch (ctx->src_fmt.pixelformat) { in deinterlace_device_run()
122 if (ctx->prev) in deinterlace_device_run()
123 addr = vb2_dma_contig_plane_dma_addr(&ctx->prev->vb2_buf, 0); in deinterlace_device_run()
129 switch (ctx->src_fmt.pixelformat) { in deinterlace_device_run()
139 width = ctx->dst_fmt.width; in deinterlace_device_run()
140 height = ctx->dst_fmt.height; in deinterlace_device_run()
141 stride = ctx->dst_fmt.bytesperline; in deinterlace_device_run()
145 DEINTERLACE_SIZE(width, height)); in deinterlace_device_run()
147 DEINTERLACE_SIZE(width / 2, height / 2)); in deinterlace_device_run()
152 addr = vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0); in deinterlace_device_run()
157 hstep = (ctx->src_fmt.width << 16) / ctx->dst_fmt.width; in deinterlace_device_run()
158 vstep = (ctx->src_fmt.height << 16) / ctx->dst_fmt.height; in deinterlace_device_run()
167 readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val, in deinterlace_device_run()
186 DEINTERLACE_FIELD_CTRL_FIELD_CNT(ctx->field)); in deinterlace_device_run()
205 return v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) >= 1 && in deinterlace_job_ready()
206 v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) >= 2; in deinterlace_job_ready()
214 ctx->aborting = 1; in deinterlace_job_abort()
225 ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); in deinterlace_irq()
227 v4l2_err(&dev->v4l2_dev, in deinterlace_irq()
249 dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in deinterlace_irq()
252 if (ctx->field != ctx->first_field || ctx->aborting) { in deinterlace_irq()
253 ctx->field = ctx->first_field; in deinterlace_irq()
255 src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in deinterlace_irq()
256 if (ctx->prev) in deinterlace_irq()
257 v4l2_m2m_buf_done(ctx->prev, state); in deinterlace_irq()
258 ctx->prev = src; in deinterlace_irq()
260 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); in deinterlace_irq()
262 ctx->field = !ctx->first_field; in deinterlace_irq()
312 return container_of(file->private_data, struct deinterlace_ctx, fh); in deinterlace_file2ctx()
328 unsigned int height = pix_fmt->height; in deinterlace_prepare_format()
329 unsigned int width = pix_fmt->width; in deinterlace_prepare_format() local
333 width = clamp(width, DEINTERLACE_MIN_WIDTH, in deinterlace_prepare_format()
338 bytesperline = ALIGN(width, 2); in deinterlace_prepare_format()
344 pix_fmt->width = width; in deinterlace_prepare_format()
345 pix_fmt->height = height; in deinterlace_prepare_format()
346 pix_fmt->bytesperline = bytesperline; in deinterlace_prepare_format()
347 pix_fmt->sizeimage = sizeimage; in deinterlace_prepare_format()
353 strscpy(cap->driver, DEINTERLACE_NAME, sizeof(cap->driver)); in deinterlace_querycap()
354 strscpy(cap->card, DEINTERLACE_NAME, sizeof(cap->card)); in deinterlace_querycap()
355 snprintf(cap->bus_info, sizeof(cap->bus_info), in deinterlace_querycap()
364 if (f->index < ARRAY_SIZE(deinterlace_formats)) { in deinterlace_enum_fmt()
365 f->pixelformat = deinterlace_formats[f->index]; in deinterlace_enum_fmt()
370 return -EINVAL; in deinterlace_enum_fmt()
376 if (fsize->index != 0) in deinterlace_enum_framesizes()
377 return -EINVAL; in deinterlace_enum_framesizes()
379 if (!deinterlace_check_format(fsize->pixel_format)) in deinterlace_enum_framesizes()
380 return -EINVAL; in deinterlace_enum_framesizes()
382 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in deinterlace_enum_framesizes()
383 fsize->stepwise.min_width = DEINTERLACE_MIN_WIDTH; in deinterlace_enum_framesizes()
384 fsize->stepwise.min_height = DEINTERLACE_MIN_HEIGHT; in deinterlace_enum_framesizes()
385 fsize->stepwise.max_width = DEINTERLACE_MAX_WIDTH; in deinterlace_enum_framesizes()
386 fsize->stepwise.max_height = DEINTERLACE_MAX_HEIGHT; in deinterlace_enum_framesizes()
387 fsize->stepwise.step_width = 2; in deinterlace_enum_framesizes()
388 fsize->stepwise.step_height = 1; in deinterlace_enum_framesizes()
398 f->fmt.pix = ctx->dst_fmt; in deinterlace_g_fmt_vid_cap()
408 f->fmt.pix = ctx->src_fmt; in deinterlace_g_fmt_vid_out()
416 if (!deinterlace_check_format(f->fmt.pix.pixelformat)) in deinterlace_try_fmt_vid_cap()
417 f->fmt.pix.pixelformat = deinterlace_formats[0]; in deinterlace_try_fmt_vid_cap()
419 if (f->fmt.pix.field != V4L2_FIELD_NONE) in deinterlace_try_fmt_vid_cap()
420 f->fmt.pix.field = V4L2_FIELD_NONE; in deinterlace_try_fmt_vid_cap()
422 deinterlace_prepare_format(&f->fmt.pix); in deinterlace_try_fmt_vid_cap()
430 if (!deinterlace_check_format(f->fmt.pix.pixelformat)) in deinterlace_try_fmt_vid_out()
431 f->fmt.pix.pixelformat = deinterlace_formats[0]; in deinterlace_try_fmt_vid_out()
433 if (f->fmt.pix.field != V4L2_FIELD_INTERLACED_TB && in deinterlace_try_fmt_vid_out()
434 f->fmt.pix.field != V4L2_FIELD_INTERLACED_BT && in deinterlace_try_fmt_vid_out()
435 f->fmt.pix.field != V4L2_FIELD_INTERLACED) in deinterlace_try_fmt_vid_out()
436 f->fmt.pix.field = V4L2_FIELD_INTERLACED; in deinterlace_try_fmt_vid_out()
438 deinterlace_prepare_format(&f->fmt.pix); in deinterlace_try_fmt_vid_out()
454 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in deinterlace_s_fmt_vid_cap()
456 return -EBUSY; in deinterlace_s_fmt_vid_cap()
458 ctx->dst_fmt = f->fmt.pix; in deinterlace_s_fmt_vid_cap()
474 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in deinterlace_s_fmt_vid_out()
476 return -EBUSY; in deinterlace_s_fmt_vid_out()
478 ctx->src_fmt = f->fmt.pix; in deinterlace_s_fmt_vid_out()
481 ctx->dst_fmt.colorspace = f->fmt.pix.colorspace; in deinterlace_s_fmt_vid_out()
482 ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func; in deinterlace_s_fmt_vid_out()
483 ctx->dst_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc; in deinterlace_s_fmt_vid_out()
484 ctx->dst_fmt.quantization = f->fmt.pix.quantization; in deinterlace_s_fmt_vid_out()
518 struct device *alloc_devs[]) in deinterlace_queue_setup()
523 if (V4L2_TYPE_IS_OUTPUT(vq->type)) in deinterlace_queue_setup()
524 pix_fmt = &ctx->src_fmt; in deinterlace_queue_setup()
526 pix_fmt = &ctx->dst_fmt; in deinterlace_queue_setup()
529 if (sizes[0] < pix_fmt->sizeimage) in deinterlace_queue_setup()
530 return -EINVAL; in deinterlace_queue_setup()
532 sizes[0] = pix_fmt->sizeimage; in deinterlace_queue_setup()
541 struct vb2_queue *vq = vb->vb2_queue; in deinterlace_buf_prepare()
545 if (V4L2_TYPE_IS_OUTPUT(vq->type)) in deinterlace_buf_prepare()
546 pix_fmt = &ctx->src_fmt; in deinterlace_buf_prepare()
548 pix_fmt = &ctx->dst_fmt; in deinterlace_buf_prepare()
550 if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage) in deinterlace_buf_prepare()
551 return -EINVAL; in deinterlace_buf_prepare()
553 vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); in deinterlace_buf_prepare()
561 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in deinterlace_buf_queue()
563 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in deinterlace_buf_queue()
572 if (V4L2_TYPE_IS_OUTPUT(vq->type)) in deinterlace_queue_cleanup()
573 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in deinterlace_queue_cleanup()
575 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in deinterlace_queue_cleanup()
581 if (V4L2_TYPE_IS_OUTPUT(vq->type) && ctx->prev) in deinterlace_queue_cleanup()
582 v4l2_m2m_buf_done(ctx->prev, state); in deinterlace_queue_cleanup()
588 struct device *dev = ctx->dev->dev; in deinterlace_start_streaming()
591 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { in deinterlace_start_streaming()
599 ctx->first_field = in deinterlace_start_streaming()
600 ctx->src_fmt.field == V4L2_FIELD_INTERLACED_BT; in deinterlace_start_streaming()
601 ctx->field = ctx->first_field; in deinterlace_start_streaming()
603 ctx->prev = NULL; in deinterlace_start_streaming()
604 ctx->aborting = 0; in deinterlace_start_streaming()
606 ctx->flag1_buf = dma_alloc_coherent(dev, FLAG_SIZE, in deinterlace_start_streaming()
607 &ctx->flag1_buf_dma, in deinterlace_start_streaming()
609 if (!ctx->flag1_buf) { in deinterlace_start_streaming()
610 ret = -ENOMEM; in deinterlace_start_streaming()
615 ctx->flag2_buf = dma_alloc_coherent(dev, FLAG_SIZE, in deinterlace_start_streaming()
616 &ctx->flag2_buf_dma, in deinterlace_start_streaming()
618 if (!ctx->flag2_buf) { in deinterlace_start_streaming()
619 ret = -ENOMEM; in deinterlace_start_streaming()
628 dma_free_coherent(dev, FLAG_SIZE, ctx->flag1_buf, in deinterlace_start_streaming()
629 ctx->flag1_buf_dma); in deinterlace_start_streaming()
642 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { in deinterlace_stop_streaming()
643 struct device *dev = ctx->dev->dev; in deinterlace_stop_streaming()
645 dma_free_coherent(dev, FLAG_SIZE, ctx->flag1_buf, in deinterlace_stop_streaming()
646 ctx->flag1_buf_dma); in deinterlace_stop_streaming()
647 dma_free_coherent(dev, FLAG_SIZE, ctx->flag2_buf, in deinterlace_stop_streaming()
648 ctx->flag2_buf_dma); in deinterlace_stop_streaming()
670 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in deinterlace_queue_init()
671 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; in deinterlace_queue_init()
672 src_vq->drv_priv = ctx; in deinterlace_queue_init()
673 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in deinterlace_queue_init()
674 src_vq->min_queued_buffers = 1; in deinterlace_queue_init()
675 src_vq->ops = &deinterlace_qops; in deinterlace_queue_init()
676 src_vq->mem_ops = &vb2_dma_contig_memops; in deinterlace_queue_init()
677 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in deinterlace_queue_init()
678 src_vq->lock = &ctx->dev->dev_mutex; in deinterlace_queue_init()
679 src_vq->dev = ctx->dev->dev; in deinterlace_queue_init()
685 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in deinterlace_queue_init()
686 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; in deinterlace_queue_init()
687 dst_vq->drv_priv = ctx; in deinterlace_queue_init()
688 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in deinterlace_queue_init()
689 dst_vq->min_queued_buffers = 2; in deinterlace_queue_init()
690 dst_vq->ops = &deinterlace_qops; in deinterlace_queue_init()
691 dst_vq->mem_ops = &vb2_dma_contig_memops; in deinterlace_queue_init()
692 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in deinterlace_queue_init()
693 dst_vq->lock = &ctx->dev->dev_mutex; in deinterlace_queue_init()
694 dst_vq->dev = ctx->dev->dev; in deinterlace_queue_init()
709 if (mutex_lock_interruptible(&dev->dev_mutex)) in deinterlace_open()
710 return -ERESTARTSYS; in deinterlace_open()
714 mutex_unlock(&dev->dev_mutex); in deinterlace_open()
715 return -ENOMEM; in deinterlace_open()
719 ctx->src_fmt.pixelformat = deinterlace_formats[0]; in deinterlace_open()
720 ctx->src_fmt.field = V4L2_FIELD_INTERLACED; in deinterlace_open()
721 ctx->src_fmt.width = 640; in deinterlace_open()
722 ctx->src_fmt.height = 480; in deinterlace_open()
723 deinterlace_prepare_format(&ctx->src_fmt); in deinterlace_open()
726 ctx->dst_fmt.pixelformat = deinterlace_formats[0]; in deinterlace_open()
727 ctx->dst_fmt.field = V4L2_FIELD_NONE; in deinterlace_open()
728 ctx->dst_fmt.width = 640; in deinterlace_open()
729 ctx->dst_fmt.height = 480; in deinterlace_open()
730 deinterlace_prepare_format(&ctx->dst_fmt); in deinterlace_open()
732 v4l2_fh_init(&ctx->fh, video_devdata(file)); in deinterlace_open()
733 file->private_data = &ctx->fh; in deinterlace_open()
734 ctx->dev = dev; in deinterlace_open()
736 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, in deinterlace_open()
738 if (IS_ERR(ctx->fh.m2m_ctx)) { in deinterlace_open()
739 ret = PTR_ERR(ctx->fh.m2m_ctx); in deinterlace_open()
743 v4l2_fh_add(&ctx->fh); in deinterlace_open()
745 mutex_unlock(&dev->dev_mutex); in deinterlace_open()
751 mutex_unlock(&dev->dev_mutex); in deinterlace_open()
759 struct deinterlace_ctx *ctx = container_of(file->private_data, in deinterlace_release()
762 mutex_lock(&dev->dev_mutex); in deinterlace_release()
764 v4l2_fh_del(&ctx->fh); in deinterlace_release()
765 v4l2_fh_exit(&ctx->fh); in deinterlace_release()
766 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in deinterlace_release()
770 mutex_unlock(&dev->dev_mutex); in deinterlace_release()
789 .minor = -1,
806 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in deinterlace_probe()
808 return -ENOMEM; in deinterlace_probe()
810 dev->vfd = deinterlace_video_device; in deinterlace_probe()
811 dev->dev = &pdev->dev; in deinterlace_probe()
817 ret = devm_request_irq(dev->dev, irq, deinterlace_irq, in deinterlace_probe()
818 0, dev_name(dev->dev), dev); in deinterlace_probe()
820 dev_err(dev->dev, "Failed to request IRQ\n"); in deinterlace_probe()
825 dev->base = devm_platform_ioremap_resource(pdev, 0); in deinterlace_probe()
826 if (IS_ERR(dev->base)) in deinterlace_probe()
827 return PTR_ERR(dev->base); in deinterlace_probe()
829 dev->bus_clk = devm_clk_get(dev->dev, "bus"); in deinterlace_probe()
830 if (IS_ERR(dev->bus_clk)) { in deinterlace_probe()
831 dev_err(dev->dev, "Failed to get bus clock\n"); in deinterlace_probe()
833 return PTR_ERR(dev->bus_clk); in deinterlace_probe()
836 dev->mod_clk = devm_clk_get(dev->dev, "mod"); in deinterlace_probe()
837 if (IS_ERR(dev->mod_clk)) { in deinterlace_probe()
838 dev_err(dev->dev, "Failed to get mod clock\n"); in deinterlace_probe()
840 return PTR_ERR(dev->mod_clk); in deinterlace_probe()
843 dev->ram_clk = devm_clk_get(dev->dev, "ram"); in deinterlace_probe()
844 if (IS_ERR(dev->ram_clk)) { in deinterlace_probe()
845 dev_err(dev->dev, "Failed to get ram clock\n"); in deinterlace_probe()
847 return PTR_ERR(dev->ram_clk); in deinterlace_probe()
850 dev->rstc = devm_reset_control_get(dev->dev, NULL); in deinterlace_probe()
851 if (IS_ERR(dev->rstc)) { in deinterlace_probe()
852 dev_err(dev->dev, "Failed to get reset control\n"); in deinterlace_probe()
854 return PTR_ERR(dev->rstc); in deinterlace_probe()
857 mutex_init(&dev->dev_mutex); in deinterlace_probe()
859 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); in deinterlace_probe()
861 dev_err(dev->dev, "Failed to register V4L2 device\n"); in deinterlace_probe()
866 vfd = &dev->vfd; in deinterlace_probe()
867 vfd->lock = &dev->dev_mutex; in deinterlace_probe()
868 vfd->v4l2_dev = &dev->v4l2_dev; in deinterlace_probe()
870 snprintf(vfd->name, sizeof(vfd->name), "%s", in deinterlace_probe()
876 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); in deinterlace_probe()
881 v4l2_info(&dev->v4l2_dev, in deinterlace_probe()
882 "Device registered as /dev/video%d\n", vfd->num); in deinterlace_probe()
884 dev->m2m_dev = v4l2_m2m_init(&deinterlace_m2m_ops); in deinterlace_probe()
885 if (IS_ERR(dev->m2m_dev)) { in deinterlace_probe()
886 v4l2_err(&dev->v4l2_dev, in deinterlace_probe()
887 "Failed to initialize V4L2 M2M device\n"); in deinterlace_probe()
888 ret = PTR_ERR(dev->m2m_dev); in deinterlace_probe()
895 pm_runtime_enable(dev->dev); in deinterlace_probe()
900 video_unregister_device(&dev->vfd); in deinterlace_probe()
902 v4l2_device_unregister(&dev->v4l2_dev); in deinterlace_probe()
911 v4l2_m2m_release(dev->m2m_dev); in deinterlace_remove()
912 video_unregister_device(&dev->vfd); in deinterlace_remove()
913 v4l2_device_unregister(&dev->v4l2_dev); in deinterlace_remove()
915 pm_runtime_force_suspend(&pdev->dev); in deinterlace_remove()
918 static int deinterlace_runtime_resume(struct device *device) in deinterlace_runtime_resume() argument
920 struct deinterlace_dev *dev = dev_get_drvdata(device); in deinterlace_runtime_resume()
923 ret = clk_set_rate_exclusive(dev->mod_clk, 300000000); in deinterlace_runtime_resume()
925 dev_err(dev->dev, "Failed to set exclusive mod clock rate\n"); in deinterlace_runtime_resume()
930 ret = reset_control_deassert(dev->rstc); in deinterlace_runtime_resume()
932 dev_err(dev->dev, "Failed to apply reset\n"); in deinterlace_runtime_resume()
937 ret = clk_prepare_enable(dev->bus_clk); in deinterlace_runtime_resume()
939 dev_err(dev->dev, "Failed to enable bus clock\n"); in deinterlace_runtime_resume()
944 ret = clk_prepare_enable(dev->mod_clk); in deinterlace_runtime_resume()
946 dev_err(dev->dev, "Failed to enable mod clock\n"); in deinterlace_runtime_resume()
951 ret = clk_prepare_enable(dev->ram_clk); in deinterlace_runtime_resume()
953 dev_err(dev->dev, "Failed to enable ram clock\n"); in deinterlace_runtime_resume()
963 clk_disable_unprepare(dev->mod_clk); in deinterlace_runtime_resume()
965 clk_disable_unprepare(dev->bus_clk); in deinterlace_runtime_resume()
967 reset_control_assert(dev->rstc); in deinterlace_runtime_resume()
969 clk_rate_exclusive_put(dev->mod_clk); in deinterlace_runtime_resume()
974 static int deinterlace_runtime_suspend(struct device *device) in deinterlace_runtime_suspend() argument
976 struct deinterlace_dev *dev = dev_get_drvdata(device); in deinterlace_runtime_suspend()
978 clk_disable_unprepare(dev->ram_clk); in deinterlace_runtime_suspend()
979 clk_disable_unprepare(dev->mod_clk); in deinterlace_runtime_suspend()
980 clk_disable_unprepare(dev->bus_clk); in deinterlace_runtime_suspend()
982 reset_control_assert(dev->rstc); in deinterlace_runtime_suspend()
984 clk_rate_exclusive_put(dev->mod_clk); in deinterlace_runtime_suspend()
990 { .compatible = "allwinner,sun8i-h3-deinterlace" },