Lines Matching +full:imx53 +full:- +full:vpu
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Coda multi-standard codec IP
6 * Javier Martin, <javier.martin@vista-silicon.com>
31 #include <media/v4l2-ctrls.h>
32 #include <media/v4l2-device.h>
33 #include <media/v4l2-event.h>
34 #include <media/v4l2-ioctl.h>
35 #include <media/v4l2-mem2mem.h>
36 #include <media/videobuf2-v4l2.h>
37 #include <media/videobuf2-dma-contig.h>
38 #include <media/videobuf2-vmalloc.h>
41 #include "imx-vdoa.h"
61 MODULE_PARM_DESC(coda_debug, "Debug level (0-2)");
69 MODULE_PARM_DESC(disable_vdoa, "Disable Video Data Order Adapter tiled to raster-scan conversion");
77 v4l2_dbg(3, coda_debug, &dev->v4l2_dev, in coda_write()
79 writel(data, dev->regs_base + reg); in coda_write()
86 data = readl(dev->regs_base + reg); in coda_read()
87 v4l2_dbg(3, coda_debug, &dev->v4l2_dev, in coda_read()
95 u32 base_y = vb2_dma_contig_plane_dma_addr(&buf->vb2_buf, 0); in coda_write_base()
98 switch (q_data->fourcc) { in coda_write_base()
100 /* Fallthrough: IN -H264-> CODA -NV12 MB-> VDOA -YUYV-> OUT */ in coda_write_base()
104 base_cb = base_y + q_data->bytesperline * q_data->height; in coda_write_base()
105 base_cr = base_cb + q_data->bytesperline * q_data->height / 4; in coda_write_base()
109 base_cr = base_y + q_data->bytesperline * q_data->height; in coda_write_base()
110 base_cb = base_cr + q_data->bytesperline * q_data->height / 4; in coda_write_base()
113 base_cb = base_y + q_data->bytesperline * q_data->height; in coda_write_base()
114 base_cr = base_cb + q_data->bytesperline * q_data->height / 2; in coda_write_base()
117 coda_write(ctx->dev, base_y, reg_y); in coda_write_base()
118 coda_write(ctx->dev, base_cb, reg_y + 4); in coda_write_base()
119 coda_write(ctx->dev, base_cr, reg_y + 8); in coda_write_base()
127 * i.MX27 -> codadx6
128 * i.MX51 -> codahx4
129 * i.MX53 -> coda7
130 * i.MX6 -> coda960
175 .name = "coda-video-encoder",
190 .name = "coda-jpeg-encoder",
205 .name = "coda-video-decoder",
226 .name = "coda-jpeg-decoder",
241 .name = "coda-jpeg-encoder",
258 .name = "coda-jpeg-decoder",
317 const struct coda_codec *codecs = dev->devtype->codecs; in coda_find_codec()
318 int num_codecs = dev->devtype->num_codecs; in coda_find_codec()
342 const struct coda_codec *codecs = dev->devtype->codecs; in coda_get_max_dimensions()
343 int num_codecs = dev->devtype->num_codecs; in coda_get_max_dimensions()
348 w = codec->max_w; in coda_get_max_dimensions()
349 h = codec->max_h; in coda_get_max_dimensions()
367 unsigned int i = vdev - dev->vfd; in to_coda_video_device()
369 if (i >= dev->devtype->num_vdevs) in to_coda_video_device()
372 return dev->devtype->vdevs[i]; in to_coda_video_device()
400 vdoa_node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-vdoa"); in coda_get_vdoa_data()
410 vdoa_data = ERR_PTR(-EPROBE_DEFER); in coda_get_vdoa_data()
412 put_device(&vdoa_pdev->dev); in coda_get_vdoa_data()
427 strscpy(cap->driver, CODA_NAME, sizeof(cap->driver)); in coda_querycap()
428 strscpy(cap->card, coda_product_name(ctx->dev->devtype->product), in coda_querycap()
429 sizeof(cap->card)); in coda_querycap()
430 strscpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); in coda_querycap()
448 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_enum_fmt()
449 formats = cvd->src_formats; in coda_enum_fmt()
450 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { in coda_enum_fmt()
454 formats = cvd->dst_formats; in coda_enum_fmt()
461 src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in coda_enum_fmt()
463 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && in coda_enum_fmt()
465 if (ctx->params.jpeg_chroma_subsampling == in coda_enum_fmt()
468 } else if (ctx->params.jpeg_chroma_subsampling == in coda_enum_fmt()
470 f->pixelformat = V4L2_PIX_FMT_YUV422P; in coda_enum_fmt()
471 return f->index ? -EINVAL : 0; in coda_enum_fmt()
475 return -EINVAL; in coda_enum_fmt()
478 if (f->index >= CODA_MAX_FORMATS || formats[f->index] == 0) in coda_enum_fmt()
479 return -EINVAL; in coda_enum_fmt()
482 if (!ctx->vdoa && f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && in coda_enum_fmt()
483 formats[f->index] == V4L2_PIX_FMT_YUYV) in coda_enum_fmt()
484 return -EINVAL; in coda_enum_fmt()
486 f->pixelformat = formats[f->index]; in coda_enum_fmt()
497 q_data = get_q_data(ctx, f->type); in coda_g_fmt()
499 return -EINVAL; in coda_g_fmt()
501 f->fmt.pix.field = V4L2_FIELD_NONE; in coda_g_fmt()
502 f->fmt.pix.pixelformat = q_data->fourcc; in coda_g_fmt()
503 f->fmt.pix.width = q_data->width; in coda_g_fmt()
504 f->fmt.pix.height = q_data->height; in coda_g_fmt()
505 f->fmt.pix.bytesperline = q_data->bytesperline; in coda_g_fmt()
507 f->fmt.pix.sizeimage = q_data->sizeimage; in coda_g_fmt()
508 f->fmt.pix.colorspace = ctx->colorspace; in coda_g_fmt()
509 f->fmt.pix.xfer_func = ctx->xfer_func; in coda_g_fmt()
510 f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; in coda_g_fmt()
511 f->fmt.pix.quantization = ctx->quantization; in coda_g_fmt()
522 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_try_pixelformat()
523 formats = ctx->cvd->src_formats; in coda_try_pixelformat()
524 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in coda_try_pixelformat()
525 formats = ctx->cvd->dst_formats; in coda_try_pixelformat()
527 return -EINVAL; in coda_try_pixelformat()
531 if (!ctx->vdoa && f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && in coda_try_pixelformat()
535 if (formats[i] == f->fmt.pix.pixelformat) { in coda_try_pixelformat()
536 f->fmt.pix.pixelformat = formats[i]; in coda_try_pixelformat()
542 q_data = get_q_data(ctx, f->type); in coda_try_pixelformat()
543 f->fmt.pix.pixelformat = q_data->fourcc; in coda_try_pixelformat()
553 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in coda_try_fmt_vdoa()
554 return -EINVAL; in coda_try_fmt_vdoa()
557 return -EINVAL; in coda_try_fmt_vdoa()
559 if (!ctx->vdoa) { in coda_try_fmt_vdoa()
564 err = vdoa_context_configure(NULL, round_up(f->fmt.pix.width, 16), in coda_try_fmt_vdoa()
565 f->fmt.pix.height, f->fmt.pix.pixelformat); in coda_try_fmt_vdoa()
590 struct coda_dev *dev = ctx->dev; in coda_try_fmt()
594 field = f->fmt.pix.field; in coda_try_fmt()
598 return -EINVAL; in coda_try_fmt()
602 f->fmt.pix.field = field; in coda_try_fmt()
605 v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN, in coda_try_fmt()
606 &f->fmt.pix.height, MIN_H, max_h, H_ALIGN, in coda_try_fmt()
609 switch (f->fmt.pix.pixelformat) { in coda_try_fmt()
617 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); in coda_try_fmt()
618 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt()
619 f->fmt.pix.height * 3 / 2; in coda_try_fmt()
622 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16) * 2; in coda_try_fmt()
623 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt()
624 f->fmt.pix.height; in coda_try_fmt()
627 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); in coda_try_fmt()
628 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt()
629 f->fmt.pix.height * 2; in coda_try_fmt()
632 /* keep 16 pixel alignment of 8-bit pixel data */ in coda_try_fmt()
633 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); in coda_try_fmt()
634 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; in coda_try_fmt()
640 f->fmt.pix.bytesperline = 0; in coda_try_fmt()
641 f->fmt.pix.sizeimage = coda_estimate_sizeimage(ctx, in coda_try_fmt()
642 f->fmt.pix.sizeimage, in coda_try_fmt()
643 f->fmt.pix.width, in coda_try_fmt()
644 f->fmt.pix.height); in coda_try_fmt()
676 src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); in coda_try_fmt_vid_cap()
678 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && in coda_try_fmt_vid_cap()
679 ctx->dev->devtype->product == CODA_960) { in coda_try_fmt_vid_cap()
680 hscale = coda_jpeg_scale(q_data_src->width, f->fmt.pix.width); in coda_try_fmt_vid_cap()
681 vscale = coda_jpeg_scale(q_data_src->height, f->fmt.pix.height); in coda_try_fmt_vid_cap()
683 f->fmt.pix.width = q_data_src->width >> hscale; in coda_try_fmt_vid_cap()
684 f->fmt.pix.height = q_data_src->height >> vscale; in coda_try_fmt_vid_cap()
686 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG) { in coda_try_fmt_vid_cap()
687 if (ctx->params.jpeg_chroma_subsampling == in coda_try_fmt_vid_cap()
689 f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) in coda_try_fmt_vid_cap()
690 f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; in coda_try_fmt_vid_cap()
691 else if (ctx->params.jpeg_chroma_subsampling == in coda_try_fmt_vid_cap()
693 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; in coda_try_fmt_vid_cap()
697 f->fmt.pix.colorspace = ctx->colorspace; in coda_try_fmt_vid_cap()
698 f->fmt.pix.xfer_func = ctx->xfer_func; in coda_try_fmt_vid_cap()
699 f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; in coda_try_fmt_vid_cap()
700 f->fmt.pix.quantization = ctx->quantization; in coda_try_fmt_vid_cap()
703 codec = coda_find_codec(ctx->dev, q_data_src->fourcc, in coda_try_fmt_vid_cap()
704 f->fmt.pix.pixelformat); in coda_try_fmt_vid_cap()
706 return -EINVAL; in coda_try_fmt_vid_cap()
713 if (ctx->inst_type == CODA_INST_DECODER) { in coda_try_fmt_vid_cap()
714 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16 >> hscale); in coda_try_fmt_vid_cap()
715 f->fmt.pix.height = round_up(f->fmt.pix.height, 16 >> vscale); in coda_try_fmt_vid_cap()
716 if (codec->src_fourcc == V4L2_PIX_FMT_JPEG && in coda_try_fmt_vid_cap()
717 f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) { in coda_try_fmt_vid_cap()
718 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt_vid_cap()
719 f->fmt.pix.height * 2; in coda_try_fmt_vid_cap()
721 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt_vid_cap()
722 f->fmt.pix.height * 3 / 2; in coda_try_fmt_vid_cap()
729 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { in coda_try_fmt_vid_cap()
731 return -EINVAL; in coda_try_fmt_vid_cap()
733 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16) * 2; in coda_try_fmt_vid_cap()
734 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt_vid_cap()
735 f->fmt.pix.height; in coda_try_fmt_vid_cap()
746 if (fmt->pixelformat == V4L2_PIX_FMT_JPEG) in coda_set_default_colorspace()
748 else if (fmt->width <= 720 && fmt->height <= 576) in coda_set_default_colorspace()
753 fmt->colorspace = colorspace; in coda_set_default_colorspace()
754 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in coda_set_default_colorspace()
755 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in coda_set_default_colorspace()
756 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in coda_set_default_colorspace()
763 struct coda_dev *dev = ctx->dev; in coda_try_fmt_vid_out()
772 if (f->fmt.pix.colorspace == V4L2_COLORSPACE_DEFAULT) in coda_try_fmt_vid_out()
773 coda_set_default_colorspace(&f->fmt.pix); in coda_try_fmt_vid_out()
776 codec = coda_find_codec(dev, f->fmt.pix.pixelformat, q_data_dst->fourcc); in coda_try_fmt_vid_out()
787 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in coda_s_fmt()
789 return -EINVAL; in coda_s_fmt()
791 q_data = get_q_data(ctx, f->type); in coda_s_fmt()
793 return -EINVAL; in coda_s_fmt()
796 v4l2_err(&ctx->dev->v4l2_dev, "%s: %s queue busy: %d\n", in coda_s_fmt()
797 __func__, v4l2_type_names[f->type], vb2_get_num_buffers(vq)); in coda_s_fmt()
798 return -EBUSY; in coda_s_fmt()
801 q_data->fourcc = f->fmt.pix.pixelformat; in coda_s_fmt()
802 q_data->width = f->fmt.pix.width; in coda_s_fmt()
803 q_data->height = f->fmt.pix.height; in coda_s_fmt()
804 q_data->bytesperline = f->fmt.pix.bytesperline; in coda_s_fmt()
805 q_data->sizeimage = f->fmt.pix.sizeimage; in coda_s_fmt()
807 q_data->rect = *r; in coda_s_fmt()
809 q_data->rect.left = 0; in coda_s_fmt()
810 q_data->rect.top = 0; in coda_s_fmt()
811 q_data->rect.width = f->fmt.pix.width; in coda_s_fmt()
812 q_data->rect.height = f->fmt.pix.height; in coda_s_fmt()
815 switch (f->fmt.pix.pixelformat) { in coda_s_fmt()
817 ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP; in coda_s_fmt()
820 if (!disable_tiling && ctx->use_bit && in coda_s_fmt()
821 ctx->dev->devtype->product == CODA_960) { in coda_s_fmt()
822 ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP; in coda_s_fmt()
829 ctx->tiled_map_type = GDI_LINEAR_FRAME_MAP; in coda_s_fmt()
835 if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP && in coda_s_fmt()
836 !coda_try_fmt_vdoa(ctx, f, &ctx->use_vdoa) && in coda_s_fmt()
837 ctx->use_vdoa) in coda_s_fmt()
838 vdoa_context_configure(ctx->vdoa, in coda_s_fmt()
839 round_up(f->fmt.pix.width, 16), in coda_s_fmt()
840 f->fmt.pix.height, in coda_s_fmt()
841 f->fmt.pix.pixelformat); in coda_s_fmt()
843 ctx->use_vdoa = false; in coda_s_fmt()
846 v4l2_type_names[f->type], q_data->width, q_data->height, in coda_s_fmt()
847 (char *)&q_data->fourcc, in coda_s_fmt()
848 (ctx->tiled_map_type == GDI_LINEAR_FRAME_MAP) ? 'L' : 'T'); in coda_s_fmt()
866 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && in coda_s_fmt_vid_cap()
867 ctx->dev->devtype->product == CODA_960) { in coda_s_fmt_vid_cap()
868 hscale = coda_jpeg_scale(q_data_src->width, f->fmt.pix.width); in coda_s_fmt_vid_cap()
869 vscale = coda_jpeg_scale(q_data_src->height, f->fmt.pix.height); in coda_s_fmt_vid_cap()
878 r.width = q_data_src->width >> hscale; in coda_s_fmt_vid_cap()
879 r.height = q_data_src->height >> vscale; in coda_s_fmt_vid_cap()
885 if (ctx->inst_type != CODA_INST_ENCODER) in coda_s_fmt_vid_cap()
889 codec = coda_find_codec(ctx->dev, q_data_src->fourcc, in coda_s_fmt_vid_cap()
890 f->fmt.pix.pixelformat); in coda_s_fmt_vid_cap()
892 v4l2_err(&ctx->dev->v4l2_dev, "failed to determine codec\n"); in coda_s_fmt_vid_cap()
893 return -EINVAL; in coda_s_fmt_vid_cap()
895 ctx->codec = codec; in coda_s_fmt_vid_cap()
897 ctx->colorspace = f->fmt.pix.colorspace; in coda_s_fmt_vid_cap()
898 ctx->xfer_func = f->fmt.pix.xfer_func; in coda_s_fmt_vid_cap()
899 ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; in coda_s_fmt_vid_cap()
900 ctx->quantization = f->fmt.pix.quantization; in coda_s_fmt_vid_cap()
922 ctx->colorspace = f->fmt.pix.colorspace; in coda_s_fmt_vid_out()
923 ctx->xfer_func = f->fmt.pix.xfer_func; in coda_s_fmt_vid_out()
924 ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; in coda_s_fmt_vid_out()
925 ctx->quantization = f->fmt.pix.quantization; in coda_s_fmt_vid_out()
927 if (ctx->inst_type != CODA_INST_DECODER) in coda_s_fmt_vid_out()
931 codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat, in coda_s_fmt_vid_out()
934 v4l2_err(&ctx->dev->v4l2_dev, "failed to determine codec\n"); in coda_s_fmt_vid_out()
935 return -EINVAL; in coda_s_fmt_vid_out()
937 ctx->codec = codec; in coda_s_fmt_vid_out()
939 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); in coda_s_fmt_vid_out()
941 return -EINVAL; in coda_s_fmt_vid_out()
955 f_cap.fmt.pix.width = f->fmt.pix.width; in coda_s_fmt_vid_out()
956 f_cap.fmt.pix.height = f->fmt.pix.height; in coda_s_fmt_vid_out()
967 ret = v4l2_m2m_reqbufs(file, ctx->fh.m2m_ctx, rb); in coda_reqbufs()
972 * Allow to allocate instance specific per-context buffers, such as in coda_reqbufs()
975 if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && ctx->ops->reqbufs) in coda_reqbufs()
976 return ctx->ops->reqbufs(ctx, rb); in coda_reqbufs()
986 if (ctx->inst_type == CODA_INST_DECODER && in coda_qbuf()
987 buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_qbuf()
988 buf->flags &= ~V4L2_BUF_FLAG_LAST; in coda_qbuf()
990 return v4l2_m2m_qbuf(file, ctx->fh.m2m_ctx, buf); in coda_qbuf()
998 ret = v4l2_m2m_dqbuf(file, ctx->fh.m2m_ctx, buf); in coda_dqbuf()
1000 if (ctx->inst_type == CODA_INST_DECODER && in coda_dqbuf()
1001 buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_dqbuf()
1002 buf->flags &= ~V4L2_BUF_FLAG_LAST; in coda_dqbuf()
1014 if (buf->flags & V4L2_BUF_FLAG_LAST) in coda_m2m_buf_done()
1015 v4l2_event_queue_fh(&ctx->fh, &eos_event); in coda_m2m_buf_done()
1027 q_data = get_q_data(ctx, s->type); in coda_g_selection()
1029 return -EINVAL; in coda_g_selection()
1033 r.width = q_data->width; in coda_g_selection()
1034 r.height = q_data->height; in coda_g_selection()
1035 rsel = &q_data->rect; in coda_g_selection()
1037 switch (s->target) { in coda_g_selection()
1043 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || in coda_g_selection()
1044 ctx->inst_type == CODA_INST_DECODER) in coda_g_selection()
1045 return -EINVAL; in coda_g_selection()
1053 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || in coda_g_selection()
1054 ctx->inst_type == CODA_INST_ENCODER) in coda_g_selection()
1055 return -EINVAL; in coda_g_selection()
1058 return -EINVAL; in coda_g_selection()
1061 s->r = *rsel; in coda_g_selection()
1072 switch (s->target) { in coda_s_selection()
1074 if (ctx->inst_type == CODA_INST_ENCODER && in coda_s_selection()
1075 s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_s_selection()
1076 q_data = get_q_data(ctx, s->type); in coda_s_selection()
1078 return -EINVAL; in coda_s_selection()
1080 s->r.left = 0; in coda_s_selection()
1081 s->r.top = 0; in coda_s_selection()
1082 s->r.width = clamp(s->r.width, 2U, q_data->width); in coda_s_selection()
1083 s->r.height = clamp(s->r.height, 2U, q_data->height); in coda_s_selection()
1085 if (s->flags & V4L2_SEL_FLAG_LE) { in coda_s_selection()
1086 s->r.width = round_up(s->r.width, 2); in coda_s_selection()
1087 s->r.height = round_up(s->r.height, 2); in coda_s_selection()
1089 s->r.width = round_down(s->r.width, 2); in coda_s_selection()
1090 s->r.height = round_down(s->r.height, 2); in coda_s_selection()
1093 q_data->rect = s->r; in coda_s_selection()
1096 s->r.width, s->r.height); in coda_s_selection()
1105 /* v4l2-compliance expects this to fail for read-only targets */ in coda_s_selection()
1106 return -EINVAL; in coda_s_selection()
1116 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); in coda_wake_up_capture_queue()
1117 dst_vq->last_buffer_dequeued = true; in coda_wake_up_capture_queue()
1118 wake_up(&dst_vq->done_wq); in coda_wake_up_capture_queue()
1132 mutex_lock(&ctx->wakeup_mutex); in coda_encoder_cmd()
1133 buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx); in coda_encoder_cmd()
1140 buf->flags |= V4L2_BUF_FLAG_LAST; in coda_encoder_cmd()
1142 /* Set the stream-end flag on this context */ in coda_encoder_cmd()
1143 ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; in coda_encoder_cmd()
1148 * via the -EPIPE mechanism. in coda_encoder_cmd()
1152 mutex_unlock(&ctx->wakeup_mutex); in coda_encoder_cmd()
1163 spin_lock(&ctx->buffer_meta_lock); in coda_mark_last_meta()
1164 if (list_empty(&ctx->buffer_meta_list)) { in coda_mark_last_meta()
1165 spin_unlock(&ctx->buffer_meta_lock); in coda_mark_last_meta()
1169 meta = list_last_entry(&ctx->buffer_meta_list, struct coda_buffer_meta, in coda_mark_last_meta()
1171 meta->last = true; in coda_mark_last_meta()
1173 spin_unlock(&ctx->buffer_meta_lock); in coda_mark_last_meta()
1186 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); in coda_mark_last_dst_buf()
1187 spin_lock_irqsave(&dst_vq->done_lock, flags); in coda_mark_last_dst_buf()
1188 if (list_empty(&dst_vq->done_list)) { in coda_mark_last_dst_buf()
1189 spin_unlock_irqrestore(&dst_vq->done_lock, flags); in coda_mark_last_dst_buf()
1193 dst_vb = list_last_entry(&dst_vq->done_list, struct vb2_buffer, in coda_mark_last_dst_buf()
1196 buf->flags |= V4L2_BUF_FLAG_LAST; in coda_mark_last_dst_buf()
1198 spin_unlock_irqrestore(&dst_vq->done_lock, flags); in coda_mark_last_dst_buf()
1206 struct coda_dev *dev = ctx->dev; in coda_decoder_cmd()
1217 switch (dc->cmd) { in coda_decoder_cmd()
1219 mutex_lock(&dev->coda_mutex); in coda_decoder_cmd()
1220 mutex_lock(&ctx->bitstream_mutex); in coda_decoder_cmd()
1222 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in coda_decoder_cmd()
1225 ctx->bit_stream_param &= ~CODA_BIT_STREAM_END_FLAG; in coda_decoder_cmd()
1227 mutex_unlock(&ctx->bitstream_mutex); in coda_decoder_cmd()
1228 mutex_unlock(&dev->coda_mutex); in coda_decoder_cmd()
1234 mutex_lock(&ctx->wakeup_mutex); in coda_decoder_cmd()
1236 buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx); in coda_decoder_cmd()
1241 buf->flags |= V4L2_BUF_FLAG_LAST; in coda_decoder_cmd()
1243 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) == 0) { in coda_decoder_cmd()
1248 if (ctx->use_bit) in coda_decoder_cmd()
1261 /* Set the stream-end flag on this context */ in coda_decoder_cmd()
1263 ctx->hold = false; in coda_decoder_cmd()
1264 v4l2_m2m_try_schedule(ctx->fh.m2m_ctx); in coda_decoder_cmd()
1272 mutex_unlock(&ctx->wakeup_mutex); in coda_decoder_cmd()
1275 return -EINVAL; in coda_decoder_cmd()
1288 if (fsize->index) in coda_enum_framesizes()
1289 return -EINVAL; in coda_enum_framesizes()
1291 if (coda_format_normalize_yuv(fsize->pixel_format) == in coda_enum_framesizes()
1294 codec = coda_find_codec(ctx->dev, fsize->pixel_format, in coda_enum_framesizes()
1295 q_data_dst->fourcc); in coda_enum_framesizes()
1297 codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, in coda_enum_framesizes()
1298 fsize->pixel_format); in coda_enum_framesizes()
1301 return -EINVAL; in coda_enum_framesizes()
1303 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; in coda_enum_framesizes()
1304 fsize->stepwise.min_width = MIN_W; in coda_enum_framesizes()
1305 fsize->stepwise.max_width = codec->max_w; in coda_enum_framesizes()
1306 fsize->stepwise.step_width = 1; in coda_enum_framesizes()
1307 fsize->stepwise.min_height = MIN_H; in coda_enum_framesizes()
1308 fsize->stepwise.max_height = codec->max_h; in coda_enum_framesizes()
1309 fsize->stepwise.step_height = 1; in coda_enum_framesizes()
1321 if (f->index) in coda_enum_frameintervals()
1322 return -EINVAL; in coda_enum_frameintervals()
1325 if (!ctx->vdoa && f->pixel_format == V4L2_PIX_FMT_YUYV) in coda_enum_frameintervals()
1326 return -EINVAL; in coda_enum_frameintervals()
1328 if (coda_format_normalize_yuv(f->pixel_format) == V4L2_PIX_FMT_YUV420) { in coda_enum_frameintervals()
1330 codec = coda_find_codec(ctx->dev, f->pixel_format, in coda_enum_frameintervals()
1331 q_data->fourcc); in coda_enum_frameintervals()
1333 codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, in coda_enum_frameintervals()
1334 f->pixel_format); in coda_enum_frameintervals()
1337 return -EINVAL; in coda_enum_frameintervals()
1339 if (f->width < MIN_W || f->width > codec->max_w || in coda_enum_frameintervals()
1340 f->height < MIN_H || f->height > codec->max_h) in coda_enum_frameintervals()
1341 return -EINVAL; in coda_enum_frameintervals()
1343 f->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; in coda_enum_frameintervals()
1344 f->stepwise.min.numerator = 1; in coda_enum_frameintervals()
1345 f->stepwise.min.denominator = 65535; in coda_enum_frameintervals()
1346 f->stepwise.max.numerator = 65536; in coda_enum_frameintervals()
1347 f->stepwise.max.denominator = 1; in coda_enum_frameintervals()
1348 f->stepwise.step.numerator = 1; in coda_enum_frameintervals()
1349 f->stepwise.step.denominator = 1; in coda_enum_frameintervals()
1359 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_g_parm()
1360 return -EINVAL; in coda_g_parm()
1362 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; in coda_g_parm()
1363 tpf = &a->parm.output.timeperframe; in coda_g_parm()
1364 tpf->denominator = ctx->params.framerate & CODA_FRATE_RES_MASK; in coda_g_parm()
1365 tpf->numerator = 1 + (ctx->params.framerate >> in coda_g_parm()
1373 * into the 16-bit CODA_FRATE_DIV and CODA_FRATE_RES fields.
1385 timeperframe->numerator = 1; in coda_approximate_timeperframe()
1386 timeperframe->denominator = 65535; in coda_approximate_timeperframe()
1392 timeperframe->numerator = 65536; in coda_approximate_timeperframe()
1393 timeperframe->denominator = 1; in coda_approximate_timeperframe()
1433 return ((timeperframe->numerator - 1) << CODA_FRATE_DIV_OFFSET) | in coda_timeperframe_to_frate()
1434 timeperframe->denominator; in coda_timeperframe_to_frate()
1442 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_s_parm()
1443 return -EINVAL; in coda_s_parm()
1445 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; in coda_s_parm()
1446 tpf = &a->parm.output.timeperframe; in coda_s_parm()
1448 ctx->params.framerate = coda_timeperframe_to_frate(tpf); in coda_s_parm()
1449 ctx->params.framerate_changed = true; in coda_s_parm()
1459 switch (sub->type) { in coda_subscribe_event()
1463 if (ctx->inst_type == CODA_INST_DECODER) in coda_subscribe_event()
1466 return -EINVAL; in coda_subscribe_event()
1516 * Mem-to-mem operations.
1522 struct coda_dev *dev = ctx->dev; in coda_device_run()
1524 queue_work(dev->workqueue, &ctx->pic_run_work); in coda_device_run()
1530 struct coda_dev *dev = ctx->dev; in coda_pic_run_work()
1533 mutex_lock(&ctx->buffer_mutex); in coda_pic_run_work()
1534 mutex_lock(&dev->coda_mutex); in coda_pic_run_work()
1536 ret = ctx->ops->prepare_run(ctx); in coda_pic_run_work()
1537 if (ret < 0 && ctx->inst_type == CODA_INST_DECODER) in coda_pic_run_work()
1540 if (!wait_for_completion_timeout(&ctx->completion, in coda_pic_run_work()
1542 if (ctx->use_bit) { in coda_pic_run_work()
1543 dev_err(dev->dev, "CODA PIC_RUN timeout\n"); in coda_pic_run_work()
1545 ctx->hold = true; in coda_pic_run_work()
1550 if (ctx->ops->run_timeout) in coda_pic_run_work()
1551 ctx->ops->run_timeout(ctx); in coda_pic_run_work()
1553 ctx->ops->finish_run(ctx); in coda_pic_run_work()
1556 if ((ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out)) && in coda_pic_run_work()
1557 ctx->ops->seq_end_work) in coda_pic_run_work()
1558 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_pic_run_work()
1561 mutex_unlock(&dev->coda_mutex); in coda_pic_run_work()
1562 mutex_unlock(&ctx->buffer_mutex); in coda_pic_run_work()
1564 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); in coda_pic_run_work()
1570 int src_bufs = v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx); in coda_job_ready()
1577 if (!src_bufs && ctx->inst_type != CODA_INST_DECODER) { in coda_job_ready()
1578 coda_dbg(1, ctx, "not ready: not enough vid-out buffers.\n"); in coda_job_ready()
1582 if (!v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) { in coda_job_ready()
1583 coda_dbg(1, ctx, "not ready: not enough vid-cap buffers.\n"); in coda_job_ready()
1587 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) { in coda_job_ready()
1588 bool stream_end = ctx->bit_stream_param & in coda_job_ready()
1590 int num_metas = ctx->num_metas; in coda_job_ready()
1594 count = hweight32(ctx->frm_dis_flg); in coda_job_ready()
1595 if (ctx->use_vdoa && count >= (ctx->num_internal_frames - 1)) { in coda_job_ready()
1598 count, ctx->num_internal_frames, in coda_job_ready()
1599 ctx->frm_dis_flg); in coda_job_ready()
1603 if (ctx->hold && !src_bufs) { in coda_job_ready()
1616 meta = list_first_entry(&ctx->buffer_meta_list, in coda_job_ready()
1618 if (!coda_bitstream_can_fetch_past(ctx, meta->end) && in coda_job_ready()
1622 meta->end, ctx->bitstream_fifo.kfifo.in); in coda_job_ready()
1627 if (ctx->aborting) { in coda_job_ready()
1641 ctx->aborting = 1; in coda_job_abort()
1656 ctx->codec = coda_find_codec(ctx->dev, ctx->cvd->src_formats[0], in set_default_params()
1657 ctx->cvd->dst_formats[0]); in set_default_params()
1658 max_w = min(ctx->codec->max_w, 1920U); in set_default_params()
1659 max_h = min(ctx->codec->max_h, 1088U); in set_default_params()
1663 ctx->params.codec_mode = ctx->codec->mode; in set_default_params()
1664 if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_JPEG || in set_default_params()
1665 ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG) { in set_default_params()
1666 ctx->colorspace = V4L2_COLORSPACE_SRGB; in set_default_params()
1667 ctx->xfer_func = V4L2_XFER_FUNC_SRGB; in set_default_params()
1668 ctx->ycbcr_enc = V4L2_YCBCR_ENC_601; in set_default_params()
1669 ctx->quantization = V4L2_QUANTIZATION_FULL_RANGE; in set_default_params()
1671 ctx->colorspace = V4L2_COLORSPACE_REC709; in set_default_params()
1672 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; in set_default_params()
1673 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in set_default_params()
1674 ctx->quantization = V4L2_QUANTIZATION_DEFAULT; in set_default_params()
1676 ctx->params.framerate = 30; in set_default_params()
1679 ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->cvd->src_formats[0]; in set_default_params()
1680 ctx->q_data[V4L2_M2M_DST].fourcc = ctx->cvd->dst_formats[0]; in set_default_params()
1681 ctx->q_data[V4L2_M2M_SRC].width = max_w; in set_default_params()
1682 ctx->q_data[V4L2_M2M_SRC].height = max_h; in set_default_params()
1683 ctx->q_data[V4L2_M2M_DST].width = max_w; in set_default_params()
1684 ctx->q_data[V4L2_M2M_DST].height = max_h; in set_default_params()
1685 if (ctx->codec->src_fourcc == V4L2_PIX_FMT_YUV420) { in set_default_params()
1686 ctx->q_data[V4L2_M2M_SRC].bytesperline = max_w; in set_default_params()
1687 ctx->q_data[V4L2_M2M_SRC].sizeimage = usize; in set_default_params()
1688 ctx->q_data[V4L2_M2M_DST].bytesperline = 0; in set_default_params()
1689 ctx->q_data[V4L2_M2M_DST].sizeimage = csize; in set_default_params()
1691 ctx->q_data[V4L2_M2M_SRC].bytesperline = 0; in set_default_params()
1692 ctx->q_data[V4L2_M2M_SRC].sizeimage = csize; in set_default_params()
1693 ctx->q_data[V4L2_M2M_DST].bytesperline = max_w; in set_default_params()
1694 ctx->q_data[V4L2_M2M_DST].sizeimage = usize; in set_default_params()
1696 ctx->q_data[V4L2_M2M_SRC].rect.width = max_w; in set_default_params()
1697 ctx->q_data[V4L2_M2M_SRC].rect.height = max_h; in set_default_params()
1698 ctx->q_data[V4L2_M2M_DST].rect.width = max_w; in set_default_params()
1699 ctx->q_data[V4L2_M2M_DST].rect.height = max_h; in set_default_params()
1705 ctx->tiled_map_type = GDI_LINEAR_FRAME_MAP; in set_default_params()
1719 q_data = get_q_data(ctx, vq->type); in coda_queue_setup()
1720 size = q_data->sizeimage; in coda_queue_setup()
1723 return sizes[0] < size ? -EINVAL : 0; in coda_queue_setup()
1737 struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in coda_buf_prepare()
1740 q_data = get_q_data(ctx, vb->vb2_queue->type); in coda_buf_prepare()
1741 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { in coda_buf_prepare()
1742 if (vbuf->field == V4L2_FIELD_ANY) in coda_buf_prepare()
1743 vbuf->field = V4L2_FIELD_NONE; in coda_buf_prepare()
1744 if (vbuf->field != V4L2_FIELD_NONE) { in coda_buf_prepare()
1745 v4l2_warn(&ctx->dev->v4l2_dev, in coda_buf_prepare()
1747 return -EINVAL; in coda_buf_prepare()
1751 if (vb2_plane_size(vb, 0) < q_data->sizeimage) { in coda_buf_prepare()
1752 v4l2_warn(&ctx->dev->v4l2_dev, in coda_buf_prepare()
1755 (long)q_data->sizeimage); in coda_buf_prepare()
1756 return -EINVAL; in coda_buf_prepare()
1773 if (value > ctrl->maximum) { in coda_update_menu_ctrl()
1774 __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, value, in coda_update_menu_ctrl()
1775 ctrl->menu_skip_mask & ~(1 << value), in coda_update_menu_ctrl()
1776 ctrl->default_value); in coda_update_menu_ctrl()
1777 } else if (value < ctrl->minimum) { in coda_update_menu_ctrl()
1778 __v4l2_ctrl_modify_range(ctrl, value, ctrl->maximum, in coda_update_menu_ctrl()
1779 ctrl->menu_skip_mask & ~(1 << value), in coda_update_menu_ctrl()
1780 ctrl->default_value); in coda_update_menu_ctrl()
1801 switch (ctx->codec->src_fourcc) { in coda_update_profile_level_ctrls()
1806 profile_ctrl = ctx->h264_profile_ctrl; in coda_update_profile_level_ctrls()
1807 level_ctrl = ctx->h264_level_ctrl; in coda_update_profile_level_ctrls()
1812 codec_name = "MPEG-2"; in coda_update_profile_level_ctrls()
1815 profile_ctrl = ctx->mpeg2_profile_ctrl; in coda_update_profile_level_ctrls()
1816 level_ctrl = ctx->mpeg2_level_ctrl; in coda_update_profile_level_ctrls()
1821 codec_name = "MPEG-4"; in coda_update_profile_level_ctrls()
1824 profile_ctrl = ctx->mpeg4_profile_ctrl; in coda_update_profile_level_ctrls()
1825 level_ctrl = ctx->mpeg4_level_ctrl; in coda_update_profile_level_ctrls()
1837 v4l2_warn(&ctx->dev->v4l2_dev, "Invalid %s profile: %u\n", in coda_update_profile_level_ctrls()
1846 v4l2_warn(&ctx->dev->v4l2_dev, "Invalid %s level: %u\n", in coda_update_profile_level_ctrls()
1862 v4l2_event_queue_fh(&ctx->fh, &source_change_event); in coda_queue_source_change_event()
1868 struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in coda_buf_queue()
1869 struct vb2_queue *vq = vb->vb2_queue; in coda_buf_queue()
1872 q_data = get_q_data(ctx, vb->vb2_queue->type); in coda_buf_queue()
1878 if (ctx->bitstream.size && vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_buf_queue()
1886 if (q_data->fourcc == V4L2_PIX_FMT_H264) { in coda_buf_queue()
1893 if (!ctx->params.h264_profile_idc) { in coda_buf_queue()
1896 ctx->params.h264_profile_idc, in coda_buf_queue()
1897 ctx->params.h264_level_idc); in coda_buf_queue()
1901 mutex_lock(&ctx->bitstream_mutex); in coda_buf_queue()
1902 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in coda_buf_queue()
1903 if (vb2_is_streaming(vb->vb2_queue)) in coda_buf_queue()
1904 /* This set buf->sequence = ctx->qsequence++ */ in coda_buf_queue()
1906 mutex_unlock(&ctx->bitstream_mutex); in coda_buf_queue()
1908 if (!ctx->initialized) { in coda_buf_queue()
1913 if (vb2_is_streaming(vb->vb2_queue) && in coda_buf_queue()
1914 ctx->ops->seq_init_work) { in coda_buf_queue()
1915 queue_work(ctx->dev->workqueue, in coda_buf_queue()
1916 &ctx->seq_init_work); in coda_buf_queue()
1917 flush_work(&ctx->seq_init_work); in coda_buf_queue()
1920 if (ctx->initialized) in coda_buf_queue()
1924 if ((ctx->inst_type == CODA_INST_ENCODER || !ctx->use_bit) && in coda_buf_queue()
1925 vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_buf_queue()
1926 vbuf->sequence = ctx->qsequence++; in coda_buf_queue()
1927 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in coda_buf_queue()
1934 buf->vaddr = dma_alloc_coherent(dev->dev, size, &buf->paddr, in coda_alloc_aux_buf()
1936 if (!buf->vaddr) { in coda_alloc_aux_buf()
1937 v4l2_err(&dev->v4l2_dev, in coda_alloc_aux_buf()
1940 return -ENOMEM; in coda_alloc_aux_buf()
1943 buf->size = size; in coda_alloc_aux_buf()
1946 buf->blob.data = buf->vaddr; in coda_alloc_aux_buf()
1947 buf->blob.size = size; in coda_alloc_aux_buf()
1948 buf->dentry = debugfs_create_blob(name, 0444, parent, in coda_alloc_aux_buf()
1949 &buf->blob); in coda_alloc_aux_buf()
1958 if (buf->vaddr) { in coda_free_aux_buf()
1959 dma_free_coherent(dev->dev, buf->size, buf->vaddr, buf->paddr); in coda_free_aux_buf()
1960 buf->vaddr = NULL; in coda_free_aux_buf()
1961 buf->size = 0; in coda_free_aux_buf()
1962 debugfs_remove(buf->dentry); in coda_free_aux_buf()
1963 buf->dentry = NULL; in coda_free_aux_buf()
1970 struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev; in coda_start_streaming()
1978 return -EINVAL; in coda_start_streaming()
1980 coda_dbg(1, ctx, "start streaming %s\n", v4l2_type_names[q->type]); in coda_start_streaming()
1985 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
1986 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) { in coda_start_streaming()
1988 mutex_lock(&ctx->bitstream_mutex); in coda_start_streaming()
1990 mutex_unlock(&ctx->bitstream_mutex); in coda_start_streaming()
1992 if (ctx->dev->devtype->product != CODA_960 && in coda_start_streaming()
1995 ret = -EINVAL; in coda_start_streaming()
1999 if (!ctx->initialized) { in coda_start_streaming()
2001 if (ctx->ops->seq_init_work) { in coda_start_streaming()
2002 queue_work(ctx->dev->workqueue, in coda_start_streaming()
2003 &ctx->seq_init_work); in coda_start_streaming()
2004 flush_work(&ctx->seq_init_work); in coda_start_streaming()
2013 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG) { in coda_start_streaming()
2014 buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in coda_start_streaming()
2015 coda_jpeg_decode_header(ctx, &buf->vb2_buf); in coda_start_streaming()
2024 q_data_dst->width = round_up(q_data_src->width, 16); in coda_start_streaming()
2025 q_data_dst->height = round_up(q_data_src->height, 16); in coda_start_streaming()
2026 q_data_dst->bytesperline = q_data_dst->width; in coda_start_streaming()
2027 if (ctx->params.jpeg_chroma_subsampling == in coda_start_streaming()
2029 q_data_dst->sizeimage = in coda_start_streaming()
2030 q_data_dst->bytesperline * in coda_start_streaming()
2031 q_data_dst->height * 3 / 2; in coda_start_streaming()
2032 if (q_data_dst->fourcc != V4L2_PIX_FMT_YUV420) in coda_start_streaming()
2033 q_data_dst->fourcc = V4L2_PIX_FMT_NV12; in coda_start_streaming()
2035 q_data_dst->sizeimage = in coda_start_streaming()
2036 q_data_dst->bytesperline * in coda_start_streaming()
2037 q_data_dst->height * 2; in coda_start_streaming()
2038 q_data_dst->fourcc = V4L2_PIX_FMT_YUV422P; in coda_start_streaming()
2040 q_data_dst->rect.left = 0; in coda_start_streaming()
2041 q_data_dst->rect.top = 0; in coda_start_streaming()
2042 q_data_dst->rect.width = q_data_src->width; in coda_start_streaming()
2043 q_data_dst->rect.height = q_data_src->height; in coda_start_streaming()
2045 ctx->streamon_out = 1; in coda_start_streaming()
2047 ctx->streamon_cap = 1; in coda_start_streaming()
2051 if (!(ctx->streamon_out && ctx->streamon_cap)) in coda_start_streaming()
2055 if ((q_data_src->rect.width != q_data_dst->width && in coda_start_streaming()
2056 round_up(q_data_src->rect.width, 16) != q_data_dst->width) || in coda_start_streaming()
2057 (q_data_src->rect.height != q_data_dst->height && in coda_start_streaming()
2058 round_up(q_data_src->rect.height, 16) != q_data_dst->height)) { in coda_start_streaming()
2060 q_data_src->rect.width, q_data_src->rect.height, in coda_start_streaming()
2061 q_data_dst->width, q_data_dst->height); in coda_start_streaming()
2062 ret = -EINVAL; in coda_start_streaming()
2067 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) in coda_start_streaming()
2068 v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); in coda_start_streaming()
2070 ctx->gopcounter = ctx->params.gop_size - 1; in coda_start_streaming()
2072 if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG) in coda_start_streaming()
2073 ctx->params.gop_size = 1; in coda_start_streaming()
2074 ctx->gopcounter = ctx->params.gop_size - 1; in coda_start_streaming()
2076 if (ctx->mb_err_cnt_ctrl) in coda_start_streaming()
2077 v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, 0); in coda_start_streaming()
2079 ret = ctx->ops->start_streaming(ctx); in coda_start_streaming()
2080 if (ctx->inst_type == CODA_INST_DECODER) { in coda_start_streaming()
2081 if (ret == -EAGAIN) in coda_start_streaming()
2088 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
2090 list_del(&m2m_buf->list); in coda_start_streaming()
2091 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_DONE); in coda_start_streaming()
2097 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
2099 list_del(&m2m_buf->list); in coda_start_streaming()
2100 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_QUEUED); in coda_start_streaming()
2102 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) in coda_start_streaming()
2105 while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) in coda_start_streaming()
2114 struct coda_dev *dev = ctx->dev; in coda_stop_streaming()
2118 stop = ctx->streamon_out && ctx->streamon_cap; in coda_stop_streaming()
2120 coda_dbg(1, ctx, "stop streaming %s\n", v4l2_type_names[q->type]); in coda_stop_streaming()
2122 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_stop_streaming()
2123 ctx->streamon_out = 0; in coda_stop_streaming()
2127 ctx->qsequence = 0; in coda_stop_streaming()
2129 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) in coda_stop_streaming()
2132 ctx->streamon_cap = 0; in coda_stop_streaming()
2134 ctx->osequence = 0; in coda_stop_streaming()
2135 ctx->sequence_offset = 0; in coda_stop_streaming()
2137 while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) in coda_stop_streaming()
2144 if (ctx->ops->seq_end_work) { in coda_stop_streaming()
2145 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_stop_streaming()
2146 flush_work(&ctx->seq_end_work); in coda_stop_streaming()
2148 spin_lock(&ctx->buffer_meta_lock); in coda_stop_streaming()
2149 while (!list_empty(&ctx->buffer_meta_list)) { in coda_stop_streaming()
2150 meta = list_first_entry(&ctx->buffer_meta_list, in coda_stop_streaming()
2152 list_del(&meta->list); in coda_stop_streaming()
2155 ctx->num_metas = 0; in coda_stop_streaming()
2156 spin_unlock(&ctx->buffer_meta_lock); in coda_stop_streaming()
2157 kfifo_init(&ctx->bitstream_fifo, in coda_stop_streaming()
2158 ctx->bitstream.vaddr, ctx->bitstream.size); in coda_stop_streaming()
2159 ctx->runcounter = 0; in coda_stop_streaming()
2160 ctx->aborting = 0; in coda_stop_streaming()
2161 ctx->hold = false; in coda_stop_streaming()
2164 if (!ctx->streamon_out && !ctx->streamon_cap) in coda_stop_streaming()
2165 ctx->bit_stream_param &= ~CODA_BIT_STREAM_END_FLAG; in coda_stop_streaming()
2180 const char * const *val_names = v4l2_ctrl_get_menu(ctrl->id); in coda_s_ctrl()
2182 container_of(ctrl->handler, struct coda_ctx, ctrls); in coda_s_ctrl()
2186 ctrl->id, ctrl->name, ctrl->val, val_names[ctrl->val]); in coda_s_ctrl()
2189 ctrl->id, ctrl->name, ctrl->val); in coda_s_ctrl()
2191 switch (ctrl->id) { in coda_s_ctrl()
2193 if (ctrl->val) in coda_s_ctrl()
2194 ctx->params.rot_mode |= CODA_MIR_HOR; in coda_s_ctrl()
2196 ctx->params.rot_mode &= ~CODA_MIR_HOR; in coda_s_ctrl()
2199 if (ctrl->val) in coda_s_ctrl()
2200 ctx->params.rot_mode |= CODA_MIR_VER; in coda_s_ctrl()
2202 ctx->params.rot_mode &= ~CODA_MIR_VER; in coda_s_ctrl()
2205 ctx->params.bitrate = ctrl->val / 1000; in coda_s_ctrl()
2206 ctx->params.bitrate_changed = true; in coda_s_ctrl()
2209 ctx->params.gop_size = ctrl->val; in coda_s_ctrl()
2212 ctx->params.h264_intra_qp = ctrl->val; in coda_s_ctrl()
2213 ctx->params.h264_intra_qp_changed = true; in coda_s_ctrl()
2216 ctx->params.h264_inter_qp = ctrl->val; in coda_s_ctrl()
2219 ctx->params.h264_min_qp = ctrl->val; in coda_s_ctrl()
2222 ctx->params.h264_max_qp = ctrl->val; in coda_s_ctrl()
2225 ctx->params.h264_slice_alpha_c0_offset_div2 = ctrl->val; in coda_s_ctrl()
2228 ctx->params.h264_slice_beta_offset_div2 = ctrl->val; in coda_s_ctrl()
2231 ctx->params.h264_disable_deblocking_filter_idc = ctrl->val; in coda_s_ctrl()
2234 ctx->params.h264_constrained_intra_pred_flag = ctrl->val; in coda_s_ctrl()
2237 ctx->params.frame_rc_enable = ctrl->val; in coda_s_ctrl()
2240 ctx->params.mb_rc_enable = ctrl->val; in coda_s_ctrl()
2243 ctx->params.h264_chroma_qp_index_offset = ctrl->val; in coda_s_ctrl()
2247 if (ctx->inst_type == CODA_INST_ENCODER) in coda_s_ctrl()
2248 ctx->params.h264_profile_idc = 66; in coda_s_ctrl()
2254 ctx->params.mpeg4_intra_qp = ctrl->val; in coda_s_ctrl()
2257 ctx->params.mpeg4_inter_qp = ctrl->val; in coda_s_ctrl()
2266 ctx->params.slice_mode = ctrl->val; in coda_s_ctrl()
2267 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2270 ctx->params.slice_max_mb = ctrl->val; in coda_s_ctrl()
2271 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2274 ctx->params.slice_max_bits = ctrl->val * 8; in coda_s_ctrl()
2275 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2280 ctx->params.intra_refresh = ctrl->val; in coda_s_ctrl()
2281 ctx->params.intra_refresh_changed = true; in coda_s_ctrl()
2284 ctx->params.force_ipicture = true; in coda_s_ctrl()
2287 coda_set_jpeg_compression_quality(ctx, ctrl->val); in coda_s_ctrl()
2290 ctx->params.jpeg_restart_interval = ctrl->val; in coda_s_ctrl()
2293 ctx->params.vbv_delay = ctrl->val; in coda_s_ctrl()
2296 ctx->params.vbv_size = min(ctrl->val * 8192, 0x7fffffff); in coda_s_ctrl()
2300 ctrl->id, ctrl->val); in coda_s_ctrl()
2301 return -EINVAL; in coda_s_ctrl()
2313 int max_gop_size = (ctx->dev->devtype->product == CODA_DX6) ? 60 : 99; in coda_encode_ctrls()
2315 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2317 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2319 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2321 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2323 if (ctx->dev->devtype->product != CODA_960) { in coda_encode_ctrls()
2324 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2327 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2329 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2330 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, -6, 6, 1, 0); in coda_encode_ctrls()
2331 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2332 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0); in coda_encode_ctrls()
2333 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2337 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2340 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2342 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2344 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2345 V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, -12, 12, 1, 0); in coda_encode_ctrls()
2346 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2350 if (ctx->dev->devtype->product == CODA_HX4 || in coda_encode_ctrls()
2351 ctx->dev->devtype->product == CODA_7541) { in coda_encode_ctrls()
2352 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2360 if (ctx->dev->devtype->product == CODA_960) { in coda_encode_ctrls()
2361 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2374 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2376 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2378 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2382 if (ctx->dev->devtype->product == CODA_HX4 || in coda_encode_ctrls()
2383 ctx->dev->devtype->product == CODA_7541 || in coda_encode_ctrls()
2384 ctx->dev->devtype->product == CODA_960) { in coda_encode_ctrls()
2385 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2391 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2395 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2397 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2400 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2405 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2408 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2414 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2420 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_jpeg_encode_ctrls()
2422 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_jpeg_encode_ctrls()
2430 ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2437 if (ctx->h264_profile_ctrl) in coda_decode_ctrls()
2438 ctx->h264_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2440 if (ctx->dev->devtype->product == CODA_HX4 || in coda_decode_ctrls()
2441 ctx->dev->devtype->product == CODA_7541) in coda_decode_ctrls()
2443 else if (ctx->dev->devtype->product == CODA_960) in coda_decode_ctrls()
2447 ctx->h264_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2449 if (ctx->h264_level_ctrl) in coda_decode_ctrls()
2450 ctx->h264_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2452 ctx->mpeg2_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2456 if (ctx->mpeg2_profile_ctrl) in coda_decode_ctrls()
2457 ctx->mpeg2_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2459 ctx->mpeg2_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2463 if (ctx->mpeg2_level_ctrl) in coda_decode_ctrls()
2464 ctx->mpeg2_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2466 ctx->mpeg4_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2470 if (ctx->mpeg4_profile_ctrl) in coda_decode_ctrls()
2471 ctx->mpeg4_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2473 ctx->mpeg4_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2477 if (ctx->mpeg4_level_ctrl) in coda_decode_ctrls()
2478 ctx->mpeg4_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2492 v4l2_ctrl_handler_init(&ctx->ctrls, 2); in coda_ctrls_setup()
2494 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2496 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2498 if (ctx->inst_type == CODA_INST_ENCODER) { in coda_ctrls_setup()
2499 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2502 if (ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG) in coda_ctrls_setup()
2507 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2510 if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_H264) in coda_ctrls_setup()
2513 ctx->mb_err_cnt_ctrl = v4l2_ctrl_new_custom(&ctx->ctrls, in coda_ctrls_setup()
2516 if (ctx->mb_err_cnt_ctrl) in coda_ctrls_setup()
2517 ctx->mb_err_cnt_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_ctrls_setup()
2520 if (ctx->ctrls.error) { in coda_ctrls_setup()
2521 v4l2_err(&ctx->dev->v4l2_dev, in coda_ctrls_setup()
2523 ctx->ctrls.error); in coda_ctrls_setup()
2524 return -EINVAL; in coda_ctrls_setup()
2527 return v4l2_ctrl_handler_setup(&ctx->ctrls); in coda_ctrls_setup()
2532 vq->drv_priv = ctx; in coda_queue_init()
2533 vq->ops = &coda_qops; in coda_queue_init()
2534 vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in coda_queue_init()
2535 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in coda_queue_init()
2536 vq->lock = &ctx->dev->dev_mutex; in coda_queue_init()
2537 /* One way to indicate end-of-stream for coda is to set the in coda_queue_init()
2543 vq->allow_zero_bytesused = 1; in coda_queue_init()
2549 vq->min_queued_buffers = 1; in coda_queue_init()
2550 vq->dev = ctx->dev->dev; in coda_queue_init()
2560 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in coda_encoder_queue_init()
2561 src_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_encoder_queue_init()
2562 src_vq->mem_ops = &vb2_dma_contig_memops; in coda_encoder_queue_init()
2568 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in coda_encoder_queue_init()
2569 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_encoder_queue_init()
2570 dst_vq->mem_ops = &vb2_dma_contig_memops; in coda_encoder_queue_init()
2580 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in coda_decoder_queue_init()
2581 src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; in coda_decoder_queue_init()
2582 src_vq->mem_ops = &vb2_vmalloc_memops; in coda_decoder_queue_init()
2588 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in coda_decoder_queue_init()
2589 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_decoder_queue_init()
2590 dst_vq->dma_attrs = DMA_ATTR_NO_KERNEL_MAPPING; in coda_decoder_queue_init()
2591 dst_vq->mem_ops = &vb2_dma_contig_memops; in coda_decoder_queue_init()
2612 return -ENOMEM; in coda_open()
2614 if (dev->devtype->product == CODA_DX6) in coda_open()
2615 max = CODADX6_MAX_INSTANCES - 1; in coda_open()
2616 idx = ida_alloc_max(&dev->ida, max, GFP_KERNEL); in coda_open()
2624 ret = -ENOMEM; in coda_open()
2628 ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); in coda_open()
2631 ctx->cvd = to_coda_video_device(vdev); in coda_open()
2632 ctx->inst_type = ctx->cvd->type; in coda_open()
2633 ctx->ops = ctx->cvd->ops; in coda_open()
2634 ctx->use_bit = !ctx->cvd->direct; in coda_open()
2635 init_completion(&ctx->completion); in coda_open()
2636 INIT_WORK(&ctx->pic_run_work, coda_pic_run_work); in coda_open()
2637 if (ctx->ops->seq_init_work) in coda_open()
2638 INIT_WORK(&ctx->seq_init_work, ctx->ops->seq_init_work); in coda_open()
2639 if (ctx->ops->seq_end_work) in coda_open()
2640 INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work); in coda_open()
2641 v4l2_fh_init(&ctx->fh, video_devdata(file)); in coda_open()
2642 file->private_data = &ctx->fh; in coda_open()
2643 v4l2_fh_add(&ctx->fh); in coda_open()
2644 ctx->dev = dev; in coda_open()
2645 ctx->idx = idx; in coda_open()
2649 switch (dev->devtype->product) { in coda_open()
2657 if (enable_bwb || ctx->inst_type == CODA_INST_ENCODER) in coda_open()
2658 ctx->frame_mem_ctrl = CODA9_FRAME_ENABLE_BWB; in coda_open()
2662 ctx->reg_idx = 0; in coda_open()
2665 ctx->reg_idx = idx; in coda_open()
2667 if (ctx->dev->vdoa && !disable_vdoa) { in coda_open()
2668 ctx->vdoa = vdoa_context_create(dev->vdoa); in coda_open()
2669 if (!ctx->vdoa) in coda_open()
2670 v4l2_warn(&dev->v4l2_dev, in coda_open()
2673 ctx->use_vdoa = false; in coda_open()
2676 ret = pm_runtime_resume_and_get(dev->dev); in coda_open()
2678 v4l2_err(&dev->v4l2_dev, "failed to power up: %d\n", ret); in coda_open()
2682 ret = clk_prepare_enable(dev->clk_per); in coda_open()
2686 ret = clk_prepare_enable(dev->clk_ahb); in coda_open()
2691 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, in coda_open()
2692 ctx->ops->queue_init); in coda_open()
2693 if (IS_ERR(ctx->fh.m2m_ctx)) { in coda_open()
2694 ret = PTR_ERR(ctx->fh.m2m_ctx); in coda_open()
2696 v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n", in coda_open()
2703 v4l2_err(&dev->v4l2_dev, "failed to setup coda controls\n"); in coda_open()
2707 ctx->fh.ctrl_handler = &ctx->ctrls; in coda_open()
2709 mutex_init(&ctx->bitstream_mutex); in coda_open()
2710 mutex_init(&ctx->buffer_mutex); in coda_open()
2711 mutex_init(&ctx->wakeup_mutex); in coda_open()
2712 INIT_LIST_HEAD(&ctx->buffer_meta_list); in coda_open()
2713 spin_lock_init(&ctx->buffer_meta_lock); in coda_open()
2718 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in coda_open()
2720 clk_disable_unprepare(dev->clk_ahb); in coda_open()
2722 clk_disable_unprepare(dev->clk_per); in coda_open()
2724 pm_runtime_put_sync(dev->dev); in coda_open()
2726 v4l2_fh_del(&ctx->fh); in coda_open()
2727 v4l2_fh_exit(&ctx->fh); in coda_open()
2729 ida_free(&dev->ida, ctx->idx); in coda_open()
2738 struct coda_ctx *ctx = fh_to_ctx(file->private_data); in coda_release()
2742 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) in coda_release()
2746 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in coda_release()
2748 if (ctx->vdoa) in coda_release()
2749 vdoa_context_destroy(ctx->vdoa); in coda_release()
2752 if (ctx->ops->seq_end_work) { in coda_release()
2753 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_release()
2754 flush_work(&ctx->seq_end_work); in coda_release()
2757 if (ctx->dev->devtype->product == CODA_DX6) in coda_release()
2758 coda_free_aux_buf(dev, &ctx->workbuf); in coda_release()
2760 v4l2_ctrl_handler_free(&ctx->ctrls); in coda_release()
2761 clk_disable_unprepare(dev->clk_ahb); in coda_release()
2762 clk_disable_unprepare(dev->clk_per); in coda_release()
2763 pm_runtime_put_sync(dev->dev); in coda_release()
2764 v4l2_fh_del(&ctx->fh); in coda_release()
2765 v4l2_fh_exit(&ctx->fh); in coda_release()
2766 ida_free(&dev->ida, ctx->idx); in coda_release()
2767 if (ctx->ops->release) in coda_release()
2768 ctx->ops->release(ctx); in coda_release()
2769 debugfs_remove_recursive(ctx->debugfs_entry); in coda_release()
2790 ret = clk_prepare_enable(dev->clk_per); in coda_hw_init()
2794 ret = clk_prepare_enable(dev->clk_ahb); in coda_hw_init()
2798 reset_control_reset(dev->rstc); in coda_hw_init()
2802 * The 16-bit chars in the code buffer are in memory access in coda_hw_init()
2803 * order, re-sort them to CODA order for register download. in coda_hw_init()
2806 p = (u16 *)dev->codebuf.vaddr; in coda_hw_init()
2807 if (dev->devtype->product == CODA_DX6) { in coda_hw_init()
2817 3 - (i % 4)]); in coda_hw_init()
2827 if (dev->devtype->product == CODA_960 || in coda_hw_init()
2828 dev->devtype->product == CODA_7541 || in coda_hw_init()
2829 dev->devtype->product == CODA_HX4) { in coda_hw_init()
2830 coda_write(dev, dev->tempbuf.paddr, in coda_hw_init()
2834 coda_write(dev, dev->workbuf.paddr, in coda_hw_init()
2837 coda_write(dev, dev->codebuf.paddr, in coda_hw_init()
2842 switch (dev->devtype->product) { in coda_hw_init()
2851 if (dev->devtype->product == CODA_960) in coda_hw_init()
2857 if (dev->devtype->product != CODA_DX6) in coda_hw_init()
2863 /* Reset VPU and start processor */ in coda_hw_init()
2872 clk_disable_unprepare(dev->clk_ahb); in coda_hw_init()
2873 clk_disable_unprepare(dev->clk_per); in coda_hw_init()
2878 clk_disable_unprepare(dev->clk_per); in coda_hw_init()
2885 struct video_device *vfd = &dev->vfd[i]; in coda_register_device()
2889 if (i >= dev->devtype->num_vdevs) in coda_register_device()
2890 return -EINVAL; in coda_register_device()
2891 name = dev->devtype->vdevs[i]->name; in coda_register_device()
2893 strscpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name)); in coda_register_device()
2894 vfd->fops = &coda_fops; in coda_register_device()
2895 vfd->ioctl_ops = &coda_ioctl_ops; in coda_register_device()
2896 vfd->release = video_device_release_empty; in coda_register_device()
2897 vfd->lock = &dev->dev_mutex; in coda_register_device()
2898 vfd->v4l2_dev = &dev->v4l2_dev; in coda_register_device()
2899 vfd->vfl_dir = VFL_DIR_M2M; in coda_register_device()
2900 vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; in coda_register_device()
2908 if (dev->devtype->vdevs[i]->type == CODA_INST_ENCODER) { in coda_register_device()
2911 if (dev->devtype->vdevs[i]->dst_formats[0] == V4L2_PIX_FMT_JPEG) { in coda_register_device()
2927 v4l2_info(&dev->v4l2_dev, "%s registered as %s\n", in coda_register_device()
2937 /* Check if the firmware has a 16-byte Freescale header, skip it */ in coda_copy_firmware()
2941 * Check whether the firmware is in native order or pre-reordered for in coda_copy_firmware()
2945 u32 *dst = dev->codebuf.vaddr; in coda_copy_firmware()
2949 if (dev->devtype->product == CODA_DX6) { in coda_copy_firmware()
2950 for (i = 0; i < (size - 16) / 4; i++) in coda_copy_firmware()
2953 for (i = 0; i < (size - 16) / 4; i += 2) { in coda_copy_firmware()
2960 memcpy(dev->codebuf.vaddr, src, size); in coda_copy_firmware()
2970 if (dev->firmware >= ARRAY_SIZE(dev->devtype->firmware)) in coda_firmware_request()
2971 return -EINVAL; in coda_firmware_request()
2973 fw = dev->devtype->firmware[dev->firmware]; in coda_firmware_request()
2975 dev_dbg(dev->dev, "requesting firmware '%s' for %s\n", fw, in coda_firmware_request()
2976 coda_product_name(dev->devtype->product)); in coda_firmware_request()
2978 return request_firmware_nowait(THIS_MODULE, true, fw, dev->dev, in coda_firmware_request()
2988 dev->firmware++; in coda_fw_callback()
2991 v4l2_err(&dev->v4l2_dev, "firmware request failed\n"); in coda_fw_callback()
2996 if (dev->firmware > 0) { in coda_fw_callback()
3002 dev_info(dev->dev, "Using fallback firmware %s\n", in coda_fw_callback()
3003 dev->devtype->firmware[dev->firmware]); in coda_fw_callback()
3006 /* allocate auxiliary per-device code buffer for the BIT processor */ in coda_fw_callback()
3007 ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf", in coda_fw_callback()
3008 dev->debugfs_root); in coda_fw_callback()
3012 coda_copy_firmware(dev, fw->data, fw->size); in coda_fw_callback()
3017 v4l2_err(&dev->v4l2_dev, "HW initialization failed\n"); in coda_fw_callback()
3025 dev->m2m_dev = v4l2_m2m_init(&coda_m2m_ops); in coda_fw_callback()
3026 if (IS_ERR(dev->m2m_dev)) { in coda_fw_callback()
3027 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); in coda_fw_callback()
3031 for (i = 0; i < dev->devtype->num_vdevs; i++) { in coda_fw_callback()
3034 v4l2_err(&dev->v4l2_dev, in coda_fw_callback()
3036 dev->devtype->vdevs[i]->name, ret); in coda_fw_callback()
3041 pm_runtime_put_sync(dev->dev); in coda_fw_callback()
3045 while (--i >= 0) in coda_fw_callback()
3046 video_unregister_device(&dev->vfd[i]); in coda_fw_callback()
3047 v4l2_m2m_release(dev->m2m_dev); in coda_fw_callback()
3049 pm_runtime_put_sync(dev->dev); in coda_fw_callback()
3064 "vpu/vpu_fw_imx27_TO2.bin",
3065 "v4l-codadx6-imx27.bin"
3078 "vpu/vpu_fw_imx51.bin",
3079 "v4l-codahx4-imx51.bin"
3093 "vpu/vpu_fw_imx53.bin",
3094 "v4l-coda7541-imx53.bin"
3108 "vpu/vpu_fw_imx6q.bin",
3109 "v4l-coda960-imx6q.bin"
3123 "vpu/vpu_fw_imx6d.bin",
3124 "v4l-coda960-imx6dl.bin"
3138 { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
3139 { .compatible = "fsl,imx51-vpu", .data = &coda_devdata[CODA_IMX51] },
3140 { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
3141 { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] },
3142 { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] },
3149 struct device_node *np = pdev->dev.of_node; in coda_probe()
3154 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in coda_probe()
3156 return -ENOMEM; in coda_probe()
3158 dev->devtype = of_device_get_match_data(&pdev->dev); in coda_probe()
3160 dev->dev = &pdev->dev; in coda_probe()
3161 dev->clk_per = devm_clk_get(&pdev->dev, "per"); in coda_probe()
3162 if (IS_ERR(dev->clk_per)) { in coda_probe()
3163 dev_err(&pdev->dev, "Could not get per clock\n"); in coda_probe()
3164 return PTR_ERR(dev->clk_per); in coda_probe()
3167 dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in coda_probe()
3168 if (IS_ERR(dev->clk_ahb)) { in coda_probe()
3169 dev_err(&pdev->dev, "Could not get ahb clock\n"); in coda_probe()
3170 return PTR_ERR(dev->clk_ahb); in coda_probe()
3174 dev->regs_base = devm_platform_ioremap_resource(pdev, 0); in coda_probe()
3175 if (IS_ERR(dev->regs_base)) in coda_probe()
3176 return PTR_ERR(dev->regs_base); in coda_probe()
3185 ret = devm_request_irq(&pdev->dev, irq, coda_irq_handler, 0, in coda_probe()
3186 CODA_NAME "-video", dev); in coda_probe()
3188 dev_err(&pdev->dev, "failed to request irq: %d\n", ret); in coda_probe()
3193 if (dev->devtype->product == CODA_960) { in coda_probe()
3198 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, in coda_probe()
3200 IRQF_ONESHOT, CODA_NAME "-jpeg", in coda_probe()
3203 dev_err(&pdev->dev, "failed to request jpeg irq\n"); in coda_probe()
3208 dev->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, in coda_probe()
3210 if (IS_ERR(dev->rstc)) { in coda_probe()
3211 ret = PTR_ERR(dev->rstc); in coda_probe()
3212 dev_err(&pdev->dev, "failed get reset control: %d\n", ret); in coda_probe()
3219 dev_err(&pdev->dev, "iram pool not available\n"); in coda_probe()
3220 return -ENOMEM; in coda_probe()
3222 dev->iram_pool = pool; in coda_probe()
3225 dev->vdoa = coda_get_vdoa_data(); in coda_probe()
3226 if (PTR_ERR(dev->vdoa) == -EPROBE_DEFER) in coda_probe()
3227 return -EPROBE_DEFER; in coda_probe()
3229 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); in coda_probe()
3233 ratelimit_default_init(&dev->mb_err_rs); in coda_probe()
3234 mutex_init(&dev->dev_mutex); in coda_probe()
3235 mutex_init(&dev->coda_mutex); in coda_probe()
3236 ida_init(&dev->ida); in coda_probe()
3238 dev->debugfs_root = debugfs_create_dir("coda", NULL); in coda_probe()
3240 /* allocate auxiliary per-device buffers for the BIT processor */ in coda_probe()
3241 if (dev->devtype->product == CODA_DX6) { in coda_probe()
3242 ret = coda_alloc_aux_buf(dev, &dev->workbuf, in coda_probe()
3243 dev->devtype->workbuf_size, "workbuf", in coda_probe()
3244 dev->debugfs_root); in coda_probe()
3249 if (dev->devtype->tempbuf_size) { in coda_probe()
3250 ret = coda_alloc_aux_buf(dev, &dev->tempbuf, in coda_probe()
3251 dev->devtype->tempbuf_size, "tempbuf", in coda_probe()
3252 dev->debugfs_root); in coda_probe()
3257 dev->iram.size = dev->devtype->iram_size; in coda_probe()
3258 dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size, in coda_probe()
3259 &dev->iram.paddr); in coda_probe()
3260 if (!dev->iram.vaddr) { in coda_probe()
3261 dev_warn(&pdev->dev, "unable to alloc iram\n"); in coda_probe()
3263 memset(dev->iram.vaddr, 0, dev->iram.size); in coda_probe()
3264 dev->iram.blob.data = dev->iram.vaddr; in coda_probe()
3265 dev->iram.blob.size = dev->iram.size; in coda_probe()
3266 dev->iram.dentry = debugfs_create_blob("iram", 0444, in coda_probe()
3267 dev->debugfs_root, in coda_probe()
3268 &dev->iram.blob); in coda_probe()
3271 dev->workqueue = alloc_ordered_workqueue("coda", WQ_MEM_RECLAIM); in coda_probe()
3272 if (!dev->workqueue) { in coda_probe()
3273 dev_err(&pdev->dev, "unable to alloc workqueue\n"); in coda_probe()
3274 ret = -ENOMEM; in coda_probe()
3285 pm_runtime_get_noresume(&pdev->dev); in coda_probe()
3286 pm_runtime_set_active(&pdev->dev); in coda_probe()
3287 pm_runtime_enable(&pdev->dev); in coda_probe()
3295 pm_runtime_disable(&pdev->dev); in coda_probe()
3296 pm_runtime_put_noidle(&pdev->dev); in coda_probe()
3297 destroy_workqueue(dev->workqueue); in coda_probe()
3299 v4l2_device_unregister(&dev->v4l2_dev); in coda_probe()
3308 for (i = 0; i < ARRAY_SIZE(dev->vfd); i++) { in coda_remove()
3309 if (video_get_drvdata(&dev->vfd[i])) in coda_remove()
3310 video_unregister_device(&dev->vfd[i]); in coda_remove()
3312 if (dev->m2m_dev) in coda_remove()
3313 v4l2_m2m_release(dev->m2m_dev); in coda_remove()
3314 pm_runtime_disable(&pdev->dev); in coda_remove()
3315 v4l2_device_unregister(&dev->v4l2_dev); in coda_remove()
3316 destroy_workqueue(dev->workqueue); in coda_remove()
3317 if (dev->iram.vaddr) in coda_remove()
3318 gen_pool_free(dev->iram_pool, (unsigned long)dev->iram.vaddr, in coda_remove()
3319 dev->iram.size); in coda_remove()
3320 coda_free_aux_buf(dev, &dev->codebuf); in coda_remove()
3321 coda_free_aux_buf(dev, &dev->tempbuf); in coda_remove()
3322 coda_free_aux_buf(dev, &dev->workbuf); in coda_remove()
3323 debugfs_remove_recursive(dev->debugfs_root); in coda_remove()
3324 ida_destroy(&dev->ida); in coda_remove()
3333 if (dev->pm_domain && cdev->codebuf.vaddr) { in coda_runtime_resume()
3336 v4l2_err(&cdev->v4l2_dev, "HW initialization failed\n"); in coda_runtime_resume()
3360 MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
3361 MODULE_DESCRIPTION("Coda multi-standard codec V4L2 driver");