Lines Matching +full:imx8qxp +full:- +full:jpgenc
1 // SPDX-License-Identifier: GPL-2.0
6 * The multi-planar buffers API is used.
12 * YUV420 is the only multi-planar format supported.
38 * This is inspired by the drivers/media/platform/samsung/s5p-jpeg driver
40 * Copyright 2018-2019 NXP
56 #include <media/v4l2-jpeg.h>
57 #include <media/v4l2-mem2mem.h>
58 #include <media/v4l2-ioctl.h>
59 #include <media/v4l2-common.h>
60 #include <media/v4l2-event.h>
61 #include <media/videobuf2-dma-contig.h>
63 #include "mxc-jpeg-hw.h"
64 #include "mxc-jpeg.h"
70 .subsampling = -1,
71 .nc = -1,
91 .name = "BGR 12bit", /*12-bit BGR packed format*/
119 .name = "ABGR 12bit", /* 12-bit ABGR packed format */
271 .compatible = "nxp,imx8qxp-jpgdec",
275 .compatible = "nxp,imx8qxp-jpgenc",
556 /* common v4l buffer stuff -- must be first */
560 /* mxc-jpeg specific */
576 MODULE_PARM_DESC(debug, "Debug level (0-3)");
601 for (plane_no = 0; plane_no < buf->num_planes; plane_no++) { in print_mxc_buf()
607 v4l2_dbg(3, debug, &jpeg->v4l2_dev, in print_mxc_buf()
627 /* index-th format of searched type found ? */ in enum_fmt()
628 if (num == f->index) in enum_fmt()
631 * just increment per-type index in enum_fmt()
639 return -EINVAL; in enum_fmt()
641 f->pixelformat = mxc_formats[i].fourcc; in enum_fmt()
653 if (fmt->fourcc == pixelformat) in mxc_jpeg_find_format()
691 return &ctx->out_q; in mxc_jpeg_get_q_data()
692 return &ctx->cap_q; in mxc_jpeg_get_q_data()
699 int img_fmt = desc->stm_ctrl & STM_CTRL_IMAGE_FORMAT_MASK; in mxc_jpeg_addrs()
700 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(raw_buf->vb2_queue); in mxc_jpeg_addrs()
703 q_data = mxc_jpeg_get_q_data(ctx, raw_buf->type); in mxc_jpeg_addrs()
704 desc->buf_base0 = vb2_dma_contig_plane_dma_addr(raw_buf, 0); in mxc_jpeg_addrs()
705 desc->buf_base1 = 0; in mxc_jpeg_addrs()
707 if (raw_buf->num_planes == 2) in mxc_jpeg_addrs()
708 desc->buf_base1 = vb2_dma_contig_plane_dma_addr(raw_buf, 1); in mxc_jpeg_addrs()
710 desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0]; in mxc_jpeg_addrs()
712 desc->stm_bufbase = vb2_dma_contig_plane_dma_addr(jpeg_buf, 0) + in mxc_jpeg_addrs()
718 if (!fmt || !(fmt->flags & MXC_JPEG_FMT_TYPE_RAW)) in mxc_jpeg_is_extended_sequential()
721 if (fmt->precision > 8) in mxc_jpeg_is_extended_sequential()
733 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event EOS reached"); in notify_eos()
734 v4l2_event_queue_fh(&ctx->fh, &ev); in notify_eos()
744 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event SRC_CH_RESOLUTION"); in notify_src_chg()
745 v4l2_event_queue_fh(&ctx->fh, &ev); in notify_src_chg()
750 if (!slot_data->used) in mxc_get_free_slot()
751 return slot_data->slot; in mxc_get_free_slot()
752 return -1; in mxc_get_free_slot()
761 if (jpeg->slot_data.desc) in mxc_jpeg_alloc_slot_data()
765 desc = dma_alloc_coherent(jpeg->dev, in mxc_jpeg_alloc_slot_data()
767 &jpeg->slot_data.desc_handle, in mxc_jpeg_alloc_slot_data()
771 jpeg->slot_data.desc = desc; in mxc_jpeg_alloc_slot_data()
774 cfg_desc = dma_alloc_coherent(jpeg->dev, in mxc_jpeg_alloc_slot_data()
776 &jpeg->slot_data.cfg_desc_handle, in mxc_jpeg_alloc_slot_data()
780 jpeg->slot_data.cfg_desc = cfg_desc; in mxc_jpeg_alloc_slot_data()
783 cfg_stm = dma_alloc_coherent(jpeg->dev, in mxc_jpeg_alloc_slot_data()
785 &jpeg->slot_data.cfg_stream_handle, in mxc_jpeg_alloc_slot_data()
789 jpeg->slot_data.cfg_stream_vaddr = cfg_stm; in mxc_jpeg_alloc_slot_data()
792 jpeg->slot_data.used = true; in mxc_jpeg_alloc_slot_data()
796 dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); in mxc_jpeg_alloc_slot_data()
804 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), in mxc_jpeg_free_slot_data()
805 jpeg->slot_data.desc, in mxc_jpeg_free_slot_data()
806 jpeg->slot_data.desc_handle); in mxc_jpeg_free_slot_data()
809 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), in mxc_jpeg_free_slot_data()
810 jpeg->slot_data.cfg_desc, in mxc_jpeg_free_slot_data()
811 jpeg->slot_data.cfg_desc_handle); in mxc_jpeg_free_slot_data()
814 dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, in mxc_jpeg_free_slot_data()
815 jpeg->slot_data.cfg_stream_vaddr, in mxc_jpeg_free_slot_data()
816 jpeg->slot_data.cfg_stream_handle); in mxc_jpeg_free_slot_data()
818 jpeg->slot_data.used = false; in mxc_jpeg_free_slot_data()
825 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) { in mxc_jpeg_check_and_set_last_buffer()
826 dst_buf->flags |= V4L2_BUF_FLAG_LAST; in mxc_jpeg_check_and_set_last_buffer()
827 v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); in mxc_jpeg_check_and_set_last_buffer()
829 ctx->header_parsed = false; in mxc_jpeg_check_and_set_last_buffer()
835 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_job_finish()
836 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_job_finish()
839 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
840 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
842 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
843 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
847 mxc_jpeg_disable_irq(reg, ctx->slot); in mxc_jpeg_job_finish()
848 jpeg->slot_data.used = false; in mxc_jpeg_job_finish()
855 const struct mxc_jpeg_fmt *fmt = q_data->fmt; in mxc_jpeg_get_plane_size()
859 if (plane_no >= fmt->mem_planes) in mxc_jpeg_get_plane_size()
862 if (fmt->mem_planes == fmt->comp_planes) in mxc_jpeg_get_plane_size()
863 return q_data->sizeimage[plane_no]; in mxc_jpeg_get_plane_size()
865 if (plane_no < fmt->mem_planes - 1) in mxc_jpeg_get_plane_size()
866 return q_data->sizeimage[plane_no]; in mxc_jpeg_get_plane_size()
868 size = q_data->sizeimage[fmt->mem_planes - 1]; in mxc_jpeg_get_plane_size()
871 if (WARN_ON_ONCE(fmt->comp_planes > ARRAY_SIZE(q_data->sizeimage))) in mxc_jpeg_get_plane_size()
874 for (i = fmt->mem_planes; i < fmt->comp_planes; i++) in mxc_jpeg_get_plane_size()
875 size += q_data->sizeimage[i]; in mxc_jpeg_get_plane_size()
884 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_dec_irq()
885 struct device *dev = jpeg->dev; in mxc_jpeg_dec_irq()
895 spin_lock(&jpeg->hw_lock); in mxc_jpeg_dec_irq()
901 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); in mxc_jpeg_dec_irq()
905 if (slot != ctx->slot) { in mxc_jpeg_dec_irq()
906 /* TODO investigate when adding multi-instance support */ in mxc_jpeg_dec_irq()
908 slot, ctx->slot); in mxc_jpeg_dec_irq()
912 if (!jpeg->slot_data.used) in mxc_jpeg_dec_irq()
918 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in mxc_jpeg_dec_irq()
919 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in mxc_jpeg_dec_irq()
924 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf); in mxc_jpeg_dec_irq()
940 if (jpeg->mode == MXC_JPEG_ENCODE && in mxc_jpeg_dec_irq()
941 ctx->enc_state == MXC_JPEG_ENC_CONF) { in mxc_jpeg_dec_irq()
943 ctx->enc_state = MXC_JPEG_ENCODING; in mxc_jpeg_dec_irq()
945 mxc_jpeg_enc_set_quality(dev, reg, ctx->jpeg_quality); in mxc_jpeg_dec_irq()
946 mxc_jpeg_enc_mode_go(dev, reg, mxc_jpeg_is_extended_sequential(q_data->fmt)); in mxc_jpeg_dec_irq()
949 if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed) { in mxc_jpeg_dec_irq()
950 jpeg_src_buf->dht_needed = false; in mxc_jpeg_dec_irq()
955 if (jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_dec_irq()
957 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); in mxc_jpeg_dec_irq()
963 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); in mxc_jpeg_dec_irq()
964 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0); in mxc_jpeg_dec_irq()
965 if (q_data->fmt->mem_planes == 2) { in mxc_jpeg_dec_irq()
967 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload); in mxc_jpeg_dec_irq()
970 vb2_get_plane_payload(&dst_buf->vb2_buf, 0), in mxc_jpeg_dec_irq()
971 vb2_get_plane_payload(&dst_buf->vb2_buf, 1)); in mxc_jpeg_dec_irq()
976 print_mxc_buf(jpeg, &src_buf->vb2_buf, 32); in mxc_jpeg_dec_irq()
978 print_mxc_buf(jpeg, &dst_buf->vb2_buf, 32); in mxc_jpeg_dec_irq()
983 spin_unlock(&jpeg->hw_lock); in mxc_jpeg_dec_irq()
984 cancel_delayed_work(&ctx->task_timer); in mxc_jpeg_dec_irq()
985 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_dec_irq()
988 spin_unlock(&jpeg->hw_lock); in mxc_jpeg_dec_irq()
1000 sof->precision = fmt->precision; in mxc_jpeg_fixup_sof()
1002 sof->precision = 8; /* TODO allow 8/12 bit precision*/ in mxc_jpeg_fixup_sof()
1003 sof->height = h; in mxc_jpeg_fixup_sof()
1004 _bswap16(&sof->height); in mxc_jpeg_fixup_sof()
1005 sof->width = w; in mxc_jpeg_fixup_sof()
1006 _bswap16(&sof->width); in mxc_jpeg_fixup_sof()
1013 sof->components_no = 3; in mxc_jpeg_fixup_sof()
1014 sof->comp[0].v = 0x2; in mxc_jpeg_fixup_sof()
1015 sof->comp[0].h = 0x2; in mxc_jpeg_fixup_sof()
1019 sof->components_no = 3; in mxc_jpeg_fixup_sof()
1020 sof->comp[0].v = 0x1; in mxc_jpeg_fixup_sof()
1021 sof->comp[0].h = 0x2; in mxc_jpeg_fixup_sof()
1028 sof->components_no = 3; in mxc_jpeg_fixup_sof()
1032 sof->components_no = 4; in mxc_jpeg_fixup_sof()
1036 sof->components_no = 1; in mxc_jpeg_fixup_sof()
1039 sof_length = 8 + 3 * sof->components_no; in mxc_jpeg_fixup_sof()
1040 sof->length = sof_length; in mxc_jpeg_fixup_sof()
1041 _bswap16(&sof->length); in mxc_jpeg_fixup_sof()
1057 sos->components_no = 3; in mxc_jpeg_fixup_sos()
1061 sos->components_no = 3; in mxc_jpeg_fixup_sos()
1068 sos->components_no = 3; in mxc_jpeg_fixup_sos()
1072 sos->components_no = 4; in mxc_jpeg_fixup_sos()
1076 sos->components_no = 1; in mxc_jpeg_fixup_sos()
1079 sos_length = 6 + 2 * sos->components_no; in mxc_jpeg_fixup_sos()
1080 sos->length = sos_length; in mxc_jpeg_fixup_sos()
1081 _bswap16(&sos->length); in mxc_jpeg_fixup_sos()
1084 sof_u8[sos_length - 1] = 0x0; in mxc_jpeg_fixup_sos()
1085 sof_u8[sos_length - 2] = 0x3f; in mxc_jpeg_fixup_sos()
1086 sof_u8[sos_length - 3] = 0x0; in mxc_jpeg_fixup_sos()
1113 if (fmt->is_rgb) { in mxc_jpeg_setup_cfg_stream()
1169 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_config_dec_desc()
1170 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_config_dec_desc()
1171 unsigned int slot = ctx->slot; in mxc_jpeg_config_dec_desc()
1172 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; in mxc_jpeg_config_dec_desc()
1173 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; in mxc_jpeg_config_dec_desc()
1174 dma_addr_t desc_handle = jpeg->slot_data.desc_handle; in mxc_jpeg_config_dec_desc()
1175 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; in mxc_jpeg_config_dec_desc()
1176 dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle; in mxc_jpeg_config_dec_desc()
1177 unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size; in mxc_jpeg_config_dec_desc()
1178 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; in mxc_jpeg_config_dec_desc()
1184 desc->next_descpt_ptr = 0; /* end of chain */ in mxc_jpeg_config_dec_desc()
1186 desc->imgsize = q_data_cap->w_adjusted << 16 | q_data_cap->h_adjusted; in mxc_jpeg_config_dec_desc()
1187 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data_cap->fmt->fourcc); in mxc_jpeg_config_dec_desc()
1188 desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF); /* clear image format */ in mxc_jpeg_config_dec_desc()
1189 desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt); in mxc_jpeg_config_dec_desc()
1190 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_dec_desc()
1191 if (mxc_jpeg_is_extended_sequential(jpeg_src_buf->fmt)) in mxc_jpeg_config_dec_desc()
1192 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_dec_desc()
1194 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_dec_desc()
1195 desc->line_pitch = q_data_cap->bytesperline[0]; in mxc_jpeg_config_dec_desc()
1198 print_descriptor_info(jpeg->dev, desc); in mxc_jpeg_config_dec_desc()
1200 if (!jpeg_src_buf->dht_needed) { in mxc_jpeg_config_dec_desc()
1214 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; in mxc_jpeg_config_dec_desc()
1215 cfg_desc->buf_base0 = vb2_dma_contig_plane_dma_addr(dst_buf, 0); in mxc_jpeg_config_dec_desc()
1216 cfg_desc->buf_base1 = 0; in mxc_jpeg_config_dec_desc()
1217 cfg_desc->imgsize = MXC_JPEG_MIN_WIDTH << 16; in mxc_jpeg_config_dec_desc()
1218 cfg_desc->imgsize |= MXC_JPEG_MIN_HEIGHT; in mxc_jpeg_config_dec_desc()
1219 cfg_desc->line_pitch = MXC_JPEG_MIN_WIDTH * 2; in mxc_jpeg_config_dec_desc()
1220 cfg_desc->stm_ctrl = STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422); in mxc_jpeg_config_dec_desc()
1221 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_dec_desc()
1222 cfg_desc->stm_bufbase = cfg_stream_handle; in mxc_jpeg_config_dec_desc()
1223 cfg_desc->stm_bufsize = ALIGN(*cfg_size, 1024); in mxc_jpeg_config_dec_desc()
1224 print_descriptor_info(jpeg->dev, cfg_desc); in mxc_jpeg_config_dec_desc()
1235 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_config_enc_desc()
1236 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_config_enc_desc()
1237 unsigned int slot = ctx->slot; in mxc_jpeg_config_enc_desc()
1238 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; in mxc_jpeg_config_enc_desc()
1239 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; in mxc_jpeg_config_enc_desc()
1240 dma_addr_t desc_handle = jpeg->slot_data.desc_handle; in mxc_jpeg_config_enc_desc()
1241 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; in mxc_jpeg_config_enc_desc()
1242 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; in mxc_jpeg_config_enc_desc()
1247 q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type); in mxc_jpeg_config_enc_desc()
1249 jpeg->slot_data.cfg_stream_size = in mxc_jpeg_config_enc_desc()
1251 q_data->fmt->fourcc, in mxc_jpeg_config_enc_desc()
1252 q_data->crop.width, in mxc_jpeg_config_enc_desc()
1253 q_data->crop.height); in mxc_jpeg_config_enc_desc()
1256 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; in mxc_jpeg_config_enc_desc()
1258 cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle; in mxc_jpeg_config_enc_desc()
1259 cfg_desc->buf_base1 = 0; in mxc_jpeg_config_enc_desc()
1260 cfg_desc->line_pitch = 0; in mxc_jpeg_config_enc_desc()
1261 cfg_desc->stm_bufbase = 0; /* no output expected */ in mxc_jpeg_config_enc_desc()
1262 cfg_desc->stm_bufsize = 0x0; in mxc_jpeg_config_enc_desc()
1263 cfg_desc->imgsize = 0; in mxc_jpeg_config_enc_desc()
1264 cfg_desc->stm_ctrl = STM_CTRL_CONFIG_MOD(1); in mxc_jpeg_config_enc_desc()
1265 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_enc_desc()
1267 desc->next_descpt_ptr = 0; /* end of chain */ in mxc_jpeg_config_enc_desc()
1270 w = q_data->crop.width; in mxc_jpeg_config_enc_desc()
1271 h = q_data->crop.height; in mxc_jpeg_config_enc_desc()
1272 v4l_bound_align_image(&w, w, MXC_JPEG_MAX_WIDTH, q_data->fmt->h_align, in mxc_jpeg_config_enc_desc()
1273 &h, h, MXC_JPEG_MAX_HEIGHT, q_data->fmt->v_align, 0); in mxc_jpeg_config_enc_desc()
1275 mxc_jpeg_set_line_pitch(desc, q_data->bytesperline[0]); in mxc_jpeg_config_enc_desc()
1277 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data->fmt->fourcc); in mxc_jpeg_config_enc_desc()
1279 dev_err(jpeg->dev, "No valid image format detected\n"); in mxc_jpeg_config_enc_desc()
1280 desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) | in mxc_jpeg_config_enc_desc()
1282 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_enc_desc()
1283 if (mxc_jpeg_is_extended_sequential(q_data->fmt)) in mxc_jpeg_config_enc_desc()
1284 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_enc_desc()
1286 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_enc_desc()
1288 dev_dbg(jpeg->dev, "cfg_desc:\n"); in mxc_jpeg_config_enc_desc()
1289 print_descriptor_info(jpeg->dev, cfg_desc); in mxc_jpeg_config_enc_desc()
1290 dev_dbg(jpeg->dev, "enc desc:\n"); in mxc_jpeg_config_enc_desc()
1291 print_descriptor_info(jpeg->dev, desc); in mxc_jpeg_config_enc_desc()
1292 print_wrapper_info(jpeg->dev, reg); in mxc_jpeg_config_enc_desc()
1293 print_cast_status(jpeg->dev, reg, MXC_JPEG_ENCODE); in mxc_jpeg_config_enc_desc()
1304 if (mxc_formats[i].subsampling == fmt->subsampling && in mxc_jpeg_get_sibling_format()
1305 mxc_formats[i].nc == fmt->nc && in mxc_jpeg_get_sibling_format()
1306 mxc_formats[i].precision == fmt->precision && in mxc_jpeg_get_sibling_format()
1307 mxc_formats[i].is_rgb == fmt->is_rgb && in mxc_jpeg_get_sibling_format()
1308 mxc_formats[i].fourcc != fmt->fourcc) in mxc_jpeg_get_sibling_format()
1329 next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_set_last_buffer()
1331 ctx->fh.m2m_ctx->is_draining = true; in mxc_jpeg_set_last_buffer()
1332 ctx->fh.m2m_ctx->next_buf_last = true; in mxc_jpeg_set_last_buffer()
1336 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, next_dst_buf); in mxc_jpeg_set_last_buffer()
1342 struct device *dev = ctx->mxc_jpeg->dev; in mxc_jpeg_source_change()
1345 if (!jpeg_src_buf->fmt) in mxc_jpeg_source_change()
1349 if (mxc_jpeg_compare_format(q_data_cap->fmt, jpeg_src_buf->fmt)) in mxc_jpeg_source_change()
1350 jpeg_src_buf->fmt = q_data_cap->fmt; in mxc_jpeg_source_change()
1351 if (ctx->need_initial_source_change_evt || in mxc_jpeg_source_change()
1352 q_data_cap->fmt != jpeg_src_buf->fmt || in mxc_jpeg_source_change()
1353 q_data_cap->w != jpeg_src_buf->w || in mxc_jpeg_source_change()
1354 q_data_cap->h != jpeg_src_buf->h) { in mxc_jpeg_source_change()
1355 dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n", in mxc_jpeg_source_change()
1356 q_data_cap->w, q_data_cap->h, in mxc_jpeg_source_change()
1357 jpeg_src_buf->w, jpeg_src_buf->h, in mxc_jpeg_source_change()
1358 (jpeg_src_buf->fmt->fourcc & 0xff), in mxc_jpeg_source_change()
1359 (jpeg_src_buf->fmt->fourcc >> 8) & 0xff, in mxc_jpeg_source_change()
1360 (jpeg_src_buf->fmt->fourcc >> 16) & 0xff, in mxc_jpeg_source_change()
1361 (jpeg_src_buf->fmt->fourcc >> 24) & 0xff); in mxc_jpeg_source_change()
1364 * set-up the capture queue with the pixelformat and resolution in mxc_jpeg_source_change()
1367 q_data_cap->w = jpeg_src_buf->w; in mxc_jpeg_source_change()
1368 q_data_cap->h = jpeg_src_buf->h; in mxc_jpeg_source_change()
1369 q_data_cap->fmt = jpeg_src_buf->fmt; in mxc_jpeg_source_change()
1370 q_data_cap->w_adjusted = q_data_cap->w; in mxc_jpeg_source_change()
1371 q_data_cap->h_adjusted = q_data_cap->h; in mxc_jpeg_source_change()
1372 q_data_cap->crop.left = 0; in mxc_jpeg_source_change()
1373 q_data_cap->crop.top = 0; in mxc_jpeg_source_change()
1374 q_data_cap->crop.width = jpeg_src_buf->w; in mxc_jpeg_source_change()
1375 q_data_cap->crop.height = jpeg_src_buf->h; in mxc_jpeg_source_change()
1376 q_data_cap->bytesperline[0] = 0; in mxc_jpeg_source_change()
1377 q_data_cap->bytesperline[1] = 0; in mxc_jpeg_source_change()
1383 v4l_bound_align_image(&q_data_cap->w_adjusted, in mxc_jpeg_source_change()
1384 q_data_cap->w_adjusted, /* adjust up */ in mxc_jpeg_source_change()
1386 q_data_cap->fmt->h_align, in mxc_jpeg_source_change()
1387 &q_data_cap->h_adjusted, in mxc_jpeg_source_change()
1388 q_data_cap->h_adjusted, /* adjust up */ in mxc_jpeg_source_change()
1390 q_data_cap->fmt->v_align, in mxc_jpeg_source_change()
1394 mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision); in mxc_jpeg_source_change()
1397 ctx->source_change = 1; in mxc_jpeg_source_change()
1398 ctx->need_initial_source_change_evt = false; in mxc_jpeg_source_change()
1399 if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) in mxc_jpeg_source_change()
1403 return ctx->source_change ? true : false; in mxc_jpeg_source_change()
1410 return ctx->source_change ? 0 : 1; in mxc_jpeg_job_ready()
1417 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_device_run_timeout()
1420 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run_timeout()
1421 if (ctx->mxc_jpeg->slot_data.used) { in mxc_jpeg_device_run_timeout()
1422 dev_warn(jpeg->dev, "%s timeout, cancel it\n", in mxc_jpeg_device_run_timeout()
1423 ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode"); in mxc_jpeg_device_run_timeout()
1425 v4l2_m2m_job_finish(ctx->mxc_jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_device_run_timeout()
1427 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run_timeout()
1433 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_device_run()
1434 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_device_run()
1435 struct device *dev = jpeg->dev; in mxc_jpeg_device_run()
1441 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1442 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1443 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1455 src_buf->sequence = q_data_out->sequence++; in mxc_jpeg_device_run()
1456 dst_buf->sequence = q_data_cap->sequence++; in mxc_jpeg_device_run()
1460 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf); in mxc_jpeg_device_run()
1461 if (q_data_cap->fmt->mem_planes != dst_buf->vb2_buf.num_planes) { in mxc_jpeg_device_run()
1463 q_data_cap->fmt->name, q_data_cap->fmt->mem_planes, in mxc_jpeg_device_run()
1464 dst_buf->vb2_buf.num_planes); in mxc_jpeg_device_run()
1465 jpeg_src_buf->jpeg_parse_error = true; in mxc_jpeg_device_run()
1467 if (jpeg_src_buf->jpeg_parse_error) { in mxc_jpeg_device_run()
1469 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1470 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1473 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1474 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1478 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) { in mxc_jpeg_device_run()
1479 if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) { in mxc_jpeg_device_run()
1480 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1481 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1489 ctx->slot = mxc_get_free_slot(&jpeg->slot_data); in mxc_jpeg_device_run()
1490 if (ctx->slot < 0) { in mxc_jpeg_device_run()
1499 mxc_jpeg_enable_slot(reg, ctx->slot); in mxc_jpeg_device_run()
1500 mxc_jpeg_enable_irq(reg, ctx->slot); in mxc_jpeg_device_run()
1502 if (jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_device_run()
1503 dev_dbg(dev, "Encoding on slot %d\n", ctx->slot); in mxc_jpeg_device_run()
1504 ctx->enc_state = MXC_JPEG_ENC_CONF; in mxc_jpeg_device_run()
1505 mxc_jpeg_config_enc_desc(&dst_buf->vb2_buf, ctx, in mxc_jpeg_device_run()
1506 &src_buf->vb2_buf, &dst_buf->vb2_buf); in mxc_jpeg_device_run()
1509 mxc_jpeg_is_extended_sequential(q_data_out->fmt)); in mxc_jpeg_device_run()
1511 dev_dbg(dev, "Decoding on slot %d\n", ctx->slot); in mxc_jpeg_device_run()
1512 print_mxc_buf(jpeg, &src_buf->vb2_buf, 0); in mxc_jpeg_device_run()
1513 mxc_jpeg_config_dec_desc(&dst_buf->vb2_buf, ctx, in mxc_jpeg_device_run()
1514 &src_buf->vb2_buf, &dst_buf->vb2_buf); in mxc_jpeg_device_run()
1517 schedule_delayed_work(&ctx->task_timer, msecs_to_jiffies(hw_timeout)); in mxc_jpeg_device_run()
1519 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1525 struct v4l2_fh *fh = file->private_data; in mxc_jpeg_decoder_cmd()
1534 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx))) in mxc_jpeg_decoder_cmd()
1537 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_decoder_cmd()
1539 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_decoder_cmd()
1543 if (cmd->cmd == V4L2_DEC_CMD_STOP && in mxc_jpeg_decoder_cmd()
1544 v4l2_m2m_has_stopped(fh->m2m_ctx)) { in mxc_jpeg_decoder_cmd()
1546 ctx->header_parsed = false; in mxc_jpeg_decoder_cmd()
1549 if (cmd->cmd == V4L2_DEC_CMD_START && in mxc_jpeg_decoder_cmd()
1550 v4l2_m2m_has_stopped(fh->m2m_ctx)) in mxc_jpeg_decoder_cmd()
1551 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); in mxc_jpeg_decoder_cmd()
1558 struct v4l2_fh *fh = file->private_data; in mxc_jpeg_encoder_cmd()
1567 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) || in mxc_jpeg_encoder_cmd()
1568 !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx))) in mxc_jpeg_encoder_cmd()
1571 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_encoder_cmd()
1573 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_encoder_cmd()
1577 if (cmd->cmd == V4L2_ENC_CMD_STOP && in mxc_jpeg_encoder_cmd()
1578 v4l2_m2m_has_stopped(fh->m2m_ctx)) in mxc_jpeg_encoder_cmd()
1581 if (cmd->cmd == V4L2_ENC_CMD_START && in mxc_jpeg_encoder_cmd()
1582 v4l2_m2m_has_stopped(fh->m2m_ctx)) in mxc_jpeg_encoder_cmd()
1583 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); in mxc_jpeg_encoder_cmd()
1598 q_data = mxc_jpeg_get_q_data(ctx, q->type); in mxc_jpeg_queue_setup()
1600 return -EINVAL; in mxc_jpeg_queue_setup()
1602 /* Handle CREATE_BUFS situation - *nplanes != 0 */ in mxc_jpeg_queue_setup()
1604 if (*nplanes != q_data->fmt->mem_planes) in mxc_jpeg_queue_setup()
1605 return -EINVAL; in mxc_jpeg_queue_setup()
1608 return -EINVAL; in mxc_jpeg_queue_setup()
1614 *nplanes = q_data->fmt->mem_planes; in mxc_jpeg_queue_setup()
1618 if (V4L2_TYPE_IS_OUTPUT(q->type)) in mxc_jpeg_queue_setup()
1619 ctx->need_initial_source_change_evt = true; in mxc_jpeg_queue_setup()
1627 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type); in mxc_jpeg_start_streaming()
1630 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); in mxc_jpeg_start_streaming()
1632 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type)) in mxc_jpeg_start_streaming()
1633 ctx->source_change = 0; in mxc_jpeg_start_streaming()
1634 dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx); in mxc_jpeg_start_streaming()
1635 q_data->sequence = 0; in mxc_jpeg_start_streaming()
1637 if (V4L2_TYPE_IS_CAPTURE(q->type)) in mxc_jpeg_start_streaming()
1638 ctx->need_initial_source_change_evt = false; in mxc_jpeg_start_streaming()
1640 ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev); in mxc_jpeg_start_streaming()
1642 dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n"); in mxc_jpeg_start_streaming()
1654 dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming ctx=%p", ctx); in mxc_jpeg_stop_streaming()
1658 if (V4L2_TYPE_IS_OUTPUT(q->type)) in mxc_jpeg_stop_streaming()
1659 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_stop_streaming()
1661 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_stop_streaming()
1667 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); in mxc_jpeg_stop_streaming()
1671 if (V4L2_TYPE_IS_CAPTURE(q->type) && ctx->source_change && ctx->fh.m2m_ctx->last_src_buf) in mxc_jpeg_stop_streaming()
1672 ctx->fh.m2m_ctx->is_draining = true; in mxc_jpeg_stop_streaming()
1674 if (V4L2_TYPE_IS_OUTPUT(q->type) && in mxc_jpeg_stop_streaming()
1675 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) { in mxc_jpeg_stop_streaming()
1677 ctx->header_parsed = false; in mxc_jpeg_stop_streaming()
1680 pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); in mxc_jpeg_stop_streaming()
1694 for (i = 0; i < sof->components_no; i++) in mxc_jpeg_valid_comp_id()
1695 if (sof->comp[i].id > MXC_JPEG_MAX_COMPONENTS) { in mxc_jpeg_valid_comp_id()
1698 i, sof->comp[i].id); in mxc_jpeg_valid_comp_id()
1702 for (i = 0; i < sof->components_no; i++) { in mxc_jpeg_valid_comp_id()
1705 sof->comp[i].id = i + 1; in mxc_jpeg_valid_comp_id()
1706 sos->comp[i].id = i + 1; in mxc_jpeg_valid_comp_id()
1715 if (fmt->subsampling != header->frame.subsampling || in mxc_jpeg_match_image_format()
1716 fmt->nc != header->frame.num_components || in mxc_jpeg_match_image_format()
1717 fmt->precision != header->frame.precision) in mxc_jpeg_match_image_format()
1723 * ITU-T T.872 chapter 6.5.3 APP14 marker segment for colour encoding in mxc_jpeg_match_image_format()
1725 if (header->frame.subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) { in mxc_jpeg_match_image_format()
1726 u8 is_rgb = header->app14_tf == V4L2_JPEG_APP14_TF_CMYK_RGB ? 1 : 0; in mxc_jpeg_match_image_format()
1728 if (is_rgb != fmt->is_rgb) in mxc_jpeg_match_image_format()
1749 header->frame.num_components, in mxc_jpeg_get_image_format()
1750 header->frame.subsampling, in mxc_jpeg_get_image_format()
1751 header->frame.precision); in mxc_jpeg_get_image_format()
1762 bytesperline[0] = q->bytesperline[0]; in mxc_jpeg_bytesperline()
1763 bytesperline[1] = q->bytesperline[0]; /*imx-jpeg only support the same line pitch*/ in mxc_jpeg_bytesperline()
1769 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) { in mxc_jpeg_bytesperline()
1771 q->bytesperline[0] = 0; in mxc_jpeg_bytesperline()
1772 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1773 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) { in mxc_jpeg_bytesperline()
1778 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8); in mxc_jpeg_bytesperline()
1779 q->bytesperline[1] = q->bytesperline[0]; in mxc_jpeg_bytesperline()
1780 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) { in mxc_jpeg_bytesperline()
1781 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * 2; in mxc_jpeg_bytesperline()
1782 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1783 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) { in mxc_jpeg_bytesperline()
1784 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * q->fmt->nc; in mxc_jpeg_bytesperline()
1785 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1788 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8); in mxc_jpeg_bytesperline()
1789 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1792 if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) { in mxc_jpeg_bytesperline()
1793 q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]); in mxc_jpeg_bytesperline()
1794 if (q->fmt->mem_planes > 1) in mxc_jpeg_bytesperline()
1795 q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]); in mxc_jpeg_bytesperline()
1801 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) { in mxc_jpeg_sizeimage()
1803 if (!q->sizeimage[0]) in mxc_jpeg_sizeimage()
1804 q->sizeimage[0] = 6 * q->w * q->h; in mxc_jpeg_sizeimage()
1805 q->sizeimage[1] = 0; in mxc_jpeg_sizeimage()
1807 if (q->sizeimage[0] > MXC_JPEG_MAX_SIZEIMAGE) in mxc_jpeg_sizeimage()
1808 q->sizeimage[0] = MXC_JPEG_MAX_SIZEIMAGE; in mxc_jpeg_sizeimage()
1811 q->sizeimage[0] = ALIGN(q->sizeimage[0], 1024); in mxc_jpeg_sizeimage()
1813 q->sizeimage[0] = q->bytesperline[0] * q->h_adjusted; in mxc_jpeg_sizeimage()
1814 q->sizeimage[1] = 0; in mxc_jpeg_sizeimage()
1815 if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) in mxc_jpeg_sizeimage()
1816 q->sizeimage[1] = q->sizeimage[0] / 2; in mxc_jpeg_sizeimage()
1822 struct device *dev = ctx->mxc_jpeg->dev; in mxc_jpeg_parse()
1842 jpeg_src_buf->dht_needed = (header.num_dht == 0); in mxc_jpeg_parse()
1846 q_data_out->w = header.frame.width; in mxc_jpeg_parse()
1847 q_data_out->h = header.frame.height; in mxc_jpeg_parse()
1852 return -EINVAL; in mxc_jpeg_parse()
1858 return -EINVAL; in mxc_jpeg_parse()
1863 return -EINVAL; in mxc_jpeg_parse()
1869 dev_warn(dev, "JPEG component ids should be 0-3 or 1-4"); in mxc_jpeg_parse()
1872 if (q_data_cap->fmt && mxc_jpeg_match_image_format(q_data_cap->fmt, &header)) in mxc_jpeg_parse()
1873 fourcc = q_data_cap->fmt->fourcc; in mxc_jpeg_parse()
1877 return -EINVAL; in mxc_jpeg_parse()
1879 jpeg_src_buf->fmt = mxc_jpeg_find_format(fourcc); in mxc_jpeg_parse()
1880 jpeg_src_buf->w = header.frame.width; in mxc_jpeg_parse()
1881 jpeg_src_buf->h = header.frame.height; in mxc_jpeg_parse()
1882 ctx->header_parsed = true; in mxc_jpeg_parse()
1884 if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx)) in mxc_jpeg_parse()
1894 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in mxc_jpeg_buf_queue()
1897 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && in mxc_jpeg_buf_queue()
1898 vb2_is_streaming(vb->vb2_queue) && in mxc_jpeg_buf_queue()
1899 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { in mxc_jpeg_buf_queue()
1902 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); in mxc_jpeg_buf_queue()
1903 vbuf->field = V4L2_FIELD_NONE; in mxc_jpeg_buf_queue()
1904 vbuf->sequence = q_data->sequence++; in mxc_jpeg_buf_queue()
1905 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); in mxc_jpeg_buf_queue()
1907 ctx->header_parsed = false; in mxc_jpeg_buf_queue()
1911 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in mxc_jpeg_buf_queue()
1915 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) in mxc_jpeg_buf_queue()
1919 jpeg_src_buf->jpeg_parse_error = false; in mxc_jpeg_buf_queue()
1922 jpeg_src_buf->jpeg_parse_error = true; in mxc_jpeg_buf_queue()
1925 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in mxc_jpeg_buf_queue()
1932 vbuf->field = V4L2_FIELD_NONE; in mxc_jpeg_buf_out_validate()
1940 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in mxc_jpeg_buf_prepare()
1942 struct device *dev = ctx->mxc_jpeg->dev; in mxc_jpeg_buf_prepare()
1946 vbuf->field = V4L2_FIELD_NONE; in mxc_jpeg_buf_prepare()
1948 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); in mxc_jpeg_buf_prepare()
1950 return -EINVAL; in mxc_jpeg_buf_prepare()
1951 for (i = 0; i < q_data->fmt->mem_planes; i++) { in mxc_jpeg_buf_prepare()
1953 if (!ctx->source_change && vb2_plane_size(vb, i) < sizeimage) { in mxc_jpeg_buf_prepare()
1956 return -EINVAL; in mxc_jpeg_buf_prepare()
1959 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) { in mxc_jpeg_buf_prepare()
1983 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; in mxc_jpeg_queue_init()
1984 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; in mxc_jpeg_queue_init()
1985 src_vq->drv_priv = ctx; in mxc_jpeg_queue_init()
1986 src_vq->buf_struct_size = sizeof(struct mxc_jpeg_src_buf); in mxc_jpeg_queue_init()
1987 src_vq->ops = &mxc_jpeg_qops; in mxc_jpeg_queue_init()
1988 src_vq->mem_ops = &vb2_dma_contig_memops; in mxc_jpeg_queue_init()
1989 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in mxc_jpeg_queue_init()
1990 src_vq->lock = &ctx->mxc_jpeg->lock; in mxc_jpeg_queue_init()
1991 src_vq->dev = ctx->mxc_jpeg->dev; in mxc_jpeg_queue_init()
1997 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in mxc_jpeg_queue_init()
1998 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; in mxc_jpeg_queue_init()
1999 dst_vq->drv_priv = ctx; in mxc_jpeg_queue_init()
2000 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in mxc_jpeg_queue_init()
2001 dst_vq->ops = &mxc_jpeg_qops; in mxc_jpeg_queue_init()
2002 dst_vq->mem_ops = &vb2_dma_contig_memops; in mxc_jpeg_queue_init()
2003 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in mxc_jpeg_queue_init()
2004 dst_vq->lock = &ctx->mxc_jpeg->lock; in mxc_jpeg_queue_init()
2005 dst_vq->dev = ctx->mxc_jpeg->dev; in mxc_jpeg_queue_init()
2013 struct mxc_jpeg_q_data *out_q = &ctx->out_q; in mxc_jpeg_set_default_params()
2014 struct mxc_jpeg_q_data *cap_q = &ctx->cap_q; in mxc_jpeg_set_default_params()
2018 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_set_default_params()
2019 out_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT); in mxc_jpeg_set_default_params()
2020 cap_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG); in mxc_jpeg_set_default_params()
2022 out_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG); in mxc_jpeg_set_default_params()
2023 cap_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT); in mxc_jpeg_set_default_params()
2027 q[i]->w = MXC_JPEG_DEFAULT_WIDTH; in mxc_jpeg_set_default_params()
2028 q[i]->h = MXC_JPEG_DEFAULT_HEIGHT; in mxc_jpeg_set_default_params()
2029 q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH; in mxc_jpeg_set_default_params()
2030 q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT; in mxc_jpeg_set_default_params()
2031 q[i]->crop.left = 0; in mxc_jpeg_set_default_params()
2032 q[i]->crop.top = 0; in mxc_jpeg_set_default_params()
2033 q[i]->crop.width = MXC_JPEG_DEFAULT_WIDTH; in mxc_jpeg_set_default_params()
2034 q[i]->crop.height = MXC_JPEG_DEFAULT_HEIGHT; in mxc_jpeg_set_default_params()
2035 mxc_jpeg_bytesperline(q[i], q[i]->fmt->precision); in mxc_jpeg_set_default_params()
2043 container_of(ctrl->handler, struct mxc_jpeg_ctx, ctrl_handler); in mxc_jpeg_s_ctrl()
2045 switch (ctrl->id) { in mxc_jpeg_s_ctrl()
2047 ctx->jpeg_quality = ctrl->val; in mxc_jpeg_s_ctrl()
2050 dev_err(ctx->mxc_jpeg->dev, "Invalid control, id = %d, val = %d\n", in mxc_jpeg_s_ctrl()
2051 ctrl->id, ctrl->val); in mxc_jpeg_s_ctrl()
2052 return -EINVAL; in mxc_jpeg_s_ctrl()
2064 v4l2_ctrl_new_std(&ctx->ctrl_handler, &mxc_jpeg_ctrl_ops, in mxc_jpeg_encode_ctrls()
2072 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 2); in mxc_jpeg_ctrls_setup()
2074 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) in mxc_jpeg_ctrls_setup()
2077 if (ctx->ctrl_handler.error) { in mxc_jpeg_ctrls_setup()
2078 err = ctx->ctrl_handler.error; in mxc_jpeg_ctrls_setup()
2080 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in mxc_jpeg_ctrls_setup()
2084 err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler); in mxc_jpeg_ctrls_setup()
2086 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in mxc_jpeg_ctrls_setup()
2094 struct device *dev = mxc_jpeg->dev; in mxc_jpeg_open()
2100 return -ENOMEM; in mxc_jpeg_open()
2102 if (mutex_lock_interruptible(&mxc_jpeg->lock)) { in mxc_jpeg_open()
2103 ret = -ERESTARTSYS; in mxc_jpeg_open()
2107 v4l2_fh_init(&ctx->fh, mxc_vfd); in mxc_jpeg_open()
2108 file->private_data = &ctx->fh; in mxc_jpeg_open()
2109 v4l2_fh_add(&ctx->fh); in mxc_jpeg_open()
2111 ctx->mxc_jpeg = mxc_jpeg; in mxc_jpeg_open()
2113 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(mxc_jpeg->m2m_dev, ctx, in mxc_jpeg_open()
2116 if (IS_ERR(ctx->fh.m2m_ctx)) { in mxc_jpeg_open()
2117 ret = PTR_ERR(ctx->fh.m2m_ctx); in mxc_jpeg_open()
2123 dev_err(ctx->mxc_jpeg->dev, "failed to setup mxc jpeg controls\n"); in mxc_jpeg_open()
2126 ctx->fh.ctrl_handler = &ctx->ctrl_handler; in mxc_jpeg_open()
2128 ctx->slot = -1; /* slot not allocated yet */ in mxc_jpeg_open()
2129 INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout); in mxc_jpeg_open()
2131 if (mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_open()
2135 mutex_unlock(&mxc_jpeg->lock); in mxc_jpeg_open()
2140 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in mxc_jpeg_open()
2142 v4l2_fh_del(&ctx->fh); in mxc_jpeg_open()
2143 v4l2_fh_exit(&ctx->fh); in mxc_jpeg_open()
2144 mutex_unlock(&mxc_jpeg->lock); in mxc_jpeg_open()
2153 strscpy(cap->driver, MXC_JPEG_NAME " codec", sizeof(cap->driver)); in mxc_jpeg_querycap()
2154 strscpy(cap->card, MXC_JPEG_NAME " codec", sizeof(cap->card)); in mxc_jpeg_querycap()
2155 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; in mxc_jpeg_querycap()
2156 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; in mxc_jpeg_querycap()
2165 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type); in mxc_jpeg_enum_fmt_vid_cap()
2167 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_enum_fmt_vid_cap()
2170 } else if (!ctx->header_parsed) { in mxc_jpeg_enum_fmt_vid_cap()
2179 int ret = -EINVAL; in mxc_jpeg_enum_fmt_vid_cap()
2182 switch (f->index) { in mxc_jpeg_enum_fmt_vid_cap()
2184 f->pixelformat = q_data->fmt->fourcc; in mxc_jpeg_enum_fmt_vid_cap()
2188 sibling = mxc_jpeg_get_sibling_format(q_data->fmt); in mxc_jpeg_enum_fmt_vid_cap()
2190 f->pixelformat = sibling->fourcc; in mxc_jpeg_enum_fmt_vid_cap()
2205 u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC : in mxc_jpeg_enum_fmt_vid_out()
2212 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_enum_fmt_vid_out()
2213 f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION; in mxc_jpeg_enum_fmt_vid_out()
2219 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_get_fmt_type()
2227 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_get_default_fourcc()
2238 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) in mxc_jpeg_try_fourcc()
2240 if (!ctx->header_parsed) in mxc_jpeg_try_fourcc()
2243 q_data_cap = &ctx->cap_q; in mxc_jpeg_try_fourcc()
2244 if (q_data_cap->fmt->fourcc == fourcc) in mxc_jpeg_try_fourcc()
2247 sibling = mxc_jpeg_get_sibling_format(q_data_cap->fmt); in mxc_jpeg_try_fourcc()
2248 if (sibling && sibling->fourcc == fourcc) in mxc_jpeg_try_fourcc()
2249 return sibling->fourcc; in mxc_jpeg_try_fourcc()
2251 return q_data_cap->fmt->fourcc; in mxc_jpeg_try_fourcc()
2258 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in mxc_jpeg_try_fmt()
2260 u32 fourcc = f->fmt.pix_mp.pixelformat; in mxc_jpeg_try_fmt()
2261 u32 w = (pix_mp->width < MXC_JPEG_MAX_WIDTH) ? in mxc_jpeg_try_fmt()
2262 pix_mp->width : MXC_JPEG_MAX_WIDTH; in mxc_jpeg_try_fmt()
2263 u32 h = (pix_mp->height < MXC_JPEG_MAX_HEIGHT) ? in mxc_jpeg_try_fmt()
2264 pix_mp->height : MXC_JPEG_MAX_HEIGHT; in mxc_jpeg_try_fmt()
2268 if (!fmt || fmt->flags != mxc_jpeg_get_fmt_type(ctx, f->type)) { in mxc_jpeg_try_fmt()
2269 dev_warn(ctx->mxc_jpeg->dev, "Format not supported: %c%c%c%c, use the default.\n", in mxc_jpeg_try_fmt()
2274 fourcc = mxc_jpeg_get_default_fourcc(ctx, f->type); in mxc_jpeg_try_fmt()
2277 return -EINVAL; in mxc_jpeg_try_fmt()
2278 f->fmt.pix_mp.pixelformat = fourcc; in mxc_jpeg_try_fmt()
2280 q_data->fmt = fmt; in mxc_jpeg_try_fmt()
2282 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); in mxc_jpeg_try_fmt()
2283 pix_mp->field = V4L2_FIELD_NONE; in mxc_jpeg_try_fmt()
2284 pix_mp->num_planes = fmt->mem_planes; in mxc_jpeg_try_fmt()
2285 pix_mp->pixelformat = fmt->fourcc; in mxc_jpeg_try_fmt()
2287 q_data->w = w; in mxc_jpeg_try_fmt()
2288 q_data->h = h; in mxc_jpeg_try_fmt()
2289 q_data->w_adjusted = w; in mxc_jpeg_try_fmt()
2290 q_data->h_adjusted = h; in mxc_jpeg_try_fmt()
2291 v4l_bound_align_image(&q_data->w_adjusted, in mxc_jpeg_try_fmt()
2294 fmt->h_align, in mxc_jpeg_try_fmt()
2295 &q_data->h_adjusted, in mxc_jpeg_try_fmt()
2298 fmt->v_align, in mxc_jpeg_try_fmt()
2300 for (i = 0; i < pix_mp->num_planes; i++) { in mxc_jpeg_try_fmt()
2301 pfmt = &pix_mp->plane_fmt[i]; in mxc_jpeg_try_fmt()
2302 q_data->bytesperline[i] = pfmt->bytesperline; in mxc_jpeg_try_fmt()
2303 q_data->sizeimage[i] = pfmt->sizeimage; in mxc_jpeg_try_fmt()
2307 mxc_jpeg_bytesperline(q_data, fmt->precision); in mxc_jpeg_try_fmt()
2311 for (i = 0; i < pix_mp->num_planes; i++) { in mxc_jpeg_try_fmt()
2312 pfmt = &pix_mp->plane_fmt[i]; in mxc_jpeg_try_fmt()
2313 memset(pfmt->reserved, 0, sizeof(pfmt->reserved)); in mxc_jpeg_try_fmt()
2314 pfmt->bytesperline = q_data->bytesperline[i]; in mxc_jpeg_try_fmt()
2315 pfmt->sizeimage = mxc_jpeg_get_plane_size(q_data, i); in mxc_jpeg_try_fmt()
2319 pix_mp->colorspace = V4L2_COLORSPACE_SRGB; in mxc_jpeg_try_fmt()
2320 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601; in mxc_jpeg_try_fmt()
2321 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB; in mxc_jpeg_try_fmt()
2324 * but since inside JPEG the YUV quantization is full-range, in mxc_jpeg_try_fmt()
2325 * this driver will always use full-range for the raw frames, too in mxc_jpeg_try_fmt()
2327 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mxc_jpeg_try_fmt()
2329 if (fmt->flags == MXC_JPEG_FMT_TYPE_RAW) { in mxc_jpeg_try_fmt()
2330 q_data->crop.left = 0; in mxc_jpeg_try_fmt()
2331 q_data->crop.top = 0; in mxc_jpeg_try_fmt()
2332 q_data->crop.width = q_data->w; in mxc_jpeg_try_fmt()
2333 q_data->crop.height = q_data->h; in mxc_jpeg_try_fmt()
2336 pix_mp->width = q_data->w_adjusted; in mxc_jpeg_try_fmt()
2337 pix_mp->height = q_data->h_adjusted; in mxc_jpeg_try_fmt()
2346 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_try_fmt_vid_cap()
2347 struct device *dev = jpeg->dev; in mxc_jpeg_try_fmt_vid_cap()
2350 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { in mxc_jpeg_try_fmt_vid_cap()
2351 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type); in mxc_jpeg_try_fmt_vid_cap()
2352 return -EINVAL; in mxc_jpeg_try_fmt_vid_cap()
2355 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(f->type)) in mxc_jpeg_try_fmt_vid_cap()
2356 f->fmt.pix_mp.pixelformat = mxc_jpeg_try_fourcc(ctx, f->fmt.pix_mp.pixelformat); in mxc_jpeg_try_fmt_vid_cap()
2365 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_try_fmt_vid_out()
2366 struct device *dev = jpeg->dev; in mxc_jpeg_try_fmt_vid_out()
2369 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { in mxc_jpeg_try_fmt_vid_out()
2370 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type); in mxc_jpeg_try_fmt_vid_out()
2371 return -EINVAL; in mxc_jpeg_try_fmt_vid_out()
2379 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in mxc_jpeg_s_parsed_fmt()
2382 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE || !V4L2_TYPE_IS_CAPTURE(f->type)) in mxc_jpeg_s_parsed_fmt()
2384 if (!ctx->header_parsed) in mxc_jpeg_s_parsed_fmt()
2387 q_data_cap = mxc_jpeg_get_q_data(ctx, f->type); in mxc_jpeg_s_parsed_fmt()
2388 pix_mp->pixelformat = mxc_jpeg_try_fourcc(ctx, pix_mp->pixelformat); in mxc_jpeg_s_parsed_fmt()
2389 pix_mp->width = q_data_cap->w; in mxc_jpeg_s_parsed_fmt()
2390 pix_mp->height = q_data_cap->h; in mxc_jpeg_s_parsed_fmt()
2397 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_s_fmt()
2399 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in mxc_jpeg_s_fmt()
2401 return -EINVAL; in mxc_jpeg_s_fmt()
2404 v4l2_err(&jpeg->v4l2_dev, "queue busy\n"); in mxc_jpeg_s_fmt()
2405 return -EBUSY; in mxc_jpeg_s_fmt()
2410 return mxc_jpeg_try_fmt(f, ctx, mxc_jpeg_get_q_data(ctx, f->type)); in mxc_jpeg_s_fmt()
2433 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) in mxc_jpeg_s_fmt_vid_out()
2436 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, cap_type); in mxc_jpeg_s_fmt_vid_out()
2438 return -EINVAL; in mxc_jpeg_s_fmt_vid_out()
2444 if (q_data_cap->w == f->fmt.pix_mp.width && q_data_cap->h == f->fmt.pix_mp.height) in mxc_jpeg_s_fmt_vid_out()
2448 fc.fmt.pix_mp.pixelformat = q_data_cap->fmt->fourcc; in mxc_jpeg_s_fmt_vid_out()
2449 fc.fmt.pix_mp.width = f->fmt.pix_mp.width; in mxc_jpeg_s_fmt_vid_out()
2450 fc.fmt.pix_mp.height = f->fmt.pix_mp.height; in mxc_jpeg_s_fmt_vid_out()
2459 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_g_fmt_vid()
2460 struct device *dev = jpeg->dev; in mxc_jpeg_g_fmt_vid()
2461 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in mxc_jpeg_g_fmt_vid()
2462 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type); in mxc_jpeg_g_fmt_vid()
2465 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { in mxc_jpeg_g_fmt_vid()
2466 dev_err(dev, "G_FMT with Invalid type: %d\n", f->type); in mxc_jpeg_g_fmt_vid()
2467 return -EINVAL; in mxc_jpeg_g_fmt_vid()
2470 pix_mp->pixelformat = q_data->fmt->fourcc; in mxc_jpeg_g_fmt_vid()
2471 pix_mp->width = q_data->w; in mxc_jpeg_g_fmt_vid()
2472 pix_mp->height = q_data->h; in mxc_jpeg_g_fmt_vid()
2473 pix_mp->field = V4L2_FIELD_NONE; in mxc_jpeg_g_fmt_vid()
2474 if (q_data->fmt->flags == MXC_JPEG_FMT_TYPE_RAW) { in mxc_jpeg_g_fmt_vid()
2475 pix_mp->width = q_data->w_adjusted; in mxc_jpeg_g_fmt_vid()
2476 pix_mp->height = q_data->h_adjusted; in mxc_jpeg_g_fmt_vid()
2480 pix_mp->colorspace = V4L2_COLORSPACE_SRGB; in mxc_jpeg_g_fmt_vid()
2481 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601; in mxc_jpeg_g_fmt_vid()
2482 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB; in mxc_jpeg_g_fmt_vid()
2483 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mxc_jpeg_g_fmt_vid()
2485 pix_mp->num_planes = q_data->fmt->mem_planes; in mxc_jpeg_g_fmt_vid()
2486 for (i = 0; i < pix_mp->num_planes; i++) { in mxc_jpeg_g_fmt_vid()
2487 pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i]; in mxc_jpeg_g_fmt_vid()
2488 pix_mp->plane_fmt[i].sizeimage = mxc_jpeg_get_plane_size(q_data, i); in mxc_jpeg_g_fmt_vid()
2499 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in mxc_jpeg_dec_g_selection()
2500 return -EINVAL; in mxc_jpeg_dec_g_selection()
2502 q_data_cap = mxc_jpeg_get_q_data(ctx, s->type); in mxc_jpeg_dec_g_selection()
2504 switch (s->target) { in mxc_jpeg_dec_g_selection()
2507 s->r = q_data_cap->crop; in mxc_jpeg_dec_g_selection()
2511 s->r.left = 0; in mxc_jpeg_dec_g_selection()
2512 s->r.top = 0; in mxc_jpeg_dec_g_selection()
2513 s->r.width = q_data_cap->w_adjusted; in mxc_jpeg_dec_g_selection()
2514 s->r.height = q_data_cap->h_adjusted; in mxc_jpeg_dec_g_selection()
2517 return -EINVAL; in mxc_jpeg_dec_g_selection()
2528 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in mxc_jpeg_enc_g_selection()
2529 return -EINVAL; in mxc_jpeg_enc_g_selection()
2531 q_data_out = mxc_jpeg_get_q_data(ctx, s->type); in mxc_jpeg_enc_g_selection()
2533 switch (s->target) { in mxc_jpeg_enc_g_selection()
2536 s->r.left = 0; in mxc_jpeg_enc_g_selection()
2537 s->r.top = 0; in mxc_jpeg_enc_g_selection()
2538 s->r.width = q_data_out->w; in mxc_jpeg_enc_g_selection()
2539 s->r.height = q_data_out->h; in mxc_jpeg_enc_g_selection()
2542 s->r = q_data_out->crop; in mxc_jpeg_enc_g_selection()
2545 return -EINVAL; in mxc_jpeg_enc_g_selection()
2555 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_g_selection()
2566 if (ctx->mxc_jpeg->mode != MXC_JPEG_ENCODE) in mxc_jpeg_s_selection()
2567 return -ENOTTY; in mxc_jpeg_s_selection()
2569 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in mxc_jpeg_s_selection()
2570 return -EINVAL; in mxc_jpeg_s_selection()
2571 if (s->target != V4L2_SEL_TGT_CROP) in mxc_jpeg_s_selection()
2572 return -EINVAL; in mxc_jpeg_s_selection()
2574 q_data_out = mxc_jpeg_get_q_data(ctx, s->type); in mxc_jpeg_s_selection()
2575 if (s->r.left || s->r.top) in mxc_jpeg_s_selection()
2576 return -EINVAL; in mxc_jpeg_s_selection()
2577 if (s->r.width > q_data_out->w || s->r.height > q_data_out->h) in mxc_jpeg_s_selection()
2578 return -EINVAL; in mxc_jpeg_s_selection()
2580 q_data_out->crop.left = 0; in mxc_jpeg_s_selection()
2581 q_data_out->crop.top = 0; in mxc_jpeg_s_selection()
2582 q_data_out->crop.width = s->r.width; in mxc_jpeg_s_selection()
2583 q_data_out->crop.height = s->r.height; in mxc_jpeg_s_selection()
2591 switch (sub->type) { in mxc_jpeg_subscribe_event()
2599 return -EINVAL; in mxc_jpeg_subscribe_event()
2643 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data); in mxc_jpeg_release()
2644 struct device *dev = mxc_jpeg->dev; in mxc_jpeg_release()
2646 mutex_lock(&mxc_jpeg->lock); in mxc_jpeg_release()
2647 if (mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_release()
2649 ctx->slot); in mxc_jpeg_release()
2652 ctx->slot); in mxc_jpeg_release()
2653 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in mxc_jpeg_release()
2654 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in mxc_jpeg_release()
2655 v4l2_fh_del(&ctx->fh); in mxc_jpeg_release()
2656 v4l2_fh_exit(&ctx->fh); in mxc_jpeg_release()
2658 mutex_unlock(&mxc_jpeg->lock); in mxc_jpeg_release()
2681 for (i = 0; i < jpeg->num_domains; i++) { in mxc_jpeg_detach_pm_domains()
2682 if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i])) in mxc_jpeg_detach_pm_domains()
2683 device_link_del(jpeg->pd_link[i]); in mxc_jpeg_detach_pm_domains()
2684 if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i])) in mxc_jpeg_detach_pm_domains()
2685 dev_pm_domain_detach(jpeg->pd_dev[i], true); in mxc_jpeg_detach_pm_domains()
2686 jpeg->pd_dev[i] = NULL; in mxc_jpeg_detach_pm_domains()
2687 jpeg->pd_link[i] = NULL; in mxc_jpeg_detach_pm_domains()
2693 struct device *dev = jpeg->dev; in mxc_jpeg_attach_pm_domains()
2694 struct device_node *np = jpeg->pdev->dev.of_node; in mxc_jpeg_attach_pm_domains()
2698 jpeg->num_domains = of_count_phandle_with_args(np, "power-domains", in mxc_jpeg_attach_pm_domains()
2699 "#power-domain-cells"); in mxc_jpeg_attach_pm_domains()
2700 if (jpeg->num_domains < 0) { in mxc_jpeg_attach_pm_domains()
2702 return jpeg->num_domains; in mxc_jpeg_attach_pm_domains()
2704 if (jpeg->num_domains == 1) { in mxc_jpeg_attach_pm_domains()
2706 jpeg->num_domains = 0; in mxc_jpeg_attach_pm_domains()
2710 jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains, in mxc_jpeg_attach_pm_domains()
2711 sizeof(*jpeg->pd_dev), GFP_KERNEL); in mxc_jpeg_attach_pm_domains()
2712 if (!jpeg->pd_dev) in mxc_jpeg_attach_pm_domains()
2713 return -ENOMEM; in mxc_jpeg_attach_pm_domains()
2715 jpeg->pd_link = devm_kmalloc_array(dev, jpeg->num_domains, in mxc_jpeg_attach_pm_domains()
2716 sizeof(*jpeg->pd_link), GFP_KERNEL); in mxc_jpeg_attach_pm_domains()
2717 if (!jpeg->pd_link) in mxc_jpeg_attach_pm_domains()
2718 return -ENOMEM; in mxc_jpeg_attach_pm_domains()
2720 for (i = 0; i < jpeg->num_domains; i++) { in mxc_jpeg_attach_pm_domains()
2721 jpeg->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i); in mxc_jpeg_attach_pm_domains()
2722 if (IS_ERR(jpeg->pd_dev[i])) { in mxc_jpeg_attach_pm_domains()
2723 ret = PTR_ERR(jpeg->pd_dev[i]); in mxc_jpeg_attach_pm_domains()
2727 jpeg->pd_link[i] = device_link_add(dev, jpeg->pd_dev[i], in mxc_jpeg_attach_pm_domains()
2730 if (!jpeg->pd_link[i]) { in mxc_jpeg_attach_pm_domains()
2731 ret = -EINVAL; in mxc_jpeg_attach_pm_domains()
2745 struct device *dev = &pdev->dev; in mxc_jpeg_probe()
2751 of_id = of_match_node(mxc_jpeg_match, dev->of_node); in mxc_jpeg_probe()
2753 return -ENODEV; in mxc_jpeg_probe()
2754 mode = *(const int *)of_id->data; in mxc_jpeg_probe()
2758 return -ENOMEM; in mxc_jpeg_probe()
2760 mutex_init(&jpeg->lock); in mxc_jpeg_probe()
2761 spin_lock_init(&jpeg->hw_lock); in mxc_jpeg_probe()
2765 dev_err(&pdev->dev, "No suitable DMA available.\n"); in mxc_jpeg_probe()
2769 jpeg->base_reg = devm_platform_ioremap_resource(pdev, 0); in mxc_jpeg_probe()
2770 if (IS_ERR(jpeg->base_reg)) in mxc_jpeg_probe()
2771 return PTR_ERR(jpeg->base_reg); in mxc_jpeg_probe()
2773 ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot); in mxc_jpeg_probe()
2775 jpeg->slot_data.slot = 0; in mxc_jpeg_probe()
2776 dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); in mxc_jpeg_probe()
2782 ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, in mxc_jpeg_probe()
2783 0, pdev->name, jpeg); in mxc_jpeg_probe()
2785 dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", in mxc_jpeg_probe()
2790 jpeg->pdev = pdev; in mxc_jpeg_probe()
2791 jpeg->dev = dev; in mxc_jpeg_probe()
2792 jpeg->mode = mode; in mxc_jpeg_probe()
2795 ret = devm_clk_bulk_get_all(&pdev->dev, &jpeg->clks); in mxc_jpeg_probe()
2800 jpeg->num_clks = ret; in mxc_jpeg_probe()
2809 ret = v4l2_device_register(dev, &jpeg->v4l2_dev); in mxc_jpeg_probe()
2814 jpeg->m2m_dev = v4l2_m2m_init(&mxc_jpeg_m2m_ops); in mxc_jpeg_probe()
2815 if (IS_ERR(jpeg->m2m_dev)) { in mxc_jpeg_probe()
2817 ret = PTR_ERR(jpeg->m2m_dev); in mxc_jpeg_probe()
2821 jpeg->dec_vdev = video_device_alloc(); in mxc_jpeg_probe()
2822 if (!jpeg->dec_vdev) { in mxc_jpeg_probe()
2824 ret = -ENOMEM; in mxc_jpeg_probe()
2828 snprintf(jpeg->dec_vdev->name, in mxc_jpeg_probe()
2829 sizeof(jpeg->dec_vdev->name), in mxc_jpeg_probe()
2830 "%s-enc", MXC_JPEG_NAME); in mxc_jpeg_probe()
2832 snprintf(jpeg->dec_vdev->name, in mxc_jpeg_probe()
2833 sizeof(jpeg->dec_vdev->name), in mxc_jpeg_probe()
2834 "%s-dec", MXC_JPEG_NAME); in mxc_jpeg_probe()
2836 jpeg->dec_vdev->fops = &mxc_jpeg_fops; in mxc_jpeg_probe()
2837 jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops; in mxc_jpeg_probe()
2838 jpeg->dec_vdev->minor = -1; in mxc_jpeg_probe()
2839 jpeg->dec_vdev->release = video_device_release; in mxc_jpeg_probe()
2840 jpeg->dec_vdev->lock = &jpeg->lock; /* lock for ioctl serialization */ in mxc_jpeg_probe()
2841 jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev; in mxc_jpeg_probe()
2842 jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M; in mxc_jpeg_probe()
2843 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING | in mxc_jpeg_probe()
2846 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD); in mxc_jpeg_probe()
2847 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD); in mxc_jpeg_probe()
2849 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_ENCODER_CMD); in mxc_jpeg_probe()
2850 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_ENCODER_CMD); in mxc_jpeg_probe()
2852 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_VIDEO, -1); in mxc_jpeg_probe()
2857 video_set_drvdata(jpeg->dec_vdev, jpeg); in mxc_jpeg_probe()
2859 v4l2_info(&jpeg->v4l2_dev, in mxc_jpeg_probe()
2861 jpeg->dec_vdev->num, VIDEO_MAJOR, in mxc_jpeg_probe()
2862 jpeg->dec_vdev->minor); in mxc_jpeg_probe()
2864 v4l2_info(&jpeg->v4l2_dev, in mxc_jpeg_probe()
2866 jpeg->dec_vdev->num, VIDEO_MAJOR, in mxc_jpeg_probe()
2867 jpeg->dec_vdev->minor); in mxc_jpeg_probe()
2875 video_device_release(jpeg->dec_vdev); in mxc_jpeg_probe()
2878 v4l2_m2m_release(jpeg->m2m_dev); in mxc_jpeg_probe()
2881 v4l2_device_unregister(&jpeg->v4l2_dev); in mxc_jpeg_probe()
2897 ret = clk_bulk_prepare_enable(jpeg->num_clks, jpeg->clks); in mxc_jpeg_runtime_resume()
2910 clk_bulk_disable_unprepare(jpeg->num_clks, jpeg->clks); in mxc_jpeg_runtime_suspend()
2921 v4l2_m2m_suspend(jpeg->m2m_dev); in mxc_jpeg_suspend()
2934 v4l2_m2m_resume(jpeg->m2m_dev); in mxc_jpeg_resume()
2951 pm_runtime_disable(&pdev->dev); in mxc_jpeg_remove()
2952 video_unregister_device(jpeg->dec_vdev); in mxc_jpeg_remove()
2953 v4l2_m2m_release(jpeg->m2m_dev); in mxc_jpeg_remove()
2954 v4l2_device_unregister(&jpeg->v4l2_dev); in mxc_jpeg_remove()
2964 .name = "mxc-jpeg",