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",
257 .name = "coda-jpeg-decoder",
316 const struct coda_codec *codecs = dev->devtype->codecs; in coda_find_codec()
317 int num_codecs = dev->devtype->num_codecs; in coda_find_codec()
341 const struct coda_codec *codecs = dev->devtype->codecs; in coda_get_max_dimensions()
342 int num_codecs = dev->devtype->num_codecs; in coda_get_max_dimensions()
347 w = codec->max_w; in coda_get_max_dimensions()
348 h = codec->max_h; in coda_get_max_dimensions()
366 unsigned int i = vdev - dev->vfd; in to_coda_video_device()
368 if (i >= dev->devtype->num_vdevs) in to_coda_video_device()
371 return dev->devtype->vdevs[i]; in to_coda_video_device()
399 vdoa_node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-vdoa"); in coda_get_vdoa_data()
409 vdoa_data = ERR_PTR(-EPROBE_DEFER); in coda_get_vdoa_data()
425 strscpy(cap->driver, CODA_NAME, sizeof(cap->driver)); in coda_querycap()
426 strscpy(cap->card, coda_product_name(ctx->dev->devtype->product), in coda_querycap()
427 sizeof(cap->card)); in coda_querycap()
428 strscpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); in coda_querycap()
446 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_enum_fmt()
447 formats = cvd->src_formats; in coda_enum_fmt()
448 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { in coda_enum_fmt()
452 formats = cvd->dst_formats; in coda_enum_fmt()
459 src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in coda_enum_fmt()
461 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && in coda_enum_fmt()
463 if (ctx->params.jpeg_chroma_subsampling == in coda_enum_fmt()
466 } else if (ctx->params.jpeg_chroma_subsampling == in coda_enum_fmt()
468 f->pixelformat = V4L2_PIX_FMT_YUV422P; in coda_enum_fmt()
469 return f->index ? -EINVAL : 0; in coda_enum_fmt()
473 return -EINVAL; in coda_enum_fmt()
476 if (f->index >= CODA_MAX_FORMATS || formats[f->index] == 0) in coda_enum_fmt()
477 return -EINVAL; in coda_enum_fmt()
480 if (!ctx->vdoa && f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && in coda_enum_fmt()
481 formats[f->index] == V4L2_PIX_FMT_YUYV) in coda_enum_fmt()
482 return -EINVAL; in coda_enum_fmt()
484 f->pixelformat = formats[f->index]; in coda_enum_fmt()
495 q_data = get_q_data(ctx, f->type); in coda_g_fmt()
497 return -EINVAL; in coda_g_fmt()
499 f->fmt.pix.field = V4L2_FIELD_NONE; in coda_g_fmt()
500 f->fmt.pix.pixelformat = q_data->fourcc; in coda_g_fmt()
501 f->fmt.pix.width = q_data->width; in coda_g_fmt()
502 f->fmt.pix.height = q_data->height; in coda_g_fmt()
503 f->fmt.pix.bytesperline = q_data->bytesperline; in coda_g_fmt()
505 f->fmt.pix.sizeimage = q_data->sizeimage; in coda_g_fmt()
506 f->fmt.pix.colorspace = ctx->colorspace; in coda_g_fmt()
507 f->fmt.pix.xfer_func = ctx->xfer_func; in coda_g_fmt()
508 f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; in coda_g_fmt()
509 f->fmt.pix.quantization = ctx->quantization; in coda_g_fmt()
520 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_try_pixelformat()
521 formats = ctx->cvd->src_formats; in coda_try_pixelformat()
522 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in coda_try_pixelformat()
523 formats = ctx->cvd->dst_formats; in coda_try_pixelformat()
525 return -EINVAL; in coda_try_pixelformat()
529 if (!ctx->vdoa && f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && in coda_try_pixelformat()
533 if (formats[i] == f->fmt.pix.pixelformat) { in coda_try_pixelformat()
534 f->fmt.pix.pixelformat = formats[i]; in coda_try_pixelformat()
540 q_data = get_q_data(ctx, f->type); in coda_try_pixelformat()
541 f->fmt.pix.pixelformat = q_data->fourcc; in coda_try_pixelformat()
551 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in coda_try_fmt_vdoa()
552 return -EINVAL; in coda_try_fmt_vdoa()
555 return -EINVAL; in coda_try_fmt_vdoa()
557 if (!ctx->vdoa) { in coda_try_fmt_vdoa()
562 err = vdoa_context_configure(NULL, round_up(f->fmt.pix.width, 16), in coda_try_fmt_vdoa()
563 f->fmt.pix.height, f->fmt.pix.pixelformat); in coda_try_fmt_vdoa()
588 struct coda_dev *dev = ctx->dev; in coda_try_fmt()
592 field = f->fmt.pix.field; in coda_try_fmt()
596 return -EINVAL; in coda_try_fmt()
600 f->fmt.pix.field = field; in coda_try_fmt()
603 v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN, in coda_try_fmt()
604 &f->fmt.pix.height, MIN_H, max_h, H_ALIGN, in coda_try_fmt()
607 switch (f->fmt.pix.pixelformat) { in coda_try_fmt()
615 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); in coda_try_fmt()
616 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt()
617 f->fmt.pix.height * 3 / 2; in coda_try_fmt()
620 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16) * 2; in coda_try_fmt()
621 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt()
622 f->fmt.pix.height; in coda_try_fmt()
625 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); in coda_try_fmt()
626 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt()
627 f->fmt.pix.height * 2; in coda_try_fmt()
633 f->fmt.pix.bytesperline = 0; in coda_try_fmt()
634 f->fmt.pix.sizeimage = coda_estimate_sizeimage(ctx, in coda_try_fmt()
635 f->fmt.pix.sizeimage, in coda_try_fmt()
636 f->fmt.pix.width, in coda_try_fmt()
637 f->fmt.pix.height); in coda_try_fmt()
667 src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); in coda_try_fmt_vid_cap()
669 f->fmt.pix.width = q_data_src->width; in coda_try_fmt_vid_cap()
670 f->fmt.pix.height = q_data_src->height; in coda_try_fmt_vid_cap()
672 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG) { in coda_try_fmt_vid_cap()
673 if (ctx->params.jpeg_chroma_subsampling == in coda_try_fmt_vid_cap()
675 f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) in coda_try_fmt_vid_cap()
676 f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; in coda_try_fmt_vid_cap()
677 else if (ctx->params.jpeg_chroma_subsampling == in coda_try_fmt_vid_cap()
679 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; in coda_try_fmt_vid_cap()
683 f->fmt.pix.colorspace = ctx->colorspace; in coda_try_fmt_vid_cap()
684 f->fmt.pix.xfer_func = ctx->xfer_func; in coda_try_fmt_vid_cap()
685 f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; in coda_try_fmt_vid_cap()
686 f->fmt.pix.quantization = ctx->quantization; in coda_try_fmt_vid_cap()
689 codec = coda_find_codec(ctx->dev, q_data_src->fourcc, in coda_try_fmt_vid_cap()
690 f->fmt.pix.pixelformat); in coda_try_fmt_vid_cap()
692 return -EINVAL; in coda_try_fmt_vid_cap()
699 if (ctx->inst_type == CODA_INST_DECODER) { in coda_try_fmt_vid_cap()
700 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); in coda_try_fmt_vid_cap()
701 f->fmt.pix.height = round_up(f->fmt.pix.height, 16); in coda_try_fmt_vid_cap()
702 if (codec->src_fourcc == V4L2_PIX_FMT_JPEG && in coda_try_fmt_vid_cap()
703 f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) { in coda_try_fmt_vid_cap()
704 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt_vid_cap()
705 f->fmt.pix.height * 2; in coda_try_fmt_vid_cap()
707 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt_vid_cap()
708 f->fmt.pix.height * 3 / 2; in coda_try_fmt_vid_cap()
715 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { in coda_try_fmt_vid_cap()
717 return -EINVAL; in coda_try_fmt_vid_cap()
719 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16) * 2; in coda_try_fmt_vid_cap()
720 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * in coda_try_fmt_vid_cap()
721 f->fmt.pix.height; in coda_try_fmt_vid_cap()
732 if (fmt->pixelformat == V4L2_PIX_FMT_JPEG) in coda_set_default_colorspace()
734 else if (fmt->width <= 720 && fmt->height <= 576) in coda_set_default_colorspace()
739 fmt->colorspace = colorspace; in coda_set_default_colorspace()
740 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in coda_set_default_colorspace()
741 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in coda_set_default_colorspace()
742 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in coda_set_default_colorspace()
749 struct coda_dev *dev = ctx->dev; in coda_try_fmt_vid_out()
758 if (f->fmt.pix.colorspace == V4L2_COLORSPACE_DEFAULT) in coda_try_fmt_vid_out()
759 coda_set_default_colorspace(&f->fmt.pix); in coda_try_fmt_vid_out()
762 codec = coda_find_codec(dev, f->fmt.pix.pixelformat, q_data_dst->fourcc); in coda_try_fmt_vid_out()
773 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in coda_s_fmt()
775 return -EINVAL; in coda_s_fmt()
777 q_data = get_q_data(ctx, f->type); in coda_s_fmt()
779 return -EINVAL; in coda_s_fmt()
782 v4l2_err(&ctx->dev->v4l2_dev, "%s: %s queue busy: %d\n", in coda_s_fmt()
783 __func__, v4l2_type_names[f->type], vq->num_buffers); in coda_s_fmt()
784 return -EBUSY; in coda_s_fmt()
787 q_data->fourcc = f->fmt.pix.pixelformat; in coda_s_fmt()
788 q_data->width = f->fmt.pix.width; in coda_s_fmt()
789 q_data->height = f->fmt.pix.height; in coda_s_fmt()
790 q_data->bytesperline = f->fmt.pix.bytesperline; in coda_s_fmt()
791 q_data->sizeimage = f->fmt.pix.sizeimage; in coda_s_fmt()
793 q_data->rect = *r; in coda_s_fmt()
795 q_data->rect.left = 0; in coda_s_fmt()
796 q_data->rect.top = 0; in coda_s_fmt()
797 q_data->rect.width = f->fmt.pix.width; in coda_s_fmt()
798 q_data->rect.height = f->fmt.pix.height; in coda_s_fmt()
801 switch (f->fmt.pix.pixelformat) { in coda_s_fmt()
803 ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP; in coda_s_fmt()
806 if (!disable_tiling && ctx->use_bit && in coda_s_fmt()
807 ctx->dev->devtype->product == CODA_960) { in coda_s_fmt()
808 ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP; in coda_s_fmt()
815 ctx->tiled_map_type = GDI_LINEAR_FRAME_MAP; in coda_s_fmt()
821 if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP && in coda_s_fmt()
822 !coda_try_fmt_vdoa(ctx, f, &ctx->use_vdoa) && in coda_s_fmt()
823 ctx->use_vdoa) in coda_s_fmt()
824 vdoa_context_configure(ctx->vdoa, in coda_s_fmt()
825 round_up(f->fmt.pix.width, 16), in coda_s_fmt()
826 f->fmt.pix.height, in coda_s_fmt()
827 f->fmt.pix.pixelformat); in coda_s_fmt()
829 ctx->use_vdoa = false; in coda_s_fmt()
832 v4l2_type_names[f->type], q_data->width, q_data->height, in coda_s_fmt()
833 (char *)&q_data->fourcc, in coda_s_fmt()
834 (ctx->tiled_map_type == GDI_LINEAR_FRAME_MAP) ? 'L' : 'T'); in coda_s_fmt()
855 r.width = q_data_src->width; in coda_s_fmt_vid_cap()
856 r.height = q_data_src->height; in coda_s_fmt_vid_cap()
862 if (ctx->inst_type != CODA_INST_ENCODER) in coda_s_fmt_vid_cap()
866 codec = coda_find_codec(ctx->dev, q_data_src->fourcc, in coda_s_fmt_vid_cap()
867 f->fmt.pix.pixelformat); in coda_s_fmt_vid_cap()
869 v4l2_err(&ctx->dev->v4l2_dev, "failed to determine codec\n"); in coda_s_fmt_vid_cap()
870 return -EINVAL; in coda_s_fmt_vid_cap()
872 ctx->codec = codec; in coda_s_fmt_vid_cap()
874 ctx->colorspace = f->fmt.pix.colorspace; in coda_s_fmt_vid_cap()
875 ctx->xfer_func = f->fmt.pix.xfer_func; in coda_s_fmt_vid_cap()
876 ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; in coda_s_fmt_vid_cap()
877 ctx->quantization = f->fmt.pix.quantization; in coda_s_fmt_vid_cap()
899 ctx->colorspace = f->fmt.pix.colorspace; in coda_s_fmt_vid_out()
900 ctx->xfer_func = f->fmt.pix.xfer_func; in coda_s_fmt_vid_out()
901 ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; in coda_s_fmt_vid_out()
902 ctx->quantization = f->fmt.pix.quantization; in coda_s_fmt_vid_out()
904 if (ctx->inst_type != CODA_INST_DECODER) in coda_s_fmt_vid_out()
908 codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat, in coda_s_fmt_vid_out()
911 v4l2_err(&ctx->dev->v4l2_dev, "failed to determine codec\n"); in coda_s_fmt_vid_out()
912 return -EINVAL; in coda_s_fmt_vid_out()
914 ctx->codec = codec; in coda_s_fmt_vid_out()
916 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); in coda_s_fmt_vid_out()
918 return -EINVAL; in coda_s_fmt_vid_out()
932 f_cap.fmt.pix.width = f->fmt.pix.width; in coda_s_fmt_vid_out()
933 f_cap.fmt.pix.height = f->fmt.pix.height; in coda_s_fmt_vid_out()
944 ret = v4l2_m2m_reqbufs(file, ctx->fh.m2m_ctx, rb); in coda_reqbufs()
949 * Allow to allocate instance specific per-context buffers, such as in coda_reqbufs()
952 if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && ctx->ops->reqbufs) in coda_reqbufs()
953 return ctx->ops->reqbufs(ctx, rb); in coda_reqbufs()
963 if (ctx->inst_type == CODA_INST_DECODER && in coda_qbuf()
964 buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_qbuf()
965 buf->flags &= ~V4L2_BUF_FLAG_LAST; in coda_qbuf()
967 return v4l2_m2m_qbuf(file, ctx->fh.m2m_ctx, buf); in coda_qbuf()
975 ret = v4l2_m2m_dqbuf(file, ctx->fh.m2m_ctx, buf); in coda_dqbuf()
977 if (ctx->inst_type == CODA_INST_DECODER && in coda_dqbuf()
978 buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_dqbuf()
979 buf->flags &= ~V4L2_BUF_FLAG_LAST; in coda_dqbuf()
991 if (buf->flags & V4L2_BUF_FLAG_LAST) in coda_m2m_buf_done()
992 v4l2_event_queue_fh(&ctx->fh, &eos_event); in coda_m2m_buf_done()
1004 q_data = get_q_data(ctx, s->type); in coda_g_selection()
1006 return -EINVAL; in coda_g_selection()
1010 r.width = q_data->width; in coda_g_selection()
1011 r.height = q_data->height; in coda_g_selection()
1012 rsel = &q_data->rect; in coda_g_selection()
1014 switch (s->target) { in coda_g_selection()
1020 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || in coda_g_selection()
1021 ctx->inst_type == CODA_INST_DECODER) in coda_g_selection()
1022 return -EINVAL; in coda_g_selection()
1030 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || in coda_g_selection()
1031 ctx->inst_type == CODA_INST_ENCODER) in coda_g_selection()
1032 return -EINVAL; in coda_g_selection()
1035 return -EINVAL; in coda_g_selection()
1038 s->r = *rsel; in coda_g_selection()
1049 switch (s->target) { in coda_s_selection()
1051 if (ctx->inst_type == CODA_INST_ENCODER && in coda_s_selection()
1052 s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_s_selection()
1053 q_data = get_q_data(ctx, s->type); in coda_s_selection()
1055 return -EINVAL; in coda_s_selection()
1057 s->r.left = 0; in coda_s_selection()
1058 s->r.top = 0; in coda_s_selection()
1059 s->r.width = clamp(s->r.width, 2U, q_data->width); in coda_s_selection()
1060 s->r.height = clamp(s->r.height, 2U, q_data->height); in coda_s_selection()
1062 if (s->flags & V4L2_SEL_FLAG_LE) { in coda_s_selection()
1063 s->r.width = round_up(s->r.width, 2); in coda_s_selection()
1064 s->r.height = round_up(s->r.height, 2); in coda_s_selection()
1066 s->r.width = round_down(s->r.width, 2); in coda_s_selection()
1067 s->r.height = round_down(s->r.height, 2); in coda_s_selection()
1070 q_data->rect = s->r; in coda_s_selection()
1073 s->r.width, s->r.height); in coda_s_selection()
1082 /* v4l2-compliance expects this to fail for read-only targets */ in coda_s_selection()
1083 return -EINVAL; in coda_s_selection()
1092 if (ctx->inst_type != CODA_INST_ENCODER) in coda_try_encoder_cmd()
1093 return -ENOTTY; in coda_try_encoder_cmd()
1104 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); in coda_wake_up_capture_queue()
1105 dst_vq->last_buffer_dequeued = true; in coda_wake_up_capture_queue()
1106 wake_up(&dst_vq->done_wq); in coda_wake_up_capture_queue()
1120 mutex_lock(&ctx->wakeup_mutex); in coda_encoder_cmd()
1121 buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx); in coda_encoder_cmd()
1128 buf->flags |= V4L2_BUF_FLAG_LAST; in coda_encoder_cmd()
1130 /* Set the stream-end flag on this context */ in coda_encoder_cmd()
1131 ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; in coda_encoder_cmd()
1136 * via the -EPIPE mechanism. in coda_encoder_cmd()
1140 mutex_unlock(&ctx->wakeup_mutex); in coda_encoder_cmd()
1150 if (ctx->inst_type != CODA_INST_DECODER) in coda_try_decoder_cmd()
1151 return -ENOTTY; in coda_try_decoder_cmd()
1162 spin_lock(&ctx->buffer_meta_lock); in coda_mark_last_meta()
1163 if (list_empty(&ctx->buffer_meta_list)) { in coda_mark_last_meta()
1164 spin_unlock(&ctx->buffer_meta_lock); in coda_mark_last_meta()
1168 meta = list_last_entry(&ctx->buffer_meta_list, struct coda_buffer_meta, in coda_mark_last_meta()
1170 meta->last = true; in coda_mark_last_meta()
1172 spin_unlock(&ctx->buffer_meta_lock); in coda_mark_last_meta()
1185 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); in coda_mark_last_dst_buf()
1186 spin_lock_irqsave(&dst_vq->done_lock, flags); in coda_mark_last_dst_buf()
1187 if (list_empty(&dst_vq->done_list)) { in coda_mark_last_dst_buf()
1188 spin_unlock_irqrestore(&dst_vq->done_lock, flags); in coda_mark_last_dst_buf()
1192 dst_vb = list_last_entry(&dst_vq->done_list, struct vb2_buffer, in coda_mark_last_dst_buf()
1195 buf->flags |= V4L2_BUF_FLAG_LAST; in coda_mark_last_dst_buf()
1197 spin_unlock_irqrestore(&dst_vq->done_lock, flags); in coda_mark_last_dst_buf()
1205 struct coda_dev *dev = ctx->dev; in coda_decoder_cmd()
1216 switch (dc->cmd) { in coda_decoder_cmd()
1218 mutex_lock(&dev->coda_mutex); in coda_decoder_cmd()
1219 mutex_lock(&ctx->bitstream_mutex); in coda_decoder_cmd()
1221 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in coda_decoder_cmd()
1224 ctx->bit_stream_param &= ~CODA_BIT_STREAM_END_FLAG; in coda_decoder_cmd()
1226 mutex_unlock(&ctx->bitstream_mutex); in coda_decoder_cmd()
1227 mutex_unlock(&dev->coda_mutex); in coda_decoder_cmd()
1233 mutex_lock(&ctx->wakeup_mutex); in coda_decoder_cmd()
1235 buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx); in coda_decoder_cmd()
1240 buf->flags |= V4L2_BUF_FLAG_LAST; in coda_decoder_cmd()
1242 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) == 0) { in coda_decoder_cmd()
1247 if (ctx->use_bit) in coda_decoder_cmd()
1260 /* Set the stream-end flag on this context */ in coda_decoder_cmd()
1262 ctx->hold = false; in coda_decoder_cmd()
1263 v4l2_m2m_try_schedule(ctx->fh.m2m_ctx); in coda_decoder_cmd()
1271 mutex_unlock(&ctx->wakeup_mutex); in coda_decoder_cmd()
1274 return -EINVAL; in coda_decoder_cmd()
1287 if (ctx->inst_type != CODA_INST_ENCODER) in coda_enum_framesizes()
1288 return -ENOTTY; in coda_enum_framesizes()
1290 if (fsize->index) in coda_enum_framesizes()
1291 return -EINVAL; in coda_enum_framesizes()
1293 if (coda_format_normalize_yuv(fsize->pixel_format) == in coda_enum_framesizes()
1296 codec = coda_find_codec(ctx->dev, fsize->pixel_format, in coda_enum_framesizes()
1297 q_data_dst->fourcc); in coda_enum_framesizes()
1299 codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, in coda_enum_framesizes()
1300 fsize->pixel_format); in coda_enum_framesizes()
1303 return -EINVAL; in coda_enum_framesizes()
1305 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; in coda_enum_framesizes()
1306 fsize->stepwise.min_width = MIN_W; in coda_enum_framesizes()
1307 fsize->stepwise.max_width = codec->max_w; in coda_enum_framesizes()
1308 fsize->stepwise.step_width = 1; in coda_enum_framesizes()
1309 fsize->stepwise.min_height = MIN_H; in coda_enum_framesizes()
1310 fsize->stepwise.max_height = codec->max_h; in coda_enum_framesizes()
1311 fsize->stepwise.step_height = 1; in coda_enum_framesizes()
1322 if (f->index) in coda_enum_frameintervals()
1323 return -EINVAL; in coda_enum_frameintervals()
1326 if (!ctx->vdoa && f->pixel_format == V4L2_PIX_FMT_YUYV) in coda_enum_frameintervals()
1327 return -EINVAL; in coda_enum_frameintervals()
1330 if (f->pixel_format == ctx->cvd->src_formats[i] || in coda_enum_frameintervals()
1331 f->pixel_format == ctx->cvd->dst_formats[i]) in coda_enum_frameintervals()
1335 return -EINVAL; in coda_enum_frameintervals()
1337 f->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; in coda_enum_frameintervals()
1338 f->stepwise.min.numerator = 1; in coda_enum_frameintervals()
1339 f->stepwise.min.denominator = 65535; in coda_enum_frameintervals()
1340 f->stepwise.max.numerator = 65536; in coda_enum_frameintervals()
1341 f->stepwise.max.denominator = 1; in coda_enum_frameintervals()
1342 f->stepwise.step.numerator = 1; in coda_enum_frameintervals()
1343 f->stepwise.step.denominator = 1; in coda_enum_frameintervals()
1353 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_g_parm()
1354 return -EINVAL; in coda_g_parm()
1356 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; in coda_g_parm()
1357 tpf = &a->parm.output.timeperframe; in coda_g_parm()
1358 tpf->denominator = ctx->params.framerate & CODA_FRATE_RES_MASK; in coda_g_parm()
1359 tpf->numerator = 1 + (ctx->params.framerate >> in coda_g_parm()
1367 * into the 16-bit CODA_FRATE_DIV and CODA_FRATE_RES fields.
1379 timeperframe->numerator = 1; in coda_approximate_timeperframe()
1380 timeperframe->denominator = 65535; in coda_approximate_timeperframe()
1386 timeperframe->numerator = 65536; in coda_approximate_timeperframe()
1387 timeperframe->denominator = 1; in coda_approximate_timeperframe()
1427 return ((timeperframe->numerator - 1) << CODA_FRATE_DIV_OFFSET) | in coda_timeperframe_to_frate()
1428 timeperframe->denominator; in coda_timeperframe_to_frate()
1436 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_s_parm()
1437 return -EINVAL; in coda_s_parm()
1439 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; in coda_s_parm()
1440 tpf = &a->parm.output.timeperframe; in coda_s_parm()
1442 ctx->params.framerate = coda_timeperframe_to_frate(tpf); in coda_s_parm()
1443 ctx->params.framerate_changed = true; in coda_s_parm()
1453 switch (sub->type) { in coda_subscribe_event()
1457 if (ctx->inst_type == CODA_INST_DECODER) in coda_subscribe_event()
1460 return -EINVAL; in coda_subscribe_event()
1510 * Mem-to-mem operations.
1516 struct coda_dev *dev = ctx->dev; in coda_device_run()
1518 queue_work(dev->workqueue, &ctx->pic_run_work); in coda_device_run()
1524 struct coda_dev *dev = ctx->dev; in coda_pic_run_work()
1527 mutex_lock(&ctx->buffer_mutex); in coda_pic_run_work()
1528 mutex_lock(&dev->coda_mutex); in coda_pic_run_work()
1530 ret = ctx->ops->prepare_run(ctx); in coda_pic_run_work()
1531 if (ret < 0 && ctx->inst_type == CODA_INST_DECODER) { in coda_pic_run_work()
1532 mutex_unlock(&dev->coda_mutex); in coda_pic_run_work()
1533 mutex_unlock(&ctx->buffer_mutex); in coda_pic_run_work()
1538 if (!wait_for_completion_timeout(&ctx->completion, in coda_pic_run_work()
1540 dev_err(dev->dev, "CODA PIC_RUN timeout\n"); in coda_pic_run_work()
1542 ctx->hold = true; in coda_pic_run_work()
1546 if (ctx->ops->run_timeout) in coda_pic_run_work()
1547 ctx->ops->run_timeout(ctx); in coda_pic_run_work()
1549 ctx->ops->finish_run(ctx); in coda_pic_run_work()
1552 if ((ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out)) && in coda_pic_run_work()
1553 ctx->ops->seq_end_work) in coda_pic_run_work()
1554 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_pic_run_work()
1556 mutex_unlock(&dev->coda_mutex); in coda_pic_run_work()
1557 mutex_unlock(&ctx->buffer_mutex); in coda_pic_run_work()
1559 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); in coda_pic_run_work()
1565 int src_bufs = v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx); in coda_job_ready()
1572 if (!src_bufs && ctx->inst_type != CODA_INST_DECODER) { in coda_job_ready()
1573 coda_dbg(1, ctx, "not ready: not enough vid-out buffers.\n"); in coda_job_ready()
1577 if (!v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) { in coda_job_ready()
1578 coda_dbg(1, ctx, "not ready: not enough vid-cap buffers.\n"); in coda_job_ready()
1582 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) { in coda_job_ready()
1583 bool stream_end = ctx->bit_stream_param & in coda_job_ready()
1585 int num_metas = ctx->num_metas; in coda_job_ready()
1589 count = hweight32(ctx->frm_dis_flg); in coda_job_ready()
1590 if (ctx->use_vdoa && count >= (ctx->num_internal_frames - 1)) { in coda_job_ready()
1593 count, ctx->num_internal_frames, in coda_job_ready()
1594 ctx->frm_dis_flg); in coda_job_ready()
1598 if (ctx->hold && !src_bufs) { in coda_job_ready()
1611 meta = list_first_entry(&ctx->buffer_meta_list, in coda_job_ready()
1613 if (!coda_bitstream_can_fetch_past(ctx, meta->end) && in coda_job_ready()
1617 meta->end, ctx->bitstream_fifo.kfifo.in); in coda_job_ready()
1622 if (ctx->aborting) { in coda_job_ready()
1636 ctx->aborting = 1; in coda_job_abort()
1651 ctx->codec = coda_find_codec(ctx->dev, ctx->cvd->src_formats[0], in set_default_params()
1652 ctx->cvd->dst_formats[0]); in set_default_params()
1653 max_w = min(ctx->codec->max_w, 1920U); in set_default_params()
1654 max_h = min(ctx->codec->max_h, 1088U); in set_default_params()
1658 ctx->params.codec_mode = ctx->codec->mode; in set_default_params()
1659 if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_JPEG) in set_default_params()
1660 ctx->colorspace = V4L2_COLORSPACE_JPEG; in set_default_params()
1662 ctx->colorspace = V4L2_COLORSPACE_REC709; in set_default_params()
1663 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; in set_default_params()
1664 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in set_default_params()
1665 ctx->quantization = V4L2_QUANTIZATION_DEFAULT; in set_default_params()
1666 ctx->params.framerate = 30; in set_default_params()
1669 ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->cvd->src_formats[0]; in set_default_params()
1670 ctx->q_data[V4L2_M2M_DST].fourcc = ctx->cvd->dst_formats[0]; in set_default_params()
1671 ctx->q_data[V4L2_M2M_SRC].width = max_w; in set_default_params()
1672 ctx->q_data[V4L2_M2M_SRC].height = max_h; in set_default_params()
1673 ctx->q_data[V4L2_M2M_DST].width = max_w; in set_default_params()
1674 ctx->q_data[V4L2_M2M_DST].height = max_h; in set_default_params()
1675 if (ctx->codec->src_fourcc == V4L2_PIX_FMT_YUV420) { in set_default_params()
1676 ctx->q_data[V4L2_M2M_SRC].bytesperline = max_w; in set_default_params()
1677 ctx->q_data[V4L2_M2M_SRC].sizeimage = usize; in set_default_params()
1678 ctx->q_data[V4L2_M2M_DST].bytesperline = 0; in set_default_params()
1679 ctx->q_data[V4L2_M2M_DST].sizeimage = csize; in set_default_params()
1681 ctx->q_data[V4L2_M2M_SRC].bytesperline = 0; in set_default_params()
1682 ctx->q_data[V4L2_M2M_SRC].sizeimage = csize; in set_default_params()
1683 ctx->q_data[V4L2_M2M_DST].bytesperline = max_w; in set_default_params()
1684 ctx->q_data[V4L2_M2M_DST].sizeimage = usize; in set_default_params()
1686 ctx->q_data[V4L2_M2M_SRC].rect.width = max_w; in set_default_params()
1687 ctx->q_data[V4L2_M2M_SRC].rect.height = max_h; in set_default_params()
1688 ctx->q_data[V4L2_M2M_DST].rect.width = max_w; in set_default_params()
1689 ctx->q_data[V4L2_M2M_DST].rect.height = max_h; in set_default_params()
1695 ctx->tiled_map_type = GDI_LINEAR_FRAME_MAP; in set_default_params()
1709 q_data = get_q_data(ctx, vq->type); in coda_queue_setup()
1710 size = q_data->sizeimage; in coda_queue_setup()
1713 return sizes[0] < size ? -EINVAL : 0; in coda_queue_setup()
1727 struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in coda_buf_prepare()
1730 q_data = get_q_data(ctx, vb->vb2_queue->type); in coda_buf_prepare()
1731 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { in coda_buf_prepare()
1732 if (vbuf->field == V4L2_FIELD_ANY) in coda_buf_prepare()
1733 vbuf->field = V4L2_FIELD_NONE; in coda_buf_prepare()
1734 if (vbuf->field != V4L2_FIELD_NONE) { in coda_buf_prepare()
1735 v4l2_warn(&ctx->dev->v4l2_dev, in coda_buf_prepare()
1737 return -EINVAL; in coda_buf_prepare()
1741 if (vb2_plane_size(vb, 0) < q_data->sizeimage) { in coda_buf_prepare()
1742 v4l2_warn(&ctx->dev->v4l2_dev, in coda_buf_prepare()
1745 (long)q_data->sizeimage); in coda_buf_prepare()
1746 return -EINVAL; in coda_buf_prepare()
1763 if (value > ctrl->maximum) { in coda_update_menu_ctrl()
1764 __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, value, in coda_update_menu_ctrl()
1765 ctrl->menu_skip_mask & ~(1 << value), in coda_update_menu_ctrl()
1766 ctrl->default_value); in coda_update_menu_ctrl()
1767 } else if (value < ctrl->minimum) { in coda_update_menu_ctrl()
1768 __v4l2_ctrl_modify_range(ctrl, value, ctrl->maximum, in coda_update_menu_ctrl()
1769 ctrl->menu_skip_mask & ~(1 << value), in coda_update_menu_ctrl()
1770 ctrl->default_value); in coda_update_menu_ctrl()
1791 switch (ctx->codec->src_fourcc) { in coda_update_profile_level_ctrls()
1796 profile_ctrl = ctx->h264_profile_ctrl; in coda_update_profile_level_ctrls()
1797 level_ctrl = ctx->h264_level_ctrl; in coda_update_profile_level_ctrls()
1802 codec_name = "MPEG-2"; in coda_update_profile_level_ctrls()
1805 profile_ctrl = ctx->mpeg2_profile_ctrl; in coda_update_profile_level_ctrls()
1806 level_ctrl = ctx->mpeg2_level_ctrl; in coda_update_profile_level_ctrls()
1811 codec_name = "MPEG-4"; in coda_update_profile_level_ctrls()
1814 profile_ctrl = ctx->mpeg4_profile_ctrl; in coda_update_profile_level_ctrls()
1815 level_ctrl = ctx->mpeg4_level_ctrl; in coda_update_profile_level_ctrls()
1827 v4l2_warn(&ctx->dev->v4l2_dev, "Invalid %s profile: %u\n", in coda_update_profile_level_ctrls()
1836 v4l2_warn(&ctx->dev->v4l2_dev, "Invalid %s level: %u\n", in coda_update_profile_level_ctrls()
1852 v4l2_event_queue_fh(&ctx->fh, &source_change_event); in coda_queue_source_change_event()
1858 struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in coda_buf_queue()
1859 struct vb2_queue *vq = vb->vb2_queue; in coda_buf_queue()
1862 q_data = get_q_data(ctx, vb->vb2_queue->type); in coda_buf_queue()
1868 if (ctx->bitstream.size && vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_buf_queue()
1876 if (q_data->fourcc == V4L2_PIX_FMT_H264) { in coda_buf_queue()
1883 if (!ctx->params.h264_profile_idc) { in coda_buf_queue()
1886 ctx->params.h264_profile_idc, in coda_buf_queue()
1887 ctx->params.h264_level_idc); in coda_buf_queue()
1891 mutex_lock(&ctx->bitstream_mutex); in coda_buf_queue()
1892 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in coda_buf_queue()
1893 if (vb2_is_streaming(vb->vb2_queue)) in coda_buf_queue()
1894 /* This set buf->sequence = ctx->qsequence++ */ in coda_buf_queue()
1896 mutex_unlock(&ctx->bitstream_mutex); in coda_buf_queue()
1898 if (!ctx->initialized) { in coda_buf_queue()
1903 if (vb2_is_streaming(vb->vb2_queue) && in coda_buf_queue()
1904 ctx->ops->seq_init_work) { in coda_buf_queue()
1905 queue_work(ctx->dev->workqueue, in coda_buf_queue()
1906 &ctx->seq_init_work); in coda_buf_queue()
1907 flush_work(&ctx->seq_init_work); in coda_buf_queue()
1910 if (ctx->initialized) in coda_buf_queue()
1914 if ((ctx->inst_type == CODA_INST_ENCODER || !ctx->use_bit) && in coda_buf_queue()
1915 vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in coda_buf_queue()
1916 vbuf->sequence = ctx->qsequence++; in coda_buf_queue()
1917 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in coda_buf_queue()
1924 buf->vaddr = dma_alloc_coherent(dev->dev, size, &buf->paddr, in coda_alloc_aux_buf()
1926 if (!buf->vaddr) { in coda_alloc_aux_buf()
1927 v4l2_err(&dev->v4l2_dev, in coda_alloc_aux_buf()
1930 return -ENOMEM; in coda_alloc_aux_buf()
1933 buf->size = size; in coda_alloc_aux_buf()
1936 buf->blob.data = buf->vaddr; in coda_alloc_aux_buf()
1937 buf->blob.size = size; in coda_alloc_aux_buf()
1938 buf->dentry = debugfs_create_blob(name, 0444, parent, in coda_alloc_aux_buf()
1939 &buf->blob); in coda_alloc_aux_buf()
1948 if (buf->vaddr) { in coda_free_aux_buf()
1949 dma_free_coherent(dev->dev, buf->size, buf->vaddr, buf->paddr); in coda_free_aux_buf()
1950 buf->vaddr = NULL; in coda_free_aux_buf()
1951 buf->size = 0; in coda_free_aux_buf()
1952 debugfs_remove(buf->dentry); in coda_free_aux_buf()
1953 buf->dentry = NULL; in coda_free_aux_buf()
1960 struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev; in coda_start_streaming()
1968 return -EINVAL; in coda_start_streaming()
1970 coda_dbg(1, ctx, "start streaming %s\n", v4l2_type_names[q->type]); in coda_start_streaming()
1975 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
1976 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) { in coda_start_streaming()
1978 mutex_lock(&ctx->bitstream_mutex); in coda_start_streaming()
1980 mutex_unlock(&ctx->bitstream_mutex); in coda_start_streaming()
1982 if (ctx->dev->devtype->product != CODA_960 && in coda_start_streaming()
1985 ret = -EINVAL; in coda_start_streaming()
1989 if (!ctx->initialized) { in coda_start_streaming()
1991 if (ctx->ops->seq_init_work) { in coda_start_streaming()
1992 queue_work(ctx->dev->workqueue, in coda_start_streaming()
1993 &ctx->seq_init_work); in coda_start_streaming()
1994 flush_work(&ctx->seq_init_work); in coda_start_streaming()
2003 if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG) { in coda_start_streaming()
2004 buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in coda_start_streaming()
2005 ret = coda_jpeg_decode_header(ctx, &buf->vb2_buf); in coda_start_streaming()
2014 q_data_dst->width = round_up(q_data_src->width, 16); in coda_start_streaming()
2015 q_data_dst->height = round_up(q_data_src->height, 16); in coda_start_streaming()
2016 q_data_dst->bytesperline = q_data_dst->width; in coda_start_streaming()
2017 if (ctx->params.jpeg_chroma_subsampling == in coda_start_streaming()
2019 q_data_dst->sizeimage = in coda_start_streaming()
2020 q_data_dst->bytesperline * in coda_start_streaming()
2021 q_data_dst->height * 3 / 2; in coda_start_streaming()
2022 if (q_data_dst->fourcc != V4L2_PIX_FMT_YUV420) in coda_start_streaming()
2023 q_data_dst->fourcc = V4L2_PIX_FMT_NV12; in coda_start_streaming()
2025 q_data_dst->sizeimage = in coda_start_streaming()
2026 q_data_dst->bytesperline * in coda_start_streaming()
2027 q_data_dst->height * 2; in coda_start_streaming()
2028 q_data_dst->fourcc = V4L2_PIX_FMT_YUV422P; in coda_start_streaming()
2030 q_data_dst->rect.left = 0; in coda_start_streaming()
2031 q_data_dst->rect.top = 0; in coda_start_streaming()
2032 q_data_dst->rect.width = q_data_src->width; in coda_start_streaming()
2033 q_data_dst->rect.height = q_data_src->height; in coda_start_streaming()
2035 ctx->streamon_out = 1; in coda_start_streaming()
2037 ctx->streamon_cap = 1; in coda_start_streaming()
2041 if (!(ctx->streamon_out && ctx->streamon_cap)) in coda_start_streaming()
2045 if ((q_data_src->rect.width != q_data_dst->width && in coda_start_streaming()
2046 round_up(q_data_src->rect.width, 16) != q_data_dst->width) || in coda_start_streaming()
2047 (q_data_src->rect.height != q_data_dst->height && in coda_start_streaming()
2048 round_up(q_data_src->rect.height, 16) != q_data_dst->height)) { in coda_start_streaming()
2050 q_data_src->rect.width, q_data_src->rect.height, in coda_start_streaming()
2051 q_data_dst->width, q_data_dst->height); in coda_start_streaming()
2052 ret = -EINVAL; in coda_start_streaming()
2057 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) in coda_start_streaming()
2058 v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); in coda_start_streaming()
2060 ctx->gopcounter = ctx->params.gop_size - 1; in coda_start_streaming()
2062 if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG) in coda_start_streaming()
2063 ctx->params.gop_size = 1; in coda_start_streaming()
2064 ctx->gopcounter = ctx->params.gop_size - 1; in coda_start_streaming()
2066 if (ctx->mb_err_cnt_ctrl) in coda_start_streaming()
2067 v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, 0); in coda_start_streaming()
2069 ret = ctx->ops->start_streaming(ctx); in coda_start_streaming()
2070 if (ctx->inst_type == CODA_INST_DECODER) { in coda_start_streaming()
2071 if (ret == -EAGAIN) in coda_start_streaming()
2078 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
2080 list_del(&m2m_buf->list); in coda_start_streaming()
2081 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_DONE); in coda_start_streaming()
2087 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
2089 list_del(&m2m_buf->list); in coda_start_streaming()
2090 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_QUEUED); in coda_start_streaming()
2092 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) in coda_start_streaming()
2095 while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) in coda_start_streaming()
2104 struct coda_dev *dev = ctx->dev; in coda_stop_streaming()
2108 stop = ctx->streamon_out && ctx->streamon_cap; in coda_stop_streaming()
2110 coda_dbg(1, ctx, "stop streaming %s\n", v4l2_type_names[q->type]); in coda_stop_streaming()
2112 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_stop_streaming()
2113 ctx->streamon_out = 0; in coda_stop_streaming()
2117 ctx->qsequence = 0; in coda_stop_streaming()
2119 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) in coda_stop_streaming()
2122 ctx->streamon_cap = 0; in coda_stop_streaming()
2124 ctx->osequence = 0; in coda_stop_streaming()
2125 ctx->sequence_offset = 0; in coda_stop_streaming()
2127 while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) in coda_stop_streaming()
2134 if (ctx->ops->seq_end_work) { in coda_stop_streaming()
2135 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_stop_streaming()
2136 flush_work(&ctx->seq_end_work); in coda_stop_streaming()
2138 spin_lock(&ctx->buffer_meta_lock); in coda_stop_streaming()
2139 while (!list_empty(&ctx->buffer_meta_list)) { in coda_stop_streaming()
2140 meta = list_first_entry(&ctx->buffer_meta_list, in coda_stop_streaming()
2142 list_del(&meta->list); in coda_stop_streaming()
2145 ctx->num_metas = 0; in coda_stop_streaming()
2146 spin_unlock(&ctx->buffer_meta_lock); in coda_stop_streaming()
2147 kfifo_init(&ctx->bitstream_fifo, in coda_stop_streaming()
2148 ctx->bitstream.vaddr, ctx->bitstream.size); in coda_stop_streaming()
2149 ctx->runcounter = 0; in coda_stop_streaming()
2150 ctx->aborting = 0; in coda_stop_streaming()
2151 ctx->hold = false; in coda_stop_streaming()
2154 if (!ctx->streamon_out && !ctx->streamon_cap) in coda_stop_streaming()
2155 ctx->bit_stream_param &= ~CODA_BIT_STREAM_END_FLAG; in coda_stop_streaming()
2170 const char * const *val_names = v4l2_ctrl_get_menu(ctrl->id); in coda_s_ctrl()
2172 container_of(ctrl->handler, struct coda_ctx, ctrls); in coda_s_ctrl()
2176 ctrl->id, ctrl->name, ctrl->val, val_names[ctrl->val]); in coda_s_ctrl()
2179 ctrl->id, ctrl->name, ctrl->val); in coda_s_ctrl()
2181 switch (ctrl->id) { in coda_s_ctrl()
2183 if (ctrl->val) in coda_s_ctrl()
2184 ctx->params.rot_mode |= CODA_MIR_HOR; in coda_s_ctrl()
2186 ctx->params.rot_mode &= ~CODA_MIR_HOR; in coda_s_ctrl()
2189 if (ctrl->val) in coda_s_ctrl()
2190 ctx->params.rot_mode |= CODA_MIR_VER; in coda_s_ctrl()
2192 ctx->params.rot_mode &= ~CODA_MIR_VER; in coda_s_ctrl()
2195 ctx->params.bitrate = ctrl->val / 1000; in coda_s_ctrl()
2196 ctx->params.bitrate_changed = true; in coda_s_ctrl()
2199 ctx->params.gop_size = ctrl->val; in coda_s_ctrl()
2202 ctx->params.h264_intra_qp = ctrl->val; in coda_s_ctrl()
2203 ctx->params.h264_intra_qp_changed = true; in coda_s_ctrl()
2206 ctx->params.h264_inter_qp = ctrl->val; in coda_s_ctrl()
2209 ctx->params.h264_min_qp = ctrl->val; in coda_s_ctrl()
2212 ctx->params.h264_max_qp = ctrl->val; in coda_s_ctrl()
2215 ctx->params.h264_slice_alpha_c0_offset_div2 = ctrl->val; in coda_s_ctrl()
2218 ctx->params.h264_slice_beta_offset_div2 = ctrl->val; in coda_s_ctrl()
2221 ctx->params.h264_disable_deblocking_filter_idc = ctrl->val; in coda_s_ctrl()
2224 ctx->params.h264_constrained_intra_pred_flag = ctrl->val; in coda_s_ctrl()
2227 ctx->params.frame_rc_enable = ctrl->val; in coda_s_ctrl()
2230 ctx->params.mb_rc_enable = ctrl->val; in coda_s_ctrl()
2233 ctx->params.h264_chroma_qp_index_offset = ctrl->val; in coda_s_ctrl()
2237 if (ctx->inst_type == CODA_INST_ENCODER) in coda_s_ctrl()
2238 ctx->params.h264_profile_idc = 66; in coda_s_ctrl()
2244 ctx->params.mpeg4_intra_qp = ctrl->val; in coda_s_ctrl()
2247 ctx->params.mpeg4_inter_qp = ctrl->val; in coda_s_ctrl()
2256 ctx->params.slice_mode = ctrl->val; in coda_s_ctrl()
2257 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2260 ctx->params.slice_max_mb = ctrl->val; in coda_s_ctrl()
2261 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2264 ctx->params.slice_max_bits = ctrl->val * 8; in coda_s_ctrl()
2265 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2270 ctx->params.intra_refresh = ctrl->val; in coda_s_ctrl()
2271 ctx->params.intra_refresh_changed = true; in coda_s_ctrl()
2274 ctx->params.force_ipicture = true; in coda_s_ctrl()
2277 coda_set_jpeg_compression_quality(ctx, ctrl->val); in coda_s_ctrl()
2280 ctx->params.jpeg_restart_interval = ctrl->val; in coda_s_ctrl()
2283 ctx->params.vbv_delay = ctrl->val; in coda_s_ctrl()
2286 ctx->params.vbv_size = min(ctrl->val * 8192, 0x7fffffff); in coda_s_ctrl()
2290 ctrl->id, ctrl->val); in coda_s_ctrl()
2291 return -EINVAL; in coda_s_ctrl()
2303 int max_gop_size = (ctx->dev->devtype->product == CODA_DX6) ? 60 : 99; in coda_encode_ctrls()
2305 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2307 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2309 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2311 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2313 if (ctx->dev->devtype->product != CODA_960) { in coda_encode_ctrls()
2314 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()
2320 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, -6, 6, 1, 0); in coda_encode_ctrls()
2321 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2322 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0); in coda_encode_ctrls()
2323 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2327 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2330 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2332 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2334 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2335 V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, -12, 12, 1, 0); in coda_encode_ctrls()
2336 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2340 if (ctx->dev->devtype->product == CODA_HX4 || in coda_encode_ctrls()
2341 ctx->dev->devtype->product == CODA_7541) { in coda_encode_ctrls()
2342 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2350 if (ctx->dev->devtype->product == CODA_960) { in coda_encode_ctrls()
2351 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2361 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2363 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2365 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2369 if (ctx->dev->devtype->product == CODA_HX4 || in coda_encode_ctrls()
2370 ctx->dev->devtype->product == CODA_7541 || in coda_encode_ctrls()
2371 ctx->dev->devtype->product == CODA_960) { in coda_encode_ctrls()
2372 v4l2_ctrl_new_std_menu(&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 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2384 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2387 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2392 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2395 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2401 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2407 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_jpeg_encode_ctrls()
2409 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_jpeg_encode_ctrls()
2417 ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2424 if (ctx->h264_profile_ctrl) in coda_decode_ctrls()
2425 ctx->h264_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2427 if (ctx->dev->devtype->product == CODA_HX4 || in coda_decode_ctrls()
2428 ctx->dev->devtype->product == CODA_7541) in coda_decode_ctrls()
2430 else if (ctx->dev->devtype->product == CODA_960) in coda_decode_ctrls()
2434 ctx->h264_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2436 if (ctx->h264_level_ctrl) in coda_decode_ctrls()
2437 ctx->h264_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2439 ctx->mpeg2_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2443 if (ctx->mpeg2_profile_ctrl) in coda_decode_ctrls()
2444 ctx->mpeg2_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2446 ctx->mpeg2_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2450 if (ctx->mpeg2_level_ctrl) in coda_decode_ctrls()
2451 ctx->mpeg2_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2453 ctx->mpeg4_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2457 if (ctx->mpeg4_profile_ctrl) in coda_decode_ctrls()
2458 ctx->mpeg4_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2460 ctx->mpeg4_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2464 if (ctx->mpeg4_level_ctrl) in coda_decode_ctrls()
2465 ctx->mpeg4_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2479 v4l2_ctrl_handler_init(&ctx->ctrls, 2); in coda_ctrls_setup()
2481 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2483 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2485 if (ctx->inst_type == CODA_INST_ENCODER) { in coda_ctrls_setup()
2486 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2489 if (ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG) in coda_ctrls_setup()
2494 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2497 if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_H264) in coda_ctrls_setup()
2500 ctx->mb_err_cnt_ctrl = v4l2_ctrl_new_custom(&ctx->ctrls, in coda_ctrls_setup()
2503 if (ctx->mb_err_cnt_ctrl) in coda_ctrls_setup()
2504 ctx->mb_err_cnt_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_ctrls_setup()
2507 if (ctx->ctrls.error) { in coda_ctrls_setup()
2508 v4l2_err(&ctx->dev->v4l2_dev, in coda_ctrls_setup()
2510 ctx->ctrls.error); in coda_ctrls_setup()
2511 return -EINVAL; in coda_ctrls_setup()
2514 return v4l2_ctrl_handler_setup(&ctx->ctrls); in coda_ctrls_setup()
2519 vq->drv_priv = ctx; in coda_queue_init()
2520 vq->ops = &coda_qops; in coda_queue_init()
2521 vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in coda_queue_init()
2522 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in coda_queue_init()
2523 vq->lock = &ctx->dev->dev_mutex; in coda_queue_init()
2524 /* One way to indicate end-of-stream for coda is to set the in coda_queue_init()
2530 vq->allow_zero_bytesused = 1; in coda_queue_init()
2536 vq->min_buffers_needed = 1; in coda_queue_init()
2537 vq->dev = ctx->dev->dev; in coda_queue_init()
2547 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in coda_encoder_queue_init()
2548 src_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_encoder_queue_init()
2549 src_vq->mem_ops = &vb2_dma_contig_memops; in coda_encoder_queue_init()
2555 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in coda_encoder_queue_init()
2556 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_encoder_queue_init()
2557 dst_vq->mem_ops = &vb2_dma_contig_memops; in coda_encoder_queue_init()
2567 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in coda_decoder_queue_init()
2568 src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; in coda_decoder_queue_init()
2569 src_vq->mem_ops = &vb2_vmalloc_memops; in coda_decoder_queue_init()
2575 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in coda_decoder_queue_init()
2576 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_decoder_queue_init()
2577 dst_vq->dma_attrs = DMA_ATTR_NO_KERNEL_MAPPING; in coda_decoder_queue_init()
2578 dst_vq->mem_ops = &vb2_dma_contig_memops; in coda_decoder_queue_init()
2599 return -ENOMEM; in coda_open()
2601 if (dev->devtype->product == CODA_DX6) in coda_open()
2602 max = CODADX6_MAX_INSTANCES - 1; in coda_open()
2603 idx = ida_alloc_max(&dev->ida, max, GFP_KERNEL); in coda_open()
2611 ret = -ENOMEM; in coda_open()
2615 ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); in coda_open()
2618 ctx->cvd = to_coda_video_device(vdev); in coda_open()
2619 ctx->inst_type = ctx->cvd->type; in coda_open()
2620 ctx->ops = ctx->cvd->ops; in coda_open()
2621 ctx->use_bit = !ctx->cvd->direct; in coda_open()
2622 init_completion(&ctx->completion); in coda_open()
2623 INIT_WORK(&ctx->pic_run_work, coda_pic_run_work); in coda_open()
2624 if (ctx->ops->seq_init_work) in coda_open()
2625 INIT_WORK(&ctx->seq_init_work, ctx->ops->seq_init_work); in coda_open()
2626 if (ctx->ops->seq_end_work) in coda_open()
2627 INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work); in coda_open()
2628 v4l2_fh_init(&ctx->fh, video_devdata(file)); in coda_open()
2629 file->private_data = &ctx->fh; in coda_open()
2630 v4l2_fh_add(&ctx->fh); in coda_open()
2631 ctx->dev = dev; in coda_open()
2632 ctx->idx = idx; in coda_open()
2636 switch (dev->devtype->product) { in coda_open()
2644 if (enable_bwb || ctx->inst_type == CODA_INST_ENCODER) in coda_open()
2645 ctx->frame_mem_ctrl = CODA9_FRAME_ENABLE_BWB; in coda_open()
2649 ctx->reg_idx = 0; in coda_open()
2652 ctx->reg_idx = idx; in coda_open()
2654 if (ctx->dev->vdoa && !disable_vdoa) { in coda_open()
2655 ctx->vdoa = vdoa_context_create(dev->vdoa); in coda_open()
2656 if (!ctx->vdoa) in coda_open()
2657 v4l2_warn(&dev->v4l2_dev, in coda_open()
2660 ctx->use_vdoa = false; in coda_open()
2663 ret = pm_runtime_resume_and_get(dev->dev); in coda_open()
2665 v4l2_err(&dev->v4l2_dev, "failed to power up: %d\n", ret); in coda_open()
2669 ret = clk_prepare_enable(dev->clk_per); in coda_open()
2673 ret = clk_prepare_enable(dev->clk_ahb); in coda_open()
2678 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, in coda_open()
2679 ctx->ops->queue_init); in coda_open()
2680 if (IS_ERR(ctx->fh.m2m_ctx)) { in coda_open()
2681 ret = PTR_ERR(ctx->fh.m2m_ctx); in coda_open()
2683 v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n", in coda_open()
2690 v4l2_err(&dev->v4l2_dev, "failed to setup coda controls\n"); in coda_open()
2694 ctx->fh.ctrl_handler = &ctx->ctrls; in coda_open()
2696 mutex_init(&ctx->bitstream_mutex); in coda_open()
2697 mutex_init(&ctx->buffer_mutex); in coda_open()
2698 mutex_init(&ctx->wakeup_mutex); in coda_open()
2699 INIT_LIST_HEAD(&ctx->buffer_meta_list); in coda_open()
2700 spin_lock_init(&ctx->buffer_meta_lock); in coda_open()
2705 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in coda_open()
2707 clk_disable_unprepare(dev->clk_ahb); in coda_open()
2709 clk_disable_unprepare(dev->clk_per); in coda_open()
2711 pm_runtime_put_sync(dev->dev); in coda_open()
2713 v4l2_fh_del(&ctx->fh); in coda_open()
2714 v4l2_fh_exit(&ctx->fh); in coda_open()
2716 ida_free(&dev->ida, ctx->idx); in coda_open()
2725 struct coda_ctx *ctx = fh_to_ctx(file->private_data); in coda_release()
2729 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) in coda_release()
2733 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in coda_release()
2735 if (ctx->vdoa) in coda_release()
2736 vdoa_context_destroy(ctx->vdoa); in coda_release()
2739 if (ctx->ops->seq_end_work) { in coda_release()
2740 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_release()
2741 flush_work(&ctx->seq_end_work); in coda_release()
2744 if (ctx->dev->devtype->product == CODA_DX6) in coda_release()
2745 coda_free_aux_buf(dev, &ctx->workbuf); in coda_release()
2747 v4l2_ctrl_handler_free(&ctx->ctrls); in coda_release()
2748 clk_disable_unprepare(dev->clk_ahb); in coda_release()
2749 clk_disable_unprepare(dev->clk_per); in coda_release()
2750 pm_runtime_put_sync(dev->dev); in coda_release()
2751 v4l2_fh_del(&ctx->fh); in coda_release()
2752 v4l2_fh_exit(&ctx->fh); in coda_release()
2753 ida_free(&dev->ida, ctx->idx); in coda_release()
2754 if (ctx->ops->release) in coda_release()
2755 ctx->ops->release(ctx); in coda_release()
2756 debugfs_remove_recursive(ctx->debugfs_entry); in coda_release()
2777 ret = clk_prepare_enable(dev->clk_per); in coda_hw_init()
2781 ret = clk_prepare_enable(dev->clk_ahb); in coda_hw_init()
2785 reset_control_reset(dev->rstc); in coda_hw_init()
2789 * The 16-bit chars in the code buffer are in memory access in coda_hw_init()
2790 * order, re-sort them to CODA order for register download. in coda_hw_init()
2793 p = (u16 *)dev->codebuf.vaddr; in coda_hw_init()
2794 if (dev->devtype->product == CODA_DX6) { in coda_hw_init()
2804 3 - (i % 4)]); in coda_hw_init()
2814 if (dev->devtype->product == CODA_960 || in coda_hw_init()
2815 dev->devtype->product == CODA_7541 || in coda_hw_init()
2816 dev->devtype->product == CODA_HX4) { in coda_hw_init()
2817 coda_write(dev, dev->tempbuf.paddr, in coda_hw_init()
2821 coda_write(dev, dev->workbuf.paddr, in coda_hw_init()
2824 coda_write(dev, dev->codebuf.paddr, in coda_hw_init()
2829 switch (dev->devtype->product) { in coda_hw_init()
2838 if (dev->devtype->product == CODA_960) in coda_hw_init()
2844 if (dev->devtype->product != CODA_DX6) in coda_hw_init()
2850 /* Reset VPU and start processor */ in coda_hw_init()
2859 clk_disable_unprepare(dev->clk_ahb); in coda_hw_init()
2860 clk_disable_unprepare(dev->clk_per); in coda_hw_init()
2865 clk_disable_unprepare(dev->clk_per); in coda_hw_init()
2872 struct video_device *vfd = &dev->vfd[i]; in coda_register_device()
2876 if (i >= dev->devtype->num_vdevs) in coda_register_device()
2877 return -EINVAL; in coda_register_device()
2878 name = dev->devtype->vdevs[i]->name; in coda_register_device()
2880 strscpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name)); in coda_register_device()
2881 vfd->fops = &coda_fops; in coda_register_device()
2882 vfd->ioctl_ops = &coda_ioctl_ops; in coda_register_device()
2883 vfd->release = video_device_release_empty; in coda_register_device()
2884 vfd->lock = &dev->dev_mutex; in coda_register_device()
2885 vfd->v4l2_dev = &dev->v4l2_dev; in coda_register_device()
2886 vfd->vfl_dir = VFL_DIR_M2M; in coda_register_device()
2887 vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; in coda_register_device()
2897 v4l2_info(&dev->v4l2_dev, "%s registered as %s\n", in coda_register_device()
2907 /* Check if the firmware has a 16-byte Freescale header, skip it */ in coda_copy_firmware()
2911 * Check whether the firmware is in native order or pre-reordered for in coda_copy_firmware()
2915 u32 *dst = dev->codebuf.vaddr; in coda_copy_firmware()
2919 if (dev->devtype->product == CODA_DX6) { in coda_copy_firmware()
2920 for (i = 0; i < (size - 16) / 4; i++) in coda_copy_firmware()
2923 for (i = 0; i < (size - 16) / 4; i += 2) { in coda_copy_firmware()
2930 memcpy(dev->codebuf.vaddr, src, size); in coda_copy_firmware()
2940 if (dev->firmware >= ARRAY_SIZE(dev->devtype->firmware)) in coda_firmware_request()
2941 return -EINVAL; in coda_firmware_request()
2943 fw = dev->devtype->firmware[dev->firmware]; in coda_firmware_request()
2945 dev_dbg(dev->dev, "requesting firmware '%s' for %s\n", fw, in coda_firmware_request()
2946 coda_product_name(dev->devtype->product)); in coda_firmware_request()
2948 return request_firmware_nowait(THIS_MODULE, true, fw, dev->dev, in coda_firmware_request()
2958 dev->firmware++; in coda_fw_callback()
2961 v4l2_err(&dev->v4l2_dev, "firmware request failed\n"); in coda_fw_callback()
2966 if (dev->firmware > 0) { in coda_fw_callback()
2972 dev_info(dev->dev, "Using fallback firmware %s\n", in coda_fw_callback()
2973 dev->devtype->firmware[dev->firmware]); in coda_fw_callback()
2976 /* allocate auxiliary per-device code buffer for the BIT processor */ in coda_fw_callback()
2977 ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf", in coda_fw_callback()
2978 dev->debugfs_root); in coda_fw_callback()
2982 coda_copy_firmware(dev, fw->data, fw->size); in coda_fw_callback()
2987 v4l2_err(&dev->v4l2_dev, "HW initialization failed\n"); in coda_fw_callback()
2995 dev->m2m_dev = v4l2_m2m_init(&coda_m2m_ops); in coda_fw_callback()
2996 if (IS_ERR(dev->m2m_dev)) { in coda_fw_callback()
2997 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); in coda_fw_callback()
3001 for (i = 0; i < dev->devtype->num_vdevs; i++) { in coda_fw_callback()
3004 v4l2_err(&dev->v4l2_dev, in coda_fw_callback()
3006 dev->devtype->vdevs[i]->name, ret); in coda_fw_callback()
3011 pm_runtime_put_sync(dev->dev); in coda_fw_callback()
3015 while (--i >= 0) in coda_fw_callback()
3016 video_unregister_device(&dev->vfd[i]); in coda_fw_callback()
3017 v4l2_m2m_release(dev->m2m_dev); in coda_fw_callback()
3019 pm_runtime_put_sync(dev->dev); in coda_fw_callback()
3034 "vpu/vpu_fw_imx27_TO2.bin",
3035 "v4l-codadx6-imx27.bin"
3048 "vpu/vpu_fw_imx51.bin",
3049 "v4l-codahx4-imx51.bin"
3063 "vpu/vpu_fw_imx53.bin",
3064 "v4l-coda7541-imx53.bin"
3078 "vpu/vpu_fw_imx6q.bin",
3079 "v4l-coda960-imx6q.bin"
3093 "vpu/vpu_fw_imx6d.bin",
3094 "v4l-coda960-imx6dl.bin"
3108 { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
3109 { .compatible = "fsl,imx51-vpu", .data = &coda_devdata[CODA_IMX51] },
3110 { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
3111 { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] },
3112 { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] },
3119 struct device_node *np = pdev->dev.of_node; in coda_probe()
3124 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in coda_probe()
3126 return -ENOMEM; in coda_probe()
3128 dev->devtype = of_device_get_match_data(&pdev->dev); in coda_probe()
3130 dev->dev = &pdev->dev; in coda_probe()
3131 dev->clk_per = devm_clk_get(&pdev->dev, "per"); in coda_probe()
3132 if (IS_ERR(dev->clk_per)) { in coda_probe()
3133 dev_err(&pdev->dev, "Could not get per clock\n"); in coda_probe()
3134 return PTR_ERR(dev->clk_per); in coda_probe()
3137 dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in coda_probe()
3138 if (IS_ERR(dev->clk_ahb)) { in coda_probe()
3139 dev_err(&pdev->dev, "Could not get ahb clock\n"); in coda_probe()
3140 return PTR_ERR(dev->clk_ahb); in coda_probe()
3144 dev->regs_base = devm_platform_ioremap_resource(pdev, 0); in coda_probe()
3145 if (IS_ERR(dev->regs_base)) in coda_probe()
3146 return PTR_ERR(dev->regs_base); in coda_probe()
3155 ret = devm_request_irq(&pdev->dev, irq, coda_irq_handler, 0, in coda_probe()
3156 CODA_NAME "-video", dev); in coda_probe()
3158 dev_err(&pdev->dev, "failed to request irq: %d\n", ret); in coda_probe()
3163 if (dev->devtype->product == CODA_960) { in coda_probe()
3168 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, in coda_probe()
3170 IRQF_ONESHOT, CODA_NAME "-jpeg", in coda_probe()
3173 dev_err(&pdev->dev, "failed to request jpeg irq\n"); in coda_probe()
3178 dev->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, in coda_probe()
3180 if (IS_ERR(dev->rstc)) { in coda_probe()
3181 ret = PTR_ERR(dev->rstc); in coda_probe()
3182 dev_err(&pdev->dev, "failed get reset control: %d\n", ret); in coda_probe()
3189 dev_err(&pdev->dev, "iram pool not available\n"); in coda_probe()
3190 return -ENOMEM; in coda_probe()
3192 dev->iram_pool = pool; in coda_probe()
3195 dev->vdoa = coda_get_vdoa_data(); in coda_probe()
3196 if (PTR_ERR(dev->vdoa) == -EPROBE_DEFER) in coda_probe()
3197 return -EPROBE_DEFER; in coda_probe()
3199 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); in coda_probe()
3203 ratelimit_default_init(&dev->mb_err_rs); in coda_probe()
3204 mutex_init(&dev->dev_mutex); in coda_probe()
3205 mutex_init(&dev->coda_mutex); in coda_probe()
3206 ida_init(&dev->ida); in coda_probe()
3208 dev->debugfs_root = debugfs_create_dir("coda", NULL); in coda_probe()
3210 /* allocate auxiliary per-device buffers for the BIT processor */ in coda_probe()
3211 if (dev->devtype->product == CODA_DX6) { in coda_probe()
3212 ret = coda_alloc_aux_buf(dev, &dev->workbuf, in coda_probe()
3213 dev->devtype->workbuf_size, "workbuf", in coda_probe()
3214 dev->debugfs_root); in coda_probe()
3219 if (dev->devtype->tempbuf_size) { in coda_probe()
3220 ret = coda_alloc_aux_buf(dev, &dev->tempbuf, in coda_probe()
3221 dev->devtype->tempbuf_size, "tempbuf", in coda_probe()
3222 dev->debugfs_root); in coda_probe()
3227 dev->iram.size = dev->devtype->iram_size; in coda_probe()
3228 dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size, in coda_probe()
3229 &dev->iram.paddr); in coda_probe()
3230 if (!dev->iram.vaddr) { in coda_probe()
3231 dev_warn(&pdev->dev, "unable to alloc iram\n"); in coda_probe()
3233 memset(dev->iram.vaddr, 0, dev->iram.size); in coda_probe()
3234 dev->iram.blob.data = dev->iram.vaddr; in coda_probe()
3235 dev->iram.blob.size = dev->iram.size; in coda_probe()
3236 dev->iram.dentry = debugfs_create_blob("iram", 0444, in coda_probe()
3237 dev->debugfs_root, in coda_probe()
3238 &dev->iram.blob); in coda_probe()
3241 dev->workqueue = alloc_workqueue("coda", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); in coda_probe()
3242 if (!dev->workqueue) { in coda_probe()
3243 dev_err(&pdev->dev, "unable to alloc workqueue\n"); in coda_probe()
3244 ret = -ENOMEM; in coda_probe()
3255 pm_runtime_get_noresume(&pdev->dev); in coda_probe()
3256 pm_runtime_set_active(&pdev->dev); in coda_probe()
3257 pm_runtime_enable(&pdev->dev); in coda_probe()
3265 pm_runtime_disable(&pdev->dev); in coda_probe()
3266 pm_runtime_put_noidle(&pdev->dev); in coda_probe()
3267 destroy_workqueue(dev->workqueue); in coda_probe()
3269 v4l2_device_unregister(&dev->v4l2_dev); in coda_probe()
3278 for (i = 0; i < ARRAY_SIZE(dev->vfd); i++) { in coda_remove()
3279 if (video_get_drvdata(&dev->vfd[i])) in coda_remove()
3280 video_unregister_device(&dev->vfd[i]); in coda_remove()
3282 if (dev->m2m_dev) in coda_remove()
3283 v4l2_m2m_release(dev->m2m_dev); in coda_remove()
3284 pm_runtime_disable(&pdev->dev); in coda_remove()
3285 v4l2_device_unregister(&dev->v4l2_dev); in coda_remove()
3286 destroy_workqueue(dev->workqueue); in coda_remove()
3287 if (dev->iram.vaddr) in coda_remove()
3288 gen_pool_free(dev->iram_pool, (unsigned long)dev->iram.vaddr, in coda_remove()
3289 dev->iram.size); in coda_remove()
3290 coda_free_aux_buf(dev, &dev->codebuf); in coda_remove()
3291 coda_free_aux_buf(dev, &dev->tempbuf); in coda_remove()
3292 coda_free_aux_buf(dev, &dev->workbuf); in coda_remove()
3293 debugfs_remove_recursive(dev->debugfs_root); in coda_remove()
3294 ida_destroy(&dev->ida); in coda_remove()
3304 if (dev->pm_domain && cdev->codebuf.vaddr) { in coda_runtime_resume()
3307 v4l2_err(&cdev->v4l2_dev, "HW initialization failed\n"); in coda_runtime_resume()
3331 MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
3332 MODULE_DESCRIPTION("Coda multi-standard codec V4L2 driver");