Lines Matching +full:imx51 +full:- +full:src

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-encoder",
190 .name = "coda-jpeg-encoder",
205 .name = "coda-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, 0644, 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 ret = ctx->ops->start_streaming(ctx); in coda_start_streaming()
2067 if (ctx->inst_type == CODA_INST_DECODER) { in coda_start_streaming()
2068 if (ret == -EAGAIN) in coda_start_streaming()
2075 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
2077 list_del(&m2m_buf->list); in coda_start_streaming()
2078 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_DONE); in coda_start_streaming()
2084 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_start_streaming()
2086 list_del(&m2m_buf->list); in coda_start_streaming()
2087 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_QUEUED); in coda_start_streaming()
2089 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) in coda_start_streaming()
2092 while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) in coda_start_streaming()
2101 struct coda_dev *dev = ctx->dev; in coda_stop_streaming()
2105 stop = ctx->streamon_out && ctx->streamon_cap; in coda_stop_streaming()
2107 coda_dbg(1, ctx, "stop streaming %s\n", v4l2_type_names[q->type]); in coda_stop_streaming()
2109 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in coda_stop_streaming()
2110 ctx->streamon_out = 0; in coda_stop_streaming()
2114 ctx->qsequence = 0; in coda_stop_streaming()
2116 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) in coda_stop_streaming()
2119 ctx->streamon_cap = 0; in coda_stop_streaming()
2121 ctx->osequence = 0; in coda_stop_streaming()
2122 ctx->sequence_offset = 0; in coda_stop_streaming()
2124 while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) in coda_stop_streaming()
2131 if (ctx->ops->seq_end_work) { in coda_stop_streaming()
2132 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_stop_streaming()
2133 flush_work(&ctx->seq_end_work); in coda_stop_streaming()
2135 spin_lock(&ctx->buffer_meta_lock); in coda_stop_streaming()
2136 while (!list_empty(&ctx->buffer_meta_list)) { in coda_stop_streaming()
2137 meta = list_first_entry(&ctx->buffer_meta_list, in coda_stop_streaming()
2139 list_del(&meta->list); in coda_stop_streaming()
2142 ctx->num_metas = 0; in coda_stop_streaming()
2143 spin_unlock(&ctx->buffer_meta_lock); in coda_stop_streaming()
2144 kfifo_init(&ctx->bitstream_fifo, in coda_stop_streaming()
2145 ctx->bitstream.vaddr, ctx->bitstream.size); in coda_stop_streaming()
2146 ctx->runcounter = 0; in coda_stop_streaming()
2147 ctx->aborting = 0; in coda_stop_streaming()
2148 ctx->hold = false; in coda_stop_streaming()
2151 if (!ctx->streamon_out && !ctx->streamon_cap) in coda_stop_streaming()
2152 ctx->bit_stream_param &= ~CODA_BIT_STREAM_END_FLAG; in coda_stop_streaming()
2167 const char * const *val_names = v4l2_ctrl_get_menu(ctrl->id); in coda_s_ctrl()
2169 container_of(ctrl->handler, struct coda_ctx, ctrls); in coda_s_ctrl()
2173 ctrl->id, ctrl->name, ctrl->val, val_names[ctrl->val]); in coda_s_ctrl()
2176 ctrl->id, ctrl->name, ctrl->val); in coda_s_ctrl()
2178 switch (ctrl->id) { in coda_s_ctrl()
2180 if (ctrl->val) in coda_s_ctrl()
2181 ctx->params.rot_mode |= CODA_MIR_HOR; in coda_s_ctrl()
2183 ctx->params.rot_mode &= ~CODA_MIR_HOR; in coda_s_ctrl()
2186 if (ctrl->val) in coda_s_ctrl()
2187 ctx->params.rot_mode |= CODA_MIR_VER; in coda_s_ctrl()
2189 ctx->params.rot_mode &= ~CODA_MIR_VER; in coda_s_ctrl()
2192 ctx->params.bitrate = ctrl->val / 1000; in coda_s_ctrl()
2193 ctx->params.bitrate_changed = true; in coda_s_ctrl()
2196 ctx->params.gop_size = ctrl->val; in coda_s_ctrl()
2199 ctx->params.h264_intra_qp = ctrl->val; in coda_s_ctrl()
2200 ctx->params.h264_intra_qp_changed = true; in coda_s_ctrl()
2203 ctx->params.h264_inter_qp = ctrl->val; in coda_s_ctrl()
2206 ctx->params.h264_min_qp = ctrl->val; in coda_s_ctrl()
2209 ctx->params.h264_max_qp = ctrl->val; in coda_s_ctrl()
2212 ctx->params.h264_slice_alpha_c0_offset_div2 = ctrl->val; in coda_s_ctrl()
2215 ctx->params.h264_slice_beta_offset_div2 = ctrl->val; in coda_s_ctrl()
2218 ctx->params.h264_disable_deblocking_filter_idc = ctrl->val; in coda_s_ctrl()
2221 ctx->params.h264_constrained_intra_pred_flag = ctrl->val; in coda_s_ctrl()
2224 ctx->params.frame_rc_enable = ctrl->val; in coda_s_ctrl()
2227 ctx->params.mb_rc_enable = ctrl->val; in coda_s_ctrl()
2230 ctx->params.h264_chroma_qp_index_offset = ctrl->val; in coda_s_ctrl()
2234 if (ctx->inst_type == CODA_INST_ENCODER) in coda_s_ctrl()
2235 ctx->params.h264_profile_idc = 66; in coda_s_ctrl()
2241 ctx->params.mpeg4_intra_qp = ctrl->val; in coda_s_ctrl()
2244 ctx->params.mpeg4_inter_qp = ctrl->val; in coda_s_ctrl()
2253 ctx->params.slice_mode = ctrl->val; in coda_s_ctrl()
2254 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2257 ctx->params.slice_max_mb = ctrl->val; in coda_s_ctrl()
2258 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2261 ctx->params.slice_max_bits = ctrl->val * 8; in coda_s_ctrl()
2262 ctx->params.slice_mode_changed = true; in coda_s_ctrl()
2267 ctx->params.intra_refresh = ctrl->val; in coda_s_ctrl()
2268 ctx->params.intra_refresh_changed = true; in coda_s_ctrl()
2271 ctx->params.force_ipicture = true; in coda_s_ctrl()
2274 coda_set_jpeg_compression_quality(ctx, ctrl->val); in coda_s_ctrl()
2277 ctx->params.jpeg_restart_interval = ctrl->val; in coda_s_ctrl()
2280 ctx->params.vbv_delay = ctrl->val; in coda_s_ctrl()
2283 ctx->params.vbv_size = min(ctrl->val * 8192, 0x7fffffff); in coda_s_ctrl()
2287 ctrl->id, ctrl->val); in coda_s_ctrl()
2288 return -EINVAL; in coda_s_ctrl()
2300 int max_gop_size = (ctx->dev->devtype->product == CODA_DX6) ? 60 : 99; in coda_encode_ctrls()
2302 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2304 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2306 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2308 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2310 if (ctx->dev->devtype->product != CODA_960) { in coda_encode_ctrls()
2311 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2314 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2316 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2317 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, -6, 6, 1, 0); in coda_encode_ctrls()
2318 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2319 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0); in coda_encode_ctrls()
2320 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, 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()
2331 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2332 V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, -12, 12, 1, 0); in coda_encode_ctrls()
2333 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2337 if (ctx->dev->devtype->product == CODA_HX4 || in coda_encode_ctrls()
2338 ctx->dev->devtype->product == CODA_7541) { in coda_encode_ctrls()
2339 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2347 if (ctx->dev->devtype->product == CODA_960) { in coda_encode_ctrls()
2348 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2358 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2360 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2362 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2366 if (ctx->dev->devtype->product == CODA_HX4 || in coda_encode_ctrls()
2367 ctx->dev->devtype->product == CODA_7541 || in coda_encode_ctrls()
2368 ctx->dev->devtype->product == CODA_960) { in coda_encode_ctrls()
2369 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2375 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2379 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2381 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2384 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2389 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2392 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2398 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_encode_ctrls()
2404 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_jpeg_encode_ctrls()
2406 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_jpeg_encode_ctrls()
2414 ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2421 if (ctx->h264_profile_ctrl) in coda_decode_ctrls()
2422 ctx->h264_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2424 if (ctx->dev->devtype->product == CODA_HX4 || in coda_decode_ctrls()
2425 ctx->dev->devtype->product == CODA_7541) in coda_decode_ctrls()
2427 else if (ctx->dev->devtype->product == CODA_960) in coda_decode_ctrls()
2431 ctx->h264_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2433 if (ctx->h264_level_ctrl) in coda_decode_ctrls()
2434 ctx->h264_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2436 ctx->mpeg2_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2440 if (ctx->mpeg2_profile_ctrl) in coda_decode_ctrls()
2441 ctx->mpeg2_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2443 ctx->mpeg2_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2447 if (ctx->mpeg2_level_ctrl) in coda_decode_ctrls()
2448 ctx->mpeg2_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2450 ctx->mpeg4_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2454 if (ctx->mpeg4_profile_ctrl) in coda_decode_ctrls()
2455 ctx->mpeg4_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2457 ctx->mpeg4_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, in coda_decode_ctrls()
2461 if (ctx->mpeg4_level_ctrl) in coda_decode_ctrls()
2462 ctx->mpeg4_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in coda_decode_ctrls()
2467 v4l2_ctrl_handler_init(&ctx->ctrls, 2); in coda_ctrls_setup()
2469 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2471 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2473 if (ctx->inst_type == CODA_INST_ENCODER) { in coda_ctrls_setup()
2474 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2477 if (ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG) in coda_ctrls_setup()
2482 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, in coda_ctrls_setup()
2485 if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_H264) in coda_ctrls_setup()
2489 if (ctx->ctrls.error) { in coda_ctrls_setup()
2490 v4l2_err(&ctx->dev->v4l2_dev, in coda_ctrls_setup()
2492 ctx->ctrls.error); in coda_ctrls_setup()
2493 return -EINVAL; in coda_ctrls_setup()
2496 return v4l2_ctrl_handler_setup(&ctx->ctrls); in coda_ctrls_setup()
2501 vq->drv_priv = ctx; in coda_queue_init()
2502 vq->ops = &coda_qops; in coda_queue_init()
2503 vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in coda_queue_init()
2504 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in coda_queue_init()
2505 vq->lock = &ctx->dev->dev_mutex; in coda_queue_init()
2506 /* One way to indicate end-of-stream for coda is to set the in coda_queue_init()
2512 vq->allow_zero_bytesused = 1; in coda_queue_init()
2518 vq->min_buffers_needed = 1; in coda_queue_init()
2519 vq->dev = ctx->dev->dev; in coda_queue_init()
2529 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in coda_encoder_queue_init()
2530 src_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_encoder_queue_init()
2531 src_vq->mem_ops = &vb2_dma_contig_memops; in coda_encoder_queue_init()
2537 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in coda_encoder_queue_init()
2538 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_encoder_queue_init()
2539 dst_vq->mem_ops = &vb2_dma_contig_memops; in coda_encoder_queue_init()
2549 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in coda_decoder_queue_init()
2550 src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; in coda_decoder_queue_init()
2551 src_vq->mem_ops = &vb2_vmalloc_memops; in coda_decoder_queue_init()
2557 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in coda_decoder_queue_init()
2558 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; in coda_decoder_queue_init()
2559 dst_vq->dma_attrs = DMA_ATTR_NO_KERNEL_MAPPING; in coda_decoder_queue_init()
2560 dst_vq->mem_ops = &vb2_dma_contig_memops; in coda_decoder_queue_init()
2581 return -ENOMEM; in coda_open()
2583 if (dev->devtype->product == CODA_DX6) in coda_open()
2584 max = CODADX6_MAX_INSTANCES - 1; in coda_open()
2585 idx = ida_alloc_max(&dev->ida, max, GFP_KERNEL); in coda_open()
2593 ret = -ENOMEM; in coda_open()
2597 ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); in coda_open()
2600 ctx->cvd = to_coda_video_device(vdev); in coda_open()
2601 ctx->inst_type = ctx->cvd->type; in coda_open()
2602 ctx->ops = ctx->cvd->ops; in coda_open()
2603 ctx->use_bit = !ctx->cvd->direct; in coda_open()
2604 init_completion(&ctx->completion); in coda_open()
2605 INIT_WORK(&ctx->pic_run_work, coda_pic_run_work); in coda_open()
2606 if (ctx->ops->seq_init_work) in coda_open()
2607 INIT_WORK(&ctx->seq_init_work, ctx->ops->seq_init_work); in coda_open()
2608 if (ctx->ops->seq_end_work) in coda_open()
2609 INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work); in coda_open()
2610 v4l2_fh_init(&ctx->fh, video_devdata(file)); in coda_open()
2611 file->private_data = &ctx->fh; in coda_open()
2612 v4l2_fh_add(&ctx->fh); in coda_open()
2613 ctx->dev = dev; in coda_open()
2614 ctx->idx = idx; in coda_open()
2618 switch (dev->devtype->product) { in coda_open()
2626 if (enable_bwb || ctx->inst_type == CODA_INST_ENCODER) in coda_open()
2627 ctx->frame_mem_ctrl = CODA9_FRAME_ENABLE_BWB; in coda_open()
2631 ctx->reg_idx = 0; in coda_open()
2634 ctx->reg_idx = idx; in coda_open()
2636 if (ctx->dev->vdoa && !disable_vdoa) { in coda_open()
2637 ctx->vdoa = vdoa_context_create(dev->vdoa); in coda_open()
2638 if (!ctx->vdoa) in coda_open()
2639 v4l2_warn(&dev->v4l2_dev, in coda_open()
2642 ctx->use_vdoa = false; in coda_open()
2645 ret = pm_runtime_get_sync(dev->dev); in coda_open()
2647 v4l2_err(&dev->v4l2_dev, "failed to power up: %d\n", ret); in coda_open()
2651 ret = clk_prepare_enable(dev->clk_per); in coda_open()
2655 ret = clk_prepare_enable(dev->clk_ahb); in coda_open()
2660 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, in coda_open()
2661 ctx->ops->queue_init); in coda_open()
2662 if (IS_ERR(ctx->fh.m2m_ctx)) { in coda_open()
2663 ret = PTR_ERR(ctx->fh.m2m_ctx); in coda_open()
2665 v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n", in coda_open()
2672 v4l2_err(&dev->v4l2_dev, "failed to setup coda controls\n"); in coda_open()
2676 ctx->fh.ctrl_handler = &ctx->ctrls; in coda_open()
2678 mutex_init(&ctx->bitstream_mutex); in coda_open()
2679 mutex_init(&ctx->buffer_mutex); in coda_open()
2680 mutex_init(&ctx->wakeup_mutex); in coda_open()
2681 INIT_LIST_HEAD(&ctx->buffer_meta_list); in coda_open()
2682 spin_lock_init(&ctx->buffer_meta_lock); in coda_open()
2687 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in coda_open()
2689 clk_disable_unprepare(dev->clk_ahb); in coda_open()
2691 clk_disable_unprepare(dev->clk_per); in coda_open()
2693 pm_runtime_put_sync(dev->dev); in coda_open()
2694 v4l2_fh_del(&ctx->fh); in coda_open()
2695 v4l2_fh_exit(&ctx->fh); in coda_open()
2697 ida_free(&dev->ida, ctx->idx); in coda_open()
2706 struct coda_ctx *ctx = fh_to_ctx(file->private_data); in coda_release()
2710 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) in coda_release()
2714 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in coda_release()
2716 if (ctx->vdoa) in coda_release()
2717 vdoa_context_destroy(ctx->vdoa); in coda_release()
2720 if (ctx->ops->seq_end_work) { in coda_release()
2721 queue_work(dev->workqueue, &ctx->seq_end_work); in coda_release()
2722 flush_work(&ctx->seq_end_work); in coda_release()
2725 if (ctx->dev->devtype->product == CODA_DX6) in coda_release()
2726 coda_free_aux_buf(dev, &ctx->workbuf); in coda_release()
2728 v4l2_ctrl_handler_free(&ctx->ctrls); in coda_release()
2729 clk_disable_unprepare(dev->clk_ahb); in coda_release()
2730 clk_disable_unprepare(dev->clk_per); in coda_release()
2731 pm_runtime_put_sync(dev->dev); in coda_release()
2732 v4l2_fh_del(&ctx->fh); in coda_release()
2733 v4l2_fh_exit(&ctx->fh); in coda_release()
2734 ida_free(&dev->ida, ctx->idx); in coda_release()
2735 if (ctx->ops->release) in coda_release()
2736 ctx->ops->release(ctx); in coda_release()
2737 debugfs_remove_recursive(ctx->debugfs_entry); in coda_release()
2758 ret = clk_prepare_enable(dev->clk_per); in coda_hw_init()
2762 ret = clk_prepare_enable(dev->clk_ahb); in coda_hw_init()
2766 reset_control_reset(dev->rstc); in coda_hw_init()
2770 * The 16-bit chars in the code buffer are in memory access in coda_hw_init()
2771 * order, re-sort them to CODA order for register download. in coda_hw_init()
2774 p = (u16 *)dev->codebuf.vaddr; in coda_hw_init()
2775 if (dev->devtype->product == CODA_DX6) { in coda_hw_init()
2785 3 - (i % 4)]); in coda_hw_init()
2795 if (dev->devtype->product == CODA_960 || in coda_hw_init()
2796 dev->devtype->product == CODA_7541 || in coda_hw_init()
2797 dev->devtype->product == CODA_HX4) { in coda_hw_init()
2798 coda_write(dev, dev->tempbuf.paddr, in coda_hw_init()
2802 coda_write(dev, dev->workbuf.paddr, in coda_hw_init()
2805 coda_write(dev, dev->codebuf.paddr, in coda_hw_init()
2810 switch (dev->devtype->product) { in coda_hw_init()
2819 if (dev->devtype->product == CODA_960) in coda_hw_init()
2825 if (dev->devtype->product != CODA_DX6) in coda_hw_init()
2840 clk_disable_unprepare(dev->clk_ahb); in coda_hw_init()
2841 clk_disable_unprepare(dev->clk_per); in coda_hw_init()
2846 clk_disable_unprepare(dev->clk_per); in coda_hw_init()
2853 struct video_device *vfd = &dev->vfd[i]; in coda_register_device()
2857 if (i >= dev->devtype->num_vdevs) in coda_register_device()
2858 return -EINVAL; in coda_register_device()
2859 type = dev->devtype->vdevs[i]->type; in coda_register_device()
2861 strscpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name)); in coda_register_device()
2862 vfd->fops = &coda_fops; in coda_register_device()
2863 vfd->ioctl_ops = &coda_ioctl_ops; in coda_register_device()
2864 vfd->release = video_device_release_empty, in coda_register_device()
2865 vfd->lock = &dev->dev_mutex; in coda_register_device()
2866 vfd->v4l2_dev = &dev->v4l2_dev; in coda_register_device()
2867 vfd->vfl_dir = VFL_DIR_M2M; in coda_register_device()
2868 vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; in coda_register_device()
2878 v4l2_info(&dev->v4l2_dev, "%s registered as %s\n", in coda_register_device()
2887 u32 *src = (u32 *)buf; in coda_copy_firmware() local
2889 /* Check if the firmware has a 16-byte Freescale header, skip it */ in coda_copy_firmware()
2891 src += 4; in coda_copy_firmware()
2893 * Check whether the firmware is in native order or pre-reordered for in coda_copy_firmware()
2896 if (__le16_to_cpup((__le16 *)src) == 0xe40e) { in coda_copy_firmware()
2897 u32 *dst = dev->codebuf.vaddr; in coda_copy_firmware()
2901 if (dev->devtype->product == CODA_DX6) { in coda_copy_firmware()
2902 for (i = 0; i < (size - 16) / 4; i++) in coda_copy_firmware()
2903 dst[i] = (src[i] << 16) | (src[i] >> 16); in coda_copy_firmware()
2905 for (i = 0; i < (size - 16) / 4; i += 2) { in coda_copy_firmware()
2906 dst[i] = (src[i + 1] << 16) | (src[i + 1] >> 16); in coda_copy_firmware()
2907 dst[i + 1] = (src[i] << 16) | (src[i] >> 16); in coda_copy_firmware()
2912 memcpy(dev->codebuf.vaddr, src, size); in coda_copy_firmware()
2922 if (dev->firmware >= ARRAY_SIZE(dev->devtype->firmware)) in coda_firmware_request()
2923 return -EINVAL; in coda_firmware_request()
2925 fw = dev->devtype->firmware[dev->firmware]; in coda_firmware_request()
2927 dev_dbg(dev->dev, "requesting firmware '%s' for %s\n", fw, in coda_firmware_request()
2928 coda_product_name(dev->devtype->product)); in coda_firmware_request()
2930 return request_firmware_nowait(THIS_MODULE, true, fw, dev->dev, in coda_firmware_request()
2940 dev->firmware++; in coda_fw_callback()
2943 v4l2_err(&dev->v4l2_dev, "firmware request failed\n"); in coda_fw_callback()
2948 if (dev->firmware > 0) { in coda_fw_callback()
2954 dev_info(dev->dev, "Using fallback firmware %s\n", in coda_fw_callback()
2955 dev->devtype->firmware[dev->firmware]); in coda_fw_callback()
2958 /* allocate auxiliary per-device code buffer for the BIT processor */ in coda_fw_callback()
2959 ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf", in coda_fw_callback()
2960 dev->debugfs_root); in coda_fw_callback()
2964 coda_copy_firmware(dev, fw->data, fw->size); in coda_fw_callback()
2969 v4l2_err(&dev->v4l2_dev, "HW initialization failed\n"); in coda_fw_callback()
2977 dev->m2m_dev = v4l2_m2m_init(&coda_m2m_ops); in coda_fw_callback()
2978 if (IS_ERR(dev->m2m_dev)) { in coda_fw_callback()
2979 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); in coda_fw_callback()
2983 for (i = 0; i < dev->devtype->num_vdevs; i++) { in coda_fw_callback()
2986 v4l2_err(&dev->v4l2_dev, in coda_fw_callback()
2988 dev->devtype->vdevs[i]->name, ret); in coda_fw_callback()
2993 pm_runtime_put_sync(dev->dev); in coda_fw_callback()
2997 while (--i >= 0) in coda_fw_callback()
2998 video_unregister_device(&dev->vfd[i]); in coda_fw_callback()
2999 v4l2_m2m_release(dev->m2m_dev); in coda_fw_callback()
3001 pm_runtime_put_sync(dev->dev); in coda_fw_callback()
3017 "v4l-codadx6-imx27.bin"
3031 "v4l-codahx4-imx51.bin"
3046 "v4l-coda7541-imx53.bin"
3061 "v4l-coda960-imx6q.bin"
3076 "v4l-coda960-imx6dl.bin"
3090 { .name = "coda-imx27", .driver_data = CODA_IMX27 },
3097 { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
3098 { .compatible = "fsl,imx51-vpu", .data = &coda_devdata[CODA_IMX51] },
3099 { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
3100 { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] },
3101 { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] },
3110 of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev); in coda_probe()
3112 struct coda_platform_data *pdata = pdev->dev.platform_data; in coda_probe()
3113 struct device_node *np = pdev->dev.of_node; in coda_probe()
3118 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in coda_probe()
3120 return -ENOMEM; in coda_probe()
3122 pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); in coda_probe()
3125 dev->devtype = of_id->data; in coda_probe()
3127 dev->devtype = &coda_devdata[pdev_id->driver_data]; in coda_probe()
3129 return -EINVAL; in coda_probe()
3131 dev->dev = &pdev->dev; in coda_probe()
3132 dev->clk_per = devm_clk_get(&pdev->dev, "per"); in coda_probe()
3133 if (IS_ERR(dev->clk_per)) { in coda_probe()
3134 dev_err(&pdev->dev, "Could not get per clock\n"); in coda_probe()
3135 return PTR_ERR(dev->clk_per); in coda_probe()
3138 dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in coda_probe()
3139 if (IS_ERR(dev->clk_ahb)) { in coda_probe()
3140 dev_err(&pdev->dev, "Could not get ahb clock\n"); in coda_probe()
3141 return PTR_ERR(dev->clk_ahb); in coda_probe()
3145 dev->regs_base = devm_platform_ioremap_resource(pdev, 0); in coda_probe()
3146 if (IS_ERR(dev->regs_base)) in coda_probe()
3147 return PTR_ERR(dev->regs_base); in coda_probe()
3156 ret = devm_request_irq(&pdev->dev, irq, coda_irq_handler, 0, in coda_probe()
3157 dev_name(&pdev->dev), dev); in coda_probe()
3159 dev_err(&pdev->dev, "failed to request irq: %d\n", ret); in coda_probe()
3164 if (dev->devtype->product == CODA_960) { in coda_probe()
3169 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, in coda_probe()
3174 dev_err(&pdev->dev, "failed to request jpeg irq\n"); in coda_probe()
3179 dev->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, in coda_probe()
3181 if (IS_ERR(dev->rstc)) { in coda_probe()
3182 ret = PTR_ERR(dev->rstc); in coda_probe()
3183 dev_err(&pdev->dev, "failed get reset control: %d\n", ret); in coda_probe()
3190 pool = gen_pool_get(pdata->iram_dev, NULL); in coda_probe()
3192 dev_err(&pdev->dev, "iram pool not available\n"); in coda_probe()
3193 return -ENOMEM; in coda_probe()
3195 dev->iram_pool = pool; in coda_probe()
3198 dev->vdoa = coda_get_vdoa_data(); in coda_probe()
3199 if (PTR_ERR(dev->vdoa) == -EPROBE_DEFER) in coda_probe()
3200 return -EPROBE_DEFER; in coda_probe()
3202 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); in coda_probe()
3206 mutex_init(&dev->dev_mutex); in coda_probe()
3207 mutex_init(&dev->coda_mutex); in coda_probe()
3208 ida_init(&dev->ida); in coda_probe()
3210 dev->debugfs_root = debugfs_create_dir("coda", NULL); in coda_probe()
3212 /* allocate auxiliary per-device buffers for the BIT processor */ in coda_probe()
3213 if (dev->devtype->product == CODA_DX6) { in coda_probe()
3214 ret = coda_alloc_aux_buf(dev, &dev->workbuf, in coda_probe()
3215 dev->devtype->workbuf_size, "workbuf", in coda_probe()
3216 dev->debugfs_root); in coda_probe()
3221 if (dev->devtype->tempbuf_size) { in coda_probe()
3222 ret = coda_alloc_aux_buf(dev, &dev->tempbuf, in coda_probe()
3223 dev->devtype->tempbuf_size, "tempbuf", in coda_probe()
3224 dev->debugfs_root); in coda_probe()
3229 dev->iram.size = dev->devtype->iram_size; in coda_probe()
3230 dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size, in coda_probe()
3231 &dev->iram.paddr); in coda_probe()
3232 if (!dev->iram.vaddr) { in coda_probe()
3233 dev_warn(&pdev->dev, "unable to alloc iram\n"); in coda_probe()
3235 memset(dev->iram.vaddr, 0, dev->iram.size); in coda_probe()
3236 dev->iram.blob.data = dev->iram.vaddr; in coda_probe()
3237 dev->iram.blob.size = dev->iram.size; in coda_probe()
3238 dev->iram.dentry = debugfs_create_blob("iram", 0644, in coda_probe()
3239 dev->debugfs_root, in coda_probe()
3240 &dev->iram.blob); in coda_probe()
3243 dev->workqueue = alloc_workqueue("coda", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); in coda_probe()
3244 if (!dev->workqueue) { in coda_probe()
3245 dev_err(&pdev->dev, "unable to alloc workqueue\n"); in coda_probe()
3246 ret = -ENOMEM; in coda_probe()
3257 pm_runtime_get_noresume(&pdev->dev); in coda_probe()
3258 pm_runtime_set_active(&pdev->dev); in coda_probe()
3259 pm_runtime_enable(&pdev->dev); in coda_probe()
3267 pm_runtime_disable(&pdev->dev); in coda_probe()
3268 pm_runtime_put_noidle(&pdev->dev); in coda_probe()
3269 destroy_workqueue(dev->workqueue); in coda_probe()
3271 v4l2_device_unregister(&dev->v4l2_dev); in coda_probe()
3280 for (i = 0; i < ARRAY_SIZE(dev->vfd); i++) { in coda_remove()
3281 if (video_get_drvdata(&dev->vfd[i])) in coda_remove()
3282 video_unregister_device(&dev->vfd[i]); in coda_remove()
3284 if (dev->m2m_dev) in coda_remove()
3285 v4l2_m2m_release(dev->m2m_dev); in coda_remove()
3286 pm_runtime_disable(&pdev->dev); in coda_remove()
3287 v4l2_device_unregister(&dev->v4l2_dev); in coda_remove()
3288 destroy_workqueue(dev->workqueue); in coda_remove()
3289 if (dev->iram.vaddr) in coda_remove()
3290 gen_pool_free(dev->iram_pool, (unsigned long)dev->iram.vaddr, in coda_remove()
3291 dev->iram.size); in coda_remove()
3292 coda_free_aux_buf(dev, &dev->codebuf); in coda_remove()
3293 coda_free_aux_buf(dev, &dev->tempbuf); in coda_remove()
3294 coda_free_aux_buf(dev, &dev->workbuf); in coda_remove()
3295 debugfs_remove_recursive(dev->debugfs_root); in coda_remove()
3296 ida_destroy(&dev->ida); in coda_remove()
3306 if (dev->pm_domain && cdev->codebuf.vaddr) { in coda_runtime_resume()
3309 v4l2_err(&cdev->v4l2_dev, "HW initialization failed\n"); in coda_runtime_resume()
3334 MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
3335 MODULE_DESCRIPTION("Coda multi-standard codec V4L2 driver");