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",
567 /* common v4l buffer stuff -- must be first */
571 /* mxc-jpeg specific */
587 MODULE_PARM_DESC(debug, "Debug level (0-3)");
603 if (plane_no >= buf->num_planes) in mxc_jpeg_get_plane_dma_addr()
605 return vb2_dma_contig_plane_dma_addr(buf, plane_no) + buf->planes[plane_no].data_offset; in mxc_jpeg_get_plane_dma_addr()
610 if (plane_no >= buf->num_planes) in mxc_jpeg_get_plane_vaddr()
612 return vb2_plane_vaddr(buf, plane_no) + buf->planes[plane_no].data_offset; in mxc_jpeg_get_plane_vaddr()
617 if (plane_no >= buf->num_planes) in mxc_jpeg_get_plane_payload()
619 return vb2_get_plane_payload(buf, plane_no) - buf->planes[plane_no].data_offset; in mxc_jpeg_get_plane_payload()
633 for (plane_no = 0; plane_no < buf->num_planes; plane_no++) { in print_mxc_buf()
639 v4l2_dbg(3, debug, &jpeg->v4l2_dev, in print_mxc_buf()
659 /* index-th format of searched type found ? */ in enum_fmt()
660 if (num == f->index) in enum_fmt()
663 * just increment per-type index in enum_fmt()
671 return -EINVAL; in enum_fmt()
673 f->pixelformat = mxc_formats[i].fourcc; in enum_fmt()
685 if (fmt->fourcc == pixelformat) in mxc_jpeg_find_format()
723 return &ctx->out_q; in mxc_jpeg_get_q_data()
724 return &ctx->cap_q; in mxc_jpeg_get_q_data()
731 int img_fmt = desc->stm_ctrl & STM_CTRL_IMAGE_FORMAT_MASK; in mxc_jpeg_addrs()
732 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(raw_buf->vb2_queue); in mxc_jpeg_addrs()
735 q_data = mxc_jpeg_get_q_data(ctx, raw_buf->type); in mxc_jpeg_addrs()
736 desc->buf_base0 = mxc_jpeg_get_plane_dma_addr(raw_buf, 0); in mxc_jpeg_addrs()
737 desc->buf_base1 = 0; in mxc_jpeg_addrs()
739 if (raw_buf->num_planes == 2) in mxc_jpeg_addrs()
740 desc->buf_base1 = mxc_jpeg_get_plane_dma_addr(raw_buf, 1); in mxc_jpeg_addrs()
742 desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0]; in mxc_jpeg_addrs()
744 desc->stm_bufbase = mxc_jpeg_get_plane_dma_addr(jpeg_buf, 0) + offset; in mxc_jpeg_addrs()
749 if (!fmt || !(fmt->flags & MXC_JPEG_FMT_TYPE_RAW)) in mxc_jpeg_is_extended_sequential()
752 if (fmt->precision > 8) in mxc_jpeg_is_extended_sequential()
764 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event EOS reached"); in notify_eos()
765 v4l2_event_queue_fh(&ctx->fh, &ev); in notify_eos()
775 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event SRC_CH_RESOLUTION"); in notify_src_chg()
776 v4l2_event_queue_fh(&ctx->fh, &ev); in notify_src_chg()
781 if (!slot_data->used) in mxc_get_free_slot()
782 return slot_data->slot; in mxc_get_free_slot()
783 return -1; in mxc_get_free_slot()
789 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), in mxc_jpeg_free_slot_data()
790 jpeg->slot_data.desc, in mxc_jpeg_free_slot_data()
791 jpeg->slot_data.desc_handle); in mxc_jpeg_free_slot_data()
792 jpeg->slot_data.desc = NULL; in mxc_jpeg_free_slot_data()
793 jpeg->slot_data.desc_handle = 0; in mxc_jpeg_free_slot_data()
796 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), in mxc_jpeg_free_slot_data()
797 jpeg->slot_data.cfg_desc, in mxc_jpeg_free_slot_data()
798 jpeg->slot_data.cfg_desc_handle); in mxc_jpeg_free_slot_data()
799 jpeg->slot_data.cfg_desc_handle = 0; in mxc_jpeg_free_slot_data()
800 jpeg->slot_data.cfg_desc = NULL; in mxc_jpeg_free_slot_data()
803 dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, in mxc_jpeg_free_slot_data()
804 jpeg->slot_data.cfg_stream_vaddr, in mxc_jpeg_free_slot_data()
805 jpeg->slot_data.cfg_stream_handle); in mxc_jpeg_free_slot_data()
806 jpeg->slot_data.cfg_stream_vaddr = NULL; in mxc_jpeg_free_slot_data()
807 jpeg->slot_data.cfg_stream_handle = 0; in mxc_jpeg_free_slot_data()
809 dma_free_coherent(jpeg->dev, jpeg->slot_data.cfg_dec_size, in mxc_jpeg_free_slot_data()
810 jpeg->slot_data.cfg_dec_vaddr, in mxc_jpeg_free_slot_data()
811 jpeg->slot_data.cfg_dec_daddr); in mxc_jpeg_free_slot_data()
812 jpeg->slot_data.cfg_dec_size = 0; in mxc_jpeg_free_slot_data()
813 jpeg->slot_data.cfg_dec_vaddr = NULL; in mxc_jpeg_free_slot_data()
814 jpeg->slot_data.cfg_dec_daddr = 0; in mxc_jpeg_free_slot_data()
816 jpeg->slot_data.used = false; in mxc_jpeg_free_slot_data()
825 if (jpeg->slot_data.desc) in mxc_jpeg_alloc_slot_data()
829 desc = dma_alloc_coherent(jpeg->dev, in mxc_jpeg_alloc_slot_data()
831 &jpeg->slot_data.desc_handle, in mxc_jpeg_alloc_slot_data()
835 jpeg->slot_data.desc = desc; in mxc_jpeg_alloc_slot_data()
838 cfg_desc = dma_alloc_coherent(jpeg->dev, in mxc_jpeg_alloc_slot_data()
840 &jpeg->slot_data.cfg_desc_handle, in mxc_jpeg_alloc_slot_data()
844 jpeg->slot_data.cfg_desc = cfg_desc; in mxc_jpeg_alloc_slot_data()
847 cfg_stm = dma_alloc_coherent(jpeg->dev, in mxc_jpeg_alloc_slot_data()
849 &jpeg->slot_data.cfg_stream_handle, in mxc_jpeg_alloc_slot_data()
853 jpeg->slot_data.cfg_stream_vaddr = cfg_stm; in mxc_jpeg_alloc_slot_data()
855 jpeg->slot_data.cfg_dec_size = MXC_JPEG_PATTERN_WIDTH * MXC_JPEG_PATTERN_HEIGHT * 2; in mxc_jpeg_alloc_slot_data()
856 jpeg->slot_data.cfg_dec_vaddr = dma_alloc_coherent(jpeg->dev, in mxc_jpeg_alloc_slot_data()
857 jpeg->slot_data.cfg_dec_size, in mxc_jpeg_alloc_slot_data()
858 &jpeg->slot_data.cfg_dec_daddr, in mxc_jpeg_alloc_slot_data()
860 if (!jpeg->slot_data.cfg_dec_vaddr) in mxc_jpeg_alloc_slot_data()
864 jpeg->slot_data.used = true; in mxc_jpeg_alloc_slot_data()
868 dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); in mxc_jpeg_alloc_slot_data()
878 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) { in mxc_jpeg_check_and_set_last_buffer()
879 dst_buf->flags |= V4L2_BUF_FLAG_LAST; in mxc_jpeg_check_and_set_last_buffer()
880 v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); in mxc_jpeg_check_and_set_last_buffer()
882 ctx->header_parsed = false; in mxc_jpeg_check_and_set_last_buffer()
888 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_job_finish()
889 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_job_finish()
892 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
893 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
895 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
896 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_job_finish()
900 mxc_jpeg_disable_irq(reg, ctx->slot); in mxc_jpeg_job_finish()
901 jpeg->slot_data.used = false; in mxc_jpeg_job_finish()
908 const struct mxc_jpeg_fmt *fmt = q_data->fmt; in mxc_jpeg_get_plane_size()
912 if (plane_no >= fmt->mem_planes) in mxc_jpeg_get_plane_size()
915 if (fmt->mem_planes == fmt->comp_planes) in mxc_jpeg_get_plane_size()
916 return q_data->sizeimage[plane_no]; in mxc_jpeg_get_plane_size()
918 if (plane_no < fmt->mem_planes - 1) in mxc_jpeg_get_plane_size()
919 return q_data->sizeimage[plane_no]; in mxc_jpeg_get_plane_size()
921 size = q_data->sizeimage[fmt->mem_planes - 1]; in mxc_jpeg_get_plane_size()
924 if (WARN_ON_ONCE(fmt->comp_planes > ARRAY_SIZE(q_data->sizeimage))) in mxc_jpeg_get_plane_size()
927 for (i = fmt->mem_planes; i < fmt->comp_planes; i++) in mxc_jpeg_get_plane_size()
928 size += q_data->sizeimage[i]; in mxc_jpeg_get_plane_size()
935 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_dec_is_ongoing()
939 curr_desc = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_CUR_DESCPT_PTR)); in mxc_dec_is_ongoing()
940 if (curr_desc == jpeg->slot_data.cfg_desc_handle) in mxc_dec_is_ongoing()
943 slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS)); in mxc_dec_is_ongoing()
954 slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS)); in mxc_dec_is_ongoing()
965 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_dec_irq()
966 struct device *dev = jpeg->dev; in mxc_jpeg_dec_irq()
976 spin_lock(&jpeg->hw_lock); in mxc_jpeg_dec_irq()
982 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); in mxc_jpeg_dec_irq()
986 if (slot != ctx->slot) { in mxc_jpeg_dec_irq()
987 /* TODO investigate when adding multi-instance support */ in mxc_jpeg_dec_irq()
989 slot, ctx->slot); in mxc_jpeg_dec_irq()
993 if (!jpeg->slot_data.used) in mxc_jpeg_dec_irq()
999 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in mxc_jpeg_dec_irq()
1000 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in mxc_jpeg_dec_irq()
1005 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf); in mxc_jpeg_dec_irq()
1021 if (jpeg->mode == MXC_JPEG_ENCODE && in mxc_jpeg_dec_irq()
1022 ctx->enc_state == MXC_JPEG_ENC_CONF) { in mxc_jpeg_dec_irq()
1024 ctx->enc_state = MXC_JPEG_ENCODING; in mxc_jpeg_dec_irq()
1026 mxc_jpeg_enc_set_quality(dev, reg, ctx->jpeg_quality); in mxc_jpeg_dec_irq()
1027 mxc_jpeg_enc_mode_go(dev, reg, mxc_jpeg_is_extended_sequential(q_data->fmt)); in mxc_jpeg_dec_irq()
1030 if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed && in mxc_jpeg_dec_irq()
1032 jpeg_src_buf->dht_needed = false; in mxc_jpeg_dec_irq()
1037 if (jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_dec_irq()
1039 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); in mxc_jpeg_dec_irq()
1045 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); in mxc_jpeg_dec_irq()
1046 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0); in mxc_jpeg_dec_irq()
1047 if (q_data->fmt->mem_planes == 2) { in mxc_jpeg_dec_irq()
1049 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload); in mxc_jpeg_dec_irq()
1052 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 0), in mxc_jpeg_dec_irq()
1053 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 1)); in mxc_jpeg_dec_irq()
1058 print_mxc_buf(jpeg, &src_buf->vb2_buf, 32); in mxc_jpeg_dec_irq()
1060 print_mxc_buf(jpeg, &dst_buf->vb2_buf, 32); in mxc_jpeg_dec_irq()
1065 spin_unlock(&jpeg->hw_lock); in mxc_jpeg_dec_irq()
1066 cancel_delayed_work(&ctx->task_timer); in mxc_jpeg_dec_irq()
1067 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_dec_irq()
1070 spin_unlock(&jpeg->hw_lock); in mxc_jpeg_dec_irq()
1082 sof->precision = fmt->precision; in mxc_jpeg_fixup_sof()
1084 sof->precision = 8; /* TODO allow 8/12 bit precision*/ in mxc_jpeg_fixup_sof()
1085 sof->height = h; in mxc_jpeg_fixup_sof()
1086 _bswap16(&sof->height); in mxc_jpeg_fixup_sof()
1087 sof->width = w; in mxc_jpeg_fixup_sof()
1088 _bswap16(&sof->width); in mxc_jpeg_fixup_sof()
1095 sof->components_no = 3; in mxc_jpeg_fixup_sof()
1096 sof->comp[0].v = 0x2; in mxc_jpeg_fixup_sof()
1097 sof->comp[0].h = 0x2; in mxc_jpeg_fixup_sof()
1101 sof->components_no = 3; in mxc_jpeg_fixup_sof()
1102 sof->comp[0].v = 0x1; in mxc_jpeg_fixup_sof()
1103 sof->comp[0].h = 0x2; in mxc_jpeg_fixup_sof()
1110 sof->components_no = 3; in mxc_jpeg_fixup_sof()
1114 sof->components_no = 4; in mxc_jpeg_fixup_sof()
1118 sof->components_no = 1; in mxc_jpeg_fixup_sof()
1121 sof_length = 8 + 3 * sof->components_no; in mxc_jpeg_fixup_sof()
1122 sof->length = sof_length; in mxc_jpeg_fixup_sof()
1123 _bswap16(&sof->length); in mxc_jpeg_fixup_sof()
1139 sos->components_no = 3; in mxc_jpeg_fixup_sos()
1143 sos->components_no = 3; in mxc_jpeg_fixup_sos()
1150 sos->components_no = 3; in mxc_jpeg_fixup_sos()
1154 sos->components_no = 4; in mxc_jpeg_fixup_sos()
1158 sos->components_no = 1; in mxc_jpeg_fixup_sos()
1161 sos_length = 6 + 2 * sos->components_no; in mxc_jpeg_fixup_sos()
1162 sos->length = sos_length; in mxc_jpeg_fixup_sos()
1163 _bswap16(&sos->length); in mxc_jpeg_fixup_sos()
1166 sof_u8[sos_length - 1] = 0x0; in mxc_jpeg_fixup_sos()
1167 sof_u8[sos_length - 2] = 0x3f; in mxc_jpeg_fixup_sos()
1168 sof_u8[sos_length - 3] = 0x0; in mxc_jpeg_fixup_sos()
1195 if (fmt->is_rgb) { in mxc_jpeg_setup_cfg_stream()
1251 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_config_dec_desc()
1252 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_config_dec_desc()
1253 unsigned int slot = ctx->slot; in mxc_jpeg_config_dec_desc()
1254 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; in mxc_jpeg_config_dec_desc()
1255 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; in mxc_jpeg_config_dec_desc()
1256 dma_addr_t desc_handle = jpeg->slot_data.desc_handle; in mxc_jpeg_config_dec_desc()
1257 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; in mxc_jpeg_config_dec_desc()
1258 dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle; in mxc_jpeg_config_dec_desc()
1259 unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size; in mxc_jpeg_config_dec_desc()
1260 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; in mxc_jpeg_config_dec_desc()
1266 desc->next_descpt_ptr = 0; /* end of chain */ in mxc_jpeg_config_dec_desc()
1268 desc->imgsize = q_data_cap->w_adjusted << 16 | q_data_cap->h_adjusted; in mxc_jpeg_config_dec_desc()
1269 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data_cap->fmt->fourcc); in mxc_jpeg_config_dec_desc()
1270 desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF); /* clear image format */ in mxc_jpeg_config_dec_desc()
1271 desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt); in mxc_jpeg_config_dec_desc()
1272 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_dec_desc()
1273 if (mxc_jpeg_is_extended_sequential(jpeg_src_buf->fmt)) in mxc_jpeg_config_dec_desc()
1274 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_dec_desc()
1276 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_dec_desc()
1277 desc->line_pitch = q_data_cap->bytesperline[0]; in mxc_jpeg_config_dec_desc()
1280 print_descriptor_info(jpeg->dev, desc); in mxc_jpeg_config_dec_desc()
1282 if (!jpeg_src_buf->dht_needed) { in mxc_jpeg_config_dec_desc()
1296 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; in mxc_jpeg_config_dec_desc()
1297 cfg_desc->buf_base0 = jpeg->slot_data.cfg_dec_daddr; in mxc_jpeg_config_dec_desc()
1298 cfg_desc->buf_base1 = 0; in mxc_jpeg_config_dec_desc()
1299 cfg_desc->imgsize = MXC_JPEG_PATTERN_WIDTH << 16; in mxc_jpeg_config_dec_desc()
1300 cfg_desc->imgsize |= MXC_JPEG_PATTERN_HEIGHT; in mxc_jpeg_config_dec_desc()
1301 cfg_desc->line_pitch = MXC_JPEG_PATTERN_WIDTH * 2; in mxc_jpeg_config_dec_desc()
1302 cfg_desc->stm_ctrl = STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422); in mxc_jpeg_config_dec_desc()
1303 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_dec_desc()
1304 cfg_desc->stm_bufbase = cfg_stream_handle; in mxc_jpeg_config_dec_desc()
1305 cfg_desc->stm_bufsize = ALIGN(*cfg_size, 1024); in mxc_jpeg_config_dec_desc()
1306 print_descriptor_info(jpeg->dev, cfg_desc); in mxc_jpeg_config_dec_desc()
1317 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_config_enc_desc()
1318 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_config_enc_desc()
1319 unsigned int slot = ctx->slot; in mxc_jpeg_config_enc_desc()
1320 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; in mxc_jpeg_config_enc_desc()
1321 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; in mxc_jpeg_config_enc_desc()
1322 dma_addr_t desc_handle = jpeg->slot_data.desc_handle; in mxc_jpeg_config_enc_desc()
1323 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; in mxc_jpeg_config_enc_desc()
1324 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; in mxc_jpeg_config_enc_desc()
1329 q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type); in mxc_jpeg_config_enc_desc()
1331 jpeg->slot_data.cfg_stream_size = in mxc_jpeg_config_enc_desc()
1333 q_data->fmt->fourcc, in mxc_jpeg_config_enc_desc()
1334 q_data->crop.width, in mxc_jpeg_config_enc_desc()
1335 q_data->crop.height); in mxc_jpeg_config_enc_desc()
1338 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; in mxc_jpeg_config_enc_desc()
1340 cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle; in mxc_jpeg_config_enc_desc()
1341 cfg_desc->buf_base1 = 0; in mxc_jpeg_config_enc_desc()
1342 cfg_desc->line_pitch = 0; in mxc_jpeg_config_enc_desc()
1343 cfg_desc->stm_bufbase = 0; /* no output expected */ in mxc_jpeg_config_enc_desc()
1344 cfg_desc->stm_bufsize = 0x0; in mxc_jpeg_config_enc_desc()
1345 cfg_desc->imgsize = 0; in mxc_jpeg_config_enc_desc()
1346 cfg_desc->stm_ctrl = STM_CTRL_CONFIG_MOD(1); in mxc_jpeg_config_enc_desc()
1347 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_enc_desc()
1349 desc->next_descpt_ptr = 0; /* end of chain */ in mxc_jpeg_config_enc_desc()
1352 w = q_data->crop.width; in mxc_jpeg_config_enc_desc()
1353 h = q_data->crop.height; in mxc_jpeg_config_enc_desc()
1354 v4l_bound_align_image(&w, w, MXC_JPEG_MAX_WIDTH, q_data->fmt->h_align, in mxc_jpeg_config_enc_desc()
1355 &h, h, MXC_JPEG_MAX_HEIGHT, q_data->fmt->v_align, 0); in mxc_jpeg_config_enc_desc()
1357 mxc_jpeg_set_line_pitch(desc, q_data->bytesperline[0]); in mxc_jpeg_config_enc_desc()
1359 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data->fmt->fourcc); in mxc_jpeg_config_enc_desc()
1361 dev_err(jpeg->dev, "No valid image format detected\n"); in mxc_jpeg_config_enc_desc()
1362 desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) | in mxc_jpeg_config_enc_desc()
1364 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); in mxc_jpeg_config_enc_desc()
1365 if (mxc_jpeg_is_extended_sequential(q_data->fmt)) in mxc_jpeg_config_enc_desc()
1366 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_enc_desc()
1368 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION; in mxc_jpeg_config_enc_desc()
1370 dev_dbg(jpeg->dev, "cfg_desc:\n"); in mxc_jpeg_config_enc_desc()
1371 print_descriptor_info(jpeg->dev, cfg_desc); in mxc_jpeg_config_enc_desc()
1372 dev_dbg(jpeg->dev, "enc desc:\n"); in mxc_jpeg_config_enc_desc()
1373 print_descriptor_info(jpeg->dev, desc); in mxc_jpeg_config_enc_desc()
1374 print_wrapper_info(jpeg->dev, reg); in mxc_jpeg_config_enc_desc()
1375 print_cast_status(jpeg->dev, reg, MXC_JPEG_ENCODE); in mxc_jpeg_config_enc_desc()
1386 if (mxc_formats[i].subsampling == fmt->subsampling && in mxc_jpeg_get_sibling_format()
1387 mxc_formats[i].nc == fmt->nc && in mxc_jpeg_get_sibling_format()
1388 mxc_formats[i].precision == fmt->precision && in mxc_jpeg_get_sibling_format()
1389 mxc_formats[i].is_rgb == fmt->is_rgb && in mxc_jpeg_get_sibling_format()
1390 mxc_formats[i].fourcc != fmt->fourcc) in mxc_jpeg_get_sibling_format()
1411 next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_set_last_buffer()
1413 ctx->fh.m2m_ctx->is_draining = true; in mxc_jpeg_set_last_buffer()
1414 ctx->fh.m2m_ctx->next_buf_last = true; in mxc_jpeg_set_last_buffer()
1418 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, next_dst_buf); in mxc_jpeg_set_last_buffer()
1424 struct device *dev = ctx->mxc_jpeg->dev; in mxc_jpeg_source_change()
1427 if (!jpeg_src_buf->fmt) in mxc_jpeg_source_change()
1431 if (mxc_jpeg_compare_format(q_data_cap->fmt, jpeg_src_buf->fmt)) in mxc_jpeg_source_change()
1432 jpeg_src_buf->fmt = q_data_cap->fmt; in mxc_jpeg_source_change()
1433 if (ctx->need_initial_source_change_evt || in mxc_jpeg_source_change()
1434 q_data_cap->fmt != jpeg_src_buf->fmt || in mxc_jpeg_source_change()
1435 q_data_cap->w != jpeg_src_buf->w || in mxc_jpeg_source_change()
1436 q_data_cap->h != jpeg_src_buf->h) { in mxc_jpeg_source_change()
1437 dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n", in mxc_jpeg_source_change()
1438 q_data_cap->w, q_data_cap->h, in mxc_jpeg_source_change()
1439 jpeg_src_buf->w, jpeg_src_buf->h, in mxc_jpeg_source_change()
1440 (jpeg_src_buf->fmt->fourcc & 0xff), in mxc_jpeg_source_change()
1441 (jpeg_src_buf->fmt->fourcc >> 8) & 0xff, in mxc_jpeg_source_change()
1442 (jpeg_src_buf->fmt->fourcc >> 16) & 0xff, in mxc_jpeg_source_change()
1443 (jpeg_src_buf->fmt->fourcc >> 24) & 0xff); in mxc_jpeg_source_change()
1446 * set-up the capture queue with the pixelformat and resolution in mxc_jpeg_source_change()
1449 q_data_cap->w = jpeg_src_buf->w; in mxc_jpeg_source_change()
1450 q_data_cap->h = jpeg_src_buf->h; in mxc_jpeg_source_change()
1451 q_data_cap->fmt = jpeg_src_buf->fmt; in mxc_jpeg_source_change()
1452 q_data_cap->w_adjusted = q_data_cap->w; in mxc_jpeg_source_change()
1453 q_data_cap->h_adjusted = q_data_cap->h; in mxc_jpeg_source_change()
1454 q_data_cap->crop.left = 0; in mxc_jpeg_source_change()
1455 q_data_cap->crop.top = 0; in mxc_jpeg_source_change()
1456 q_data_cap->crop.width = jpeg_src_buf->w; in mxc_jpeg_source_change()
1457 q_data_cap->crop.height = jpeg_src_buf->h; in mxc_jpeg_source_change()
1458 q_data_cap->bytesperline[0] = 0; in mxc_jpeg_source_change()
1459 q_data_cap->bytesperline[1] = 0; in mxc_jpeg_source_change()
1465 v4l_bound_align_image(&q_data_cap->w_adjusted, in mxc_jpeg_source_change()
1466 q_data_cap->w_adjusted, /* adjust up */ in mxc_jpeg_source_change()
1468 q_data_cap->fmt->h_align, in mxc_jpeg_source_change()
1469 &q_data_cap->h_adjusted, in mxc_jpeg_source_change()
1470 q_data_cap->h_adjusted, /* adjust up */ in mxc_jpeg_source_change()
1472 q_data_cap->fmt->v_align, in mxc_jpeg_source_change()
1476 mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision); in mxc_jpeg_source_change()
1479 ctx->source_change = 1; in mxc_jpeg_source_change()
1480 ctx->need_initial_source_change_evt = false; in mxc_jpeg_source_change()
1481 if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) in mxc_jpeg_source_change()
1485 return ctx->source_change ? true : false; in mxc_jpeg_source_change()
1492 return ctx->source_change ? 0 : 1; in mxc_jpeg_job_ready()
1499 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_device_run_timeout()
1502 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run_timeout()
1503 if (ctx->mxc_jpeg->slot_data.used) { in mxc_jpeg_device_run_timeout()
1504 dev_warn(jpeg->dev, "%s timeout, cancel it\n", in mxc_jpeg_device_run_timeout()
1505 ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode"); in mxc_jpeg_device_run_timeout()
1507 v4l2_m2m_job_finish(ctx->mxc_jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_device_run_timeout()
1509 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run_timeout()
1515 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_device_run()
1516 void __iomem *reg = jpeg->base_reg; in mxc_jpeg_device_run()
1517 struct device *dev = jpeg->dev; in mxc_jpeg_device_run()
1523 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1524 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1525 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1537 src_buf->sequence = q_data_out->sequence++; in mxc_jpeg_device_run()
1538 dst_buf->sequence = q_data_cap->sequence++; in mxc_jpeg_device_run()
1542 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf); in mxc_jpeg_device_run()
1543 if (q_data_cap->fmt->mem_planes != dst_buf->vb2_buf.num_planes) { in mxc_jpeg_device_run()
1545 q_data_cap->fmt->name, q_data_cap->fmt->mem_planes, in mxc_jpeg_device_run()
1546 dst_buf->vb2_buf.num_planes); in mxc_jpeg_device_run()
1547 jpeg_src_buf->jpeg_parse_error = true; in mxc_jpeg_device_run()
1549 if (jpeg_src_buf->jpeg_parse_error) { in mxc_jpeg_device_run()
1551 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1552 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1555 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1556 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1560 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) { in mxc_jpeg_device_run()
1561 if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) { in mxc_jpeg_device_run()
1562 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1563 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); in mxc_jpeg_device_run()
1571 ctx->slot = mxc_get_free_slot(&jpeg->slot_data); in mxc_jpeg_device_run()
1572 if (ctx->slot < 0) { in mxc_jpeg_device_run()
1581 mxc_jpeg_enable_slot(reg, ctx->slot); in mxc_jpeg_device_run()
1582 mxc_jpeg_enable_irq(reg, ctx->slot); in mxc_jpeg_device_run()
1584 if (jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_device_run()
1585 dev_dbg(dev, "Encoding on slot %d\n", ctx->slot); in mxc_jpeg_device_run()
1586 ctx->enc_state = MXC_JPEG_ENC_CONF; in mxc_jpeg_device_run()
1587 mxc_jpeg_config_enc_desc(&dst_buf->vb2_buf, ctx, in mxc_jpeg_device_run()
1588 &src_buf->vb2_buf, &dst_buf->vb2_buf); in mxc_jpeg_device_run()
1591 mxc_jpeg_is_extended_sequential(q_data_out->fmt)); in mxc_jpeg_device_run()
1593 dev_dbg(dev, "Decoding on slot %d\n", ctx->slot); in mxc_jpeg_device_run()
1594 print_mxc_buf(jpeg, &src_buf->vb2_buf, 0); in mxc_jpeg_device_run()
1595 mxc_jpeg_config_dec_desc(&dst_buf->vb2_buf, ctx, in mxc_jpeg_device_run()
1596 &src_buf->vb2_buf, &dst_buf->vb2_buf); in mxc_jpeg_device_run()
1599 schedule_delayed_work(&ctx->task_timer, msecs_to_jiffies(hw_timeout)); in mxc_jpeg_device_run()
1601 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_device_run()
1607 struct v4l2_fh *fh = file->private_data; in mxc_jpeg_decoder_cmd()
1616 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx))) in mxc_jpeg_decoder_cmd()
1619 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_decoder_cmd()
1621 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_decoder_cmd()
1625 if (cmd->cmd == V4L2_DEC_CMD_STOP && in mxc_jpeg_decoder_cmd()
1626 v4l2_m2m_has_stopped(fh->m2m_ctx)) { in mxc_jpeg_decoder_cmd()
1628 ctx->header_parsed = false; in mxc_jpeg_decoder_cmd()
1631 if (cmd->cmd == V4L2_DEC_CMD_START && in mxc_jpeg_decoder_cmd()
1632 v4l2_m2m_has_stopped(fh->m2m_ctx)) in mxc_jpeg_decoder_cmd()
1633 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); in mxc_jpeg_decoder_cmd()
1640 struct v4l2_fh *fh = file->private_data; in mxc_jpeg_encoder_cmd()
1649 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) || in mxc_jpeg_encoder_cmd()
1650 !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx))) in mxc_jpeg_encoder_cmd()
1653 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_encoder_cmd()
1655 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); in mxc_jpeg_encoder_cmd()
1659 if (cmd->cmd == V4L2_ENC_CMD_STOP && in mxc_jpeg_encoder_cmd()
1660 v4l2_m2m_has_stopped(fh->m2m_ctx)) in mxc_jpeg_encoder_cmd()
1663 if (cmd->cmd == V4L2_ENC_CMD_START && in mxc_jpeg_encoder_cmd()
1664 v4l2_m2m_has_stopped(fh->m2m_ctx)) in mxc_jpeg_encoder_cmd()
1665 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); in mxc_jpeg_encoder_cmd()
1680 q_data = mxc_jpeg_get_q_data(ctx, q->type); in mxc_jpeg_queue_setup()
1682 return -EINVAL; in mxc_jpeg_queue_setup()
1684 /* Handle CREATE_BUFS situation - *nplanes != 0 */ in mxc_jpeg_queue_setup()
1686 if (*nplanes != q_data->fmt->mem_planes) in mxc_jpeg_queue_setup()
1687 return -EINVAL; in mxc_jpeg_queue_setup()
1690 return -EINVAL; in mxc_jpeg_queue_setup()
1696 *nplanes = q_data->fmt->mem_planes; in mxc_jpeg_queue_setup()
1700 if (V4L2_TYPE_IS_OUTPUT(q->type)) in mxc_jpeg_queue_setup()
1701 ctx->need_initial_source_change_evt = true; in mxc_jpeg_queue_setup()
1709 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type); in mxc_jpeg_start_streaming()
1712 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); in mxc_jpeg_start_streaming()
1714 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type)) in mxc_jpeg_start_streaming()
1715 ctx->source_change = 0; in mxc_jpeg_start_streaming()
1716 dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx); in mxc_jpeg_start_streaming()
1717 q_data->sequence = 0; in mxc_jpeg_start_streaming()
1719 if (V4L2_TYPE_IS_CAPTURE(q->type)) in mxc_jpeg_start_streaming()
1720 ctx->need_initial_source_change_evt = false; in mxc_jpeg_start_streaming()
1722 ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev); in mxc_jpeg_start_streaming()
1724 dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n"); in mxc_jpeg_start_streaming()
1736 dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming ctx=%p", ctx); in mxc_jpeg_stop_streaming()
1740 if (V4L2_TYPE_IS_OUTPUT(q->type)) in mxc_jpeg_stop_streaming()
1741 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_stop_streaming()
1743 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in mxc_jpeg_stop_streaming()
1749 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); in mxc_jpeg_stop_streaming()
1753 if (V4L2_TYPE_IS_CAPTURE(q->type) && ctx->source_change && ctx->fh.m2m_ctx->last_src_buf) in mxc_jpeg_stop_streaming()
1754 ctx->fh.m2m_ctx->is_draining = true; in mxc_jpeg_stop_streaming()
1756 if (V4L2_TYPE_IS_OUTPUT(q->type) && in mxc_jpeg_stop_streaming()
1757 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) { in mxc_jpeg_stop_streaming()
1759 ctx->header_parsed = false; in mxc_jpeg_stop_streaming()
1762 pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); in mxc_jpeg_stop_streaming()
1776 for (i = 0; i < sof->components_no; i++) in mxc_jpeg_valid_comp_id()
1777 if (sof->comp[i].id > MXC_JPEG_MAX_COMPONENTS) { in mxc_jpeg_valid_comp_id()
1780 i, sof->comp[i].id); in mxc_jpeg_valid_comp_id()
1784 for (i = 0; i < sof->components_no; i++) { in mxc_jpeg_valid_comp_id()
1787 sof->comp[i].id = i + 1; in mxc_jpeg_valid_comp_id()
1788 sos->comp[i].id = i + 1; in mxc_jpeg_valid_comp_id()
1797 if (fmt->subsampling != header->frame.subsampling || in mxc_jpeg_match_image_format()
1798 fmt->nc != header->frame.num_components || in mxc_jpeg_match_image_format()
1799 fmt->precision != header->frame.precision) in mxc_jpeg_match_image_format()
1805 * ITU-T T.872 chapter 6.5.3 APP14 marker segment for colour encoding in mxc_jpeg_match_image_format()
1807 if (header->frame.subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) { in mxc_jpeg_match_image_format()
1808 u8 is_rgb = header->app14_tf == V4L2_JPEG_APP14_TF_CMYK_RGB ? 1 : 0; in mxc_jpeg_match_image_format()
1810 if (is_rgb != fmt->is_rgb) in mxc_jpeg_match_image_format()
1831 header->frame.num_components, in mxc_jpeg_get_image_format()
1832 header->frame.subsampling, in mxc_jpeg_get_image_format()
1833 header->frame.precision); in mxc_jpeg_get_image_format()
1844 bytesperline[0] = q->bytesperline[0]; in mxc_jpeg_bytesperline()
1845 bytesperline[1] = q->bytesperline[0]; /*imx-jpeg only support the same line pitch*/ in mxc_jpeg_bytesperline()
1851 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) { in mxc_jpeg_bytesperline()
1853 q->bytesperline[0] = 0; in mxc_jpeg_bytesperline()
1854 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1855 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) { in mxc_jpeg_bytesperline()
1860 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8); in mxc_jpeg_bytesperline()
1861 q->bytesperline[1] = q->bytesperline[0]; in mxc_jpeg_bytesperline()
1862 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) { in mxc_jpeg_bytesperline()
1863 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * 2; in mxc_jpeg_bytesperline()
1864 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1865 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) { in mxc_jpeg_bytesperline()
1866 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * q->fmt->nc; in mxc_jpeg_bytesperline()
1867 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1870 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8); in mxc_jpeg_bytesperline()
1871 q->bytesperline[1] = 0; in mxc_jpeg_bytesperline()
1874 if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) { in mxc_jpeg_bytesperline()
1875 q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]); in mxc_jpeg_bytesperline()
1876 if (q->fmt->mem_planes > 1) in mxc_jpeg_bytesperline()
1877 q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]); in mxc_jpeg_bytesperline()
1883 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) { in mxc_jpeg_sizeimage()
1885 if (!q->sizeimage[0]) in mxc_jpeg_sizeimage()
1886 q->sizeimage[0] = 6 * q->w * q->h; in mxc_jpeg_sizeimage()
1887 q->sizeimage[1] = 0; in mxc_jpeg_sizeimage()
1889 if (q->sizeimage[0] > MXC_JPEG_MAX_SIZEIMAGE) in mxc_jpeg_sizeimage()
1890 q->sizeimage[0] = MXC_JPEG_MAX_SIZEIMAGE; in mxc_jpeg_sizeimage()
1893 q->sizeimage[0] = ALIGN(q->sizeimage[0], 1024); in mxc_jpeg_sizeimage()
1895 q->sizeimage[0] = q->bytesperline[0] * q->h_adjusted; in mxc_jpeg_sizeimage()
1896 q->sizeimage[1] = 0; in mxc_jpeg_sizeimage()
1897 if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) in mxc_jpeg_sizeimage()
1898 q->sizeimage[1] = q->sizeimage[0] / 2; in mxc_jpeg_sizeimage()
1904 struct device *dev = ctx->mxc_jpeg->dev; in mxc_jpeg_parse()
1924 jpeg_src_buf->dht_needed = (header.num_dht == 0); in mxc_jpeg_parse()
1928 q_data_out->w = header.frame.width; in mxc_jpeg_parse()
1929 q_data_out->h = header.frame.height; in mxc_jpeg_parse()
1934 return -EINVAL; in mxc_jpeg_parse()
1940 return -EINVAL; in mxc_jpeg_parse()
1945 return -EINVAL; in mxc_jpeg_parse()
1951 dev_warn(dev, "JPEG component ids should be 0-3 or 1-4"); in mxc_jpeg_parse()
1954 if (q_data_cap->fmt && mxc_jpeg_match_image_format(q_data_cap->fmt, &header)) in mxc_jpeg_parse()
1955 fourcc = q_data_cap->fmt->fourcc; in mxc_jpeg_parse()
1959 return -EINVAL; in mxc_jpeg_parse()
1961 jpeg_src_buf->fmt = mxc_jpeg_find_format(fourcc); in mxc_jpeg_parse()
1962 jpeg_src_buf->w = header.frame.width; in mxc_jpeg_parse()
1963 jpeg_src_buf->h = header.frame.height; in mxc_jpeg_parse()
1964 ctx->header_parsed = true; in mxc_jpeg_parse()
1966 if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx)) in mxc_jpeg_parse()
1976 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in mxc_jpeg_buf_queue()
1979 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && in mxc_jpeg_buf_queue()
1980 vb2_is_streaming(vb->vb2_queue) && in mxc_jpeg_buf_queue()
1981 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { in mxc_jpeg_buf_queue()
1984 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); in mxc_jpeg_buf_queue()
1985 vbuf->field = V4L2_FIELD_NONE; in mxc_jpeg_buf_queue()
1986 vbuf->sequence = q_data->sequence++; in mxc_jpeg_buf_queue()
1987 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); in mxc_jpeg_buf_queue()
1989 ctx->header_parsed = false; in mxc_jpeg_buf_queue()
1993 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in mxc_jpeg_buf_queue()
1997 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) in mxc_jpeg_buf_queue()
2001 jpeg_src_buf->jpeg_parse_error = false; in mxc_jpeg_buf_queue()
2004 jpeg_src_buf->jpeg_parse_error = true; in mxc_jpeg_buf_queue()
2010 if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) { in mxc_jpeg_buf_queue()
2017 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in mxc_jpeg_buf_queue()
2024 vbuf->field = V4L2_FIELD_NONE; in mxc_jpeg_buf_out_validate()
2032 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in mxc_jpeg_buf_prepare()
2034 struct device *dev = ctx->mxc_jpeg->dev; in mxc_jpeg_buf_prepare()
2038 vbuf->field = V4L2_FIELD_NONE; in mxc_jpeg_buf_prepare()
2040 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); in mxc_jpeg_buf_prepare()
2042 return -EINVAL; in mxc_jpeg_buf_prepare()
2043 for (i = 0; i < q_data->fmt->mem_planes; i++) { in mxc_jpeg_buf_prepare()
2045 if (!ctx->source_change && vb2_plane_size(vb, i) < sizeimage) { in mxc_jpeg_buf_prepare()
2048 return -EINVAL; in mxc_jpeg_buf_prepare()
2053 return -EINVAL; in mxc_jpeg_buf_prepare()
2056 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) { in mxc_jpeg_buf_prepare()
2078 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; in mxc_jpeg_queue_init()
2079 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; in mxc_jpeg_queue_init()
2080 src_vq->drv_priv = ctx; in mxc_jpeg_queue_init()
2081 src_vq->buf_struct_size = sizeof(struct mxc_jpeg_src_buf); in mxc_jpeg_queue_init()
2082 src_vq->ops = &mxc_jpeg_qops; in mxc_jpeg_queue_init()
2083 src_vq->mem_ops = &vb2_dma_contig_memops; in mxc_jpeg_queue_init()
2084 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in mxc_jpeg_queue_init()
2085 src_vq->lock = &ctx->mxc_jpeg->lock; in mxc_jpeg_queue_init()
2086 src_vq->dev = ctx->mxc_jpeg->dev; in mxc_jpeg_queue_init()
2092 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in mxc_jpeg_queue_init()
2093 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; in mxc_jpeg_queue_init()
2094 dst_vq->drv_priv = ctx; in mxc_jpeg_queue_init()
2095 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in mxc_jpeg_queue_init()
2096 dst_vq->ops = &mxc_jpeg_qops; in mxc_jpeg_queue_init()
2097 dst_vq->mem_ops = &vb2_dma_contig_memops; in mxc_jpeg_queue_init()
2098 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in mxc_jpeg_queue_init()
2099 dst_vq->lock = &ctx->mxc_jpeg->lock; in mxc_jpeg_queue_init()
2100 dst_vq->dev = ctx->mxc_jpeg->dev; in mxc_jpeg_queue_init()
2108 struct mxc_jpeg_q_data *out_q = &ctx->out_q; in mxc_jpeg_set_default_params()
2109 struct mxc_jpeg_q_data *cap_q = &ctx->cap_q; in mxc_jpeg_set_default_params()
2113 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_set_default_params()
2114 out_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT); in mxc_jpeg_set_default_params()
2115 cap_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG); in mxc_jpeg_set_default_params()
2117 out_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG); in mxc_jpeg_set_default_params()
2118 cap_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT); in mxc_jpeg_set_default_params()
2122 q[i]->w = MXC_JPEG_DEFAULT_WIDTH; in mxc_jpeg_set_default_params()
2123 q[i]->h = MXC_JPEG_DEFAULT_HEIGHT; in mxc_jpeg_set_default_params()
2124 q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH; in mxc_jpeg_set_default_params()
2125 q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT; in mxc_jpeg_set_default_params()
2126 q[i]->crop.left = 0; in mxc_jpeg_set_default_params()
2127 q[i]->crop.top = 0; in mxc_jpeg_set_default_params()
2128 q[i]->crop.width = MXC_JPEG_DEFAULT_WIDTH; in mxc_jpeg_set_default_params()
2129 q[i]->crop.height = MXC_JPEG_DEFAULT_HEIGHT; in mxc_jpeg_set_default_params()
2130 mxc_jpeg_bytesperline(q[i], q[i]->fmt->precision); in mxc_jpeg_set_default_params()
2138 container_of(ctrl->handler, struct mxc_jpeg_ctx, ctrl_handler); in mxc_jpeg_s_ctrl()
2140 switch (ctrl->id) { in mxc_jpeg_s_ctrl()
2142 ctx->jpeg_quality = ctrl->val; in mxc_jpeg_s_ctrl()
2145 dev_err(ctx->mxc_jpeg->dev, "Invalid control, id = %d, val = %d\n", in mxc_jpeg_s_ctrl()
2146 ctrl->id, ctrl->val); in mxc_jpeg_s_ctrl()
2147 return -EINVAL; in mxc_jpeg_s_ctrl()
2159 v4l2_ctrl_new_std(&ctx->ctrl_handler, &mxc_jpeg_ctrl_ops, in mxc_jpeg_encode_ctrls()
2167 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 2); in mxc_jpeg_ctrls_setup()
2169 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) in mxc_jpeg_ctrls_setup()
2172 if (ctx->ctrl_handler.error) { in mxc_jpeg_ctrls_setup()
2173 err = ctx->ctrl_handler.error; in mxc_jpeg_ctrls_setup()
2175 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in mxc_jpeg_ctrls_setup()
2179 err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler); in mxc_jpeg_ctrls_setup()
2181 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in mxc_jpeg_ctrls_setup()
2189 struct device *dev = mxc_jpeg->dev; in mxc_jpeg_open()
2195 return -ENOMEM; in mxc_jpeg_open()
2197 if (mutex_lock_interruptible(&mxc_jpeg->lock)) { in mxc_jpeg_open()
2198 ret = -ERESTARTSYS; in mxc_jpeg_open()
2202 v4l2_fh_init(&ctx->fh, mxc_vfd); in mxc_jpeg_open()
2203 file->private_data = &ctx->fh; in mxc_jpeg_open()
2204 v4l2_fh_add(&ctx->fh); in mxc_jpeg_open()
2206 ctx->mxc_jpeg = mxc_jpeg; in mxc_jpeg_open()
2208 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(mxc_jpeg->m2m_dev, ctx, in mxc_jpeg_open()
2211 if (IS_ERR(ctx->fh.m2m_ctx)) { in mxc_jpeg_open()
2212 ret = PTR_ERR(ctx->fh.m2m_ctx); in mxc_jpeg_open()
2218 dev_err(ctx->mxc_jpeg->dev, "failed to setup mxc jpeg controls\n"); in mxc_jpeg_open()
2221 ctx->fh.ctrl_handler = &ctx->ctrl_handler; in mxc_jpeg_open()
2223 ctx->slot = -1; /* slot not allocated yet */ in mxc_jpeg_open()
2224 INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout); in mxc_jpeg_open()
2226 if (mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_open()
2230 mutex_unlock(&mxc_jpeg->lock); in mxc_jpeg_open()
2235 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in mxc_jpeg_open()
2237 v4l2_fh_del(&ctx->fh); in mxc_jpeg_open()
2238 v4l2_fh_exit(&ctx->fh); in mxc_jpeg_open()
2239 mutex_unlock(&mxc_jpeg->lock); in mxc_jpeg_open()
2248 strscpy(cap->driver, MXC_JPEG_NAME " codec", sizeof(cap->driver)); in mxc_jpeg_querycap()
2249 strscpy(cap->card, MXC_JPEG_NAME " codec", sizeof(cap->card)); in mxc_jpeg_querycap()
2250 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; in mxc_jpeg_querycap()
2251 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; in mxc_jpeg_querycap()
2260 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type); in mxc_jpeg_enum_fmt_vid_cap()
2262 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) { in mxc_jpeg_enum_fmt_vid_cap()
2265 } else if (!ctx->header_parsed) { in mxc_jpeg_enum_fmt_vid_cap()
2274 int ret = -EINVAL; in mxc_jpeg_enum_fmt_vid_cap()
2277 switch (f->index) { in mxc_jpeg_enum_fmt_vid_cap()
2279 f->pixelformat = q_data->fmt->fourcc; in mxc_jpeg_enum_fmt_vid_cap()
2283 sibling = mxc_jpeg_get_sibling_format(q_data->fmt); in mxc_jpeg_enum_fmt_vid_cap()
2285 f->pixelformat = sibling->fourcc; in mxc_jpeg_enum_fmt_vid_cap()
2300 u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC : in mxc_jpeg_enum_fmt_vid_out()
2307 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_enum_fmt_vid_out()
2308 f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION; in mxc_jpeg_enum_fmt_vid_out()
2314 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_get_fmt_type()
2322 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_get_default_fourcc()
2333 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) in mxc_jpeg_try_fourcc()
2335 if (!ctx->header_parsed) in mxc_jpeg_try_fourcc()
2338 q_data_cap = &ctx->cap_q; in mxc_jpeg_try_fourcc()
2339 if (q_data_cap->fmt->fourcc == fourcc) in mxc_jpeg_try_fourcc()
2342 sibling = mxc_jpeg_get_sibling_format(q_data_cap->fmt); in mxc_jpeg_try_fourcc()
2343 if (sibling && sibling->fourcc == fourcc) in mxc_jpeg_try_fourcc()
2344 return sibling->fourcc; in mxc_jpeg_try_fourcc()
2346 return q_data_cap->fmt->fourcc; in mxc_jpeg_try_fourcc()
2353 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in mxc_jpeg_try_fmt()
2355 u32 fourcc = f->fmt.pix_mp.pixelformat; in mxc_jpeg_try_fmt()
2356 u32 w = (pix_mp->width < MXC_JPEG_MAX_WIDTH) ? in mxc_jpeg_try_fmt()
2357 pix_mp->width : MXC_JPEG_MAX_WIDTH; in mxc_jpeg_try_fmt()
2358 u32 h = (pix_mp->height < MXC_JPEG_MAX_HEIGHT) ? in mxc_jpeg_try_fmt()
2359 pix_mp->height : MXC_JPEG_MAX_HEIGHT; in mxc_jpeg_try_fmt()
2363 if (!fmt || fmt->flags != mxc_jpeg_get_fmt_type(ctx, f->type)) { in mxc_jpeg_try_fmt()
2364 dev_warn(ctx->mxc_jpeg->dev, "Format not supported: %c%c%c%c, use the default.\n", in mxc_jpeg_try_fmt()
2369 fourcc = mxc_jpeg_get_default_fourcc(ctx, f->type); in mxc_jpeg_try_fmt()
2372 return -EINVAL; in mxc_jpeg_try_fmt()
2373 f->fmt.pix_mp.pixelformat = fourcc; in mxc_jpeg_try_fmt()
2375 q_data->fmt = fmt; in mxc_jpeg_try_fmt()
2377 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); in mxc_jpeg_try_fmt()
2378 pix_mp->field = V4L2_FIELD_NONE; in mxc_jpeg_try_fmt()
2379 pix_mp->num_planes = fmt->mem_planes; in mxc_jpeg_try_fmt()
2380 pix_mp->pixelformat = fmt->fourcc; in mxc_jpeg_try_fmt()
2382 q_data->w = w; in mxc_jpeg_try_fmt()
2383 q_data->h = h; in mxc_jpeg_try_fmt()
2384 q_data->w_adjusted = w; in mxc_jpeg_try_fmt()
2385 q_data->h_adjusted = h; in mxc_jpeg_try_fmt()
2386 v4l_bound_align_image(&q_data->w_adjusted, in mxc_jpeg_try_fmt()
2389 fmt->h_align, in mxc_jpeg_try_fmt()
2390 &q_data->h_adjusted, in mxc_jpeg_try_fmt()
2393 fmt->v_align, in mxc_jpeg_try_fmt()
2395 for (i = 0; i < pix_mp->num_planes; i++) { in mxc_jpeg_try_fmt()
2396 pfmt = &pix_mp->plane_fmt[i]; in mxc_jpeg_try_fmt()
2397 q_data->bytesperline[i] = pfmt->bytesperline; in mxc_jpeg_try_fmt()
2398 q_data->sizeimage[i] = pfmt->sizeimage; in mxc_jpeg_try_fmt()
2402 mxc_jpeg_bytesperline(q_data, fmt->precision); in mxc_jpeg_try_fmt()
2406 for (i = 0; i < pix_mp->num_planes; i++) { in mxc_jpeg_try_fmt()
2407 pfmt = &pix_mp->plane_fmt[i]; in mxc_jpeg_try_fmt()
2408 memset(pfmt->reserved, 0, sizeof(pfmt->reserved)); in mxc_jpeg_try_fmt()
2409 pfmt->bytesperline = q_data->bytesperline[i]; in mxc_jpeg_try_fmt()
2410 pfmt->sizeimage = mxc_jpeg_get_plane_size(q_data, i); in mxc_jpeg_try_fmt()
2414 pix_mp->colorspace = V4L2_COLORSPACE_SRGB; in mxc_jpeg_try_fmt()
2415 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601; in mxc_jpeg_try_fmt()
2416 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB; in mxc_jpeg_try_fmt()
2419 * but since inside JPEG the YUV quantization is full-range, in mxc_jpeg_try_fmt()
2420 * this driver will always use full-range for the raw frames, too in mxc_jpeg_try_fmt()
2422 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mxc_jpeg_try_fmt()
2424 if (fmt->flags == MXC_JPEG_FMT_TYPE_RAW) { in mxc_jpeg_try_fmt()
2425 q_data->crop.left = 0; in mxc_jpeg_try_fmt()
2426 q_data->crop.top = 0; in mxc_jpeg_try_fmt()
2427 q_data->crop.width = q_data->w; in mxc_jpeg_try_fmt()
2428 q_data->crop.height = q_data->h; in mxc_jpeg_try_fmt()
2431 pix_mp->width = q_data->w_adjusted; in mxc_jpeg_try_fmt()
2432 pix_mp->height = q_data->h_adjusted; in mxc_jpeg_try_fmt()
2441 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_try_fmt_vid_cap()
2442 struct device *dev = jpeg->dev; in mxc_jpeg_try_fmt_vid_cap()
2445 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { in mxc_jpeg_try_fmt_vid_cap()
2446 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type); in mxc_jpeg_try_fmt_vid_cap()
2447 return -EINVAL; in mxc_jpeg_try_fmt_vid_cap()
2450 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(f->type)) in mxc_jpeg_try_fmt_vid_cap()
2451 f->fmt.pix_mp.pixelformat = mxc_jpeg_try_fourcc(ctx, f->fmt.pix_mp.pixelformat); in mxc_jpeg_try_fmt_vid_cap()
2460 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_try_fmt_vid_out()
2461 struct device *dev = jpeg->dev; in mxc_jpeg_try_fmt_vid_out()
2464 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { in mxc_jpeg_try_fmt_vid_out()
2465 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type); in mxc_jpeg_try_fmt_vid_out()
2466 return -EINVAL; in mxc_jpeg_try_fmt_vid_out()
2474 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in mxc_jpeg_s_parsed_fmt()
2477 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE || !V4L2_TYPE_IS_CAPTURE(f->type)) in mxc_jpeg_s_parsed_fmt()
2479 if (!ctx->header_parsed) in mxc_jpeg_s_parsed_fmt()
2482 q_data_cap = mxc_jpeg_get_q_data(ctx, f->type); in mxc_jpeg_s_parsed_fmt()
2483 pix_mp->pixelformat = mxc_jpeg_try_fourcc(ctx, pix_mp->pixelformat); in mxc_jpeg_s_parsed_fmt()
2484 pix_mp->width = q_data_cap->w; in mxc_jpeg_s_parsed_fmt()
2485 pix_mp->height = q_data_cap->h; in mxc_jpeg_s_parsed_fmt()
2492 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_s_fmt()
2494 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in mxc_jpeg_s_fmt()
2496 return -EINVAL; in mxc_jpeg_s_fmt()
2499 v4l2_err(&jpeg->v4l2_dev, "queue busy\n"); in mxc_jpeg_s_fmt()
2500 return -EBUSY; in mxc_jpeg_s_fmt()
2505 return mxc_jpeg_try_fmt(f, ctx, mxc_jpeg_get_q_data(ctx, f->type)); in mxc_jpeg_s_fmt()
2528 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE) in mxc_jpeg_s_fmt_vid_out()
2531 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, cap_type); in mxc_jpeg_s_fmt_vid_out()
2533 return -EINVAL; in mxc_jpeg_s_fmt_vid_out()
2539 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()
2543 fc.fmt.pix_mp.pixelformat = q_data_cap->fmt->fourcc; in mxc_jpeg_s_fmt_vid_out()
2544 fc.fmt.pix_mp.width = f->fmt.pix_mp.width; in mxc_jpeg_s_fmt_vid_out()
2545 fc.fmt.pix_mp.height = f->fmt.pix_mp.height; in mxc_jpeg_s_fmt_vid_out()
2554 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; in mxc_jpeg_g_fmt_vid()
2555 struct device *dev = jpeg->dev; in mxc_jpeg_g_fmt_vid()
2556 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in mxc_jpeg_g_fmt_vid()
2557 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type); in mxc_jpeg_g_fmt_vid()
2560 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { in mxc_jpeg_g_fmt_vid()
2561 dev_err(dev, "G_FMT with Invalid type: %d\n", f->type); in mxc_jpeg_g_fmt_vid()
2562 return -EINVAL; in mxc_jpeg_g_fmt_vid()
2565 pix_mp->pixelformat = q_data->fmt->fourcc; in mxc_jpeg_g_fmt_vid()
2566 pix_mp->width = q_data->w; in mxc_jpeg_g_fmt_vid()
2567 pix_mp->height = q_data->h; in mxc_jpeg_g_fmt_vid()
2568 pix_mp->field = V4L2_FIELD_NONE; in mxc_jpeg_g_fmt_vid()
2569 if (q_data->fmt->flags == MXC_JPEG_FMT_TYPE_RAW) { in mxc_jpeg_g_fmt_vid()
2570 pix_mp->width = q_data->w_adjusted; in mxc_jpeg_g_fmt_vid()
2571 pix_mp->height = q_data->h_adjusted; in mxc_jpeg_g_fmt_vid()
2575 pix_mp->colorspace = V4L2_COLORSPACE_SRGB; in mxc_jpeg_g_fmt_vid()
2576 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601; in mxc_jpeg_g_fmt_vid()
2577 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB; in mxc_jpeg_g_fmt_vid()
2578 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mxc_jpeg_g_fmt_vid()
2580 pix_mp->num_planes = q_data->fmt->mem_planes; in mxc_jpeg_g_fmt_vid()
2581 for (i = 0; i < pix_mp->num_planes; i++) { in mxc_jpeg_g_fmt_vid()
2582 pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i]; in mxc_jpeg_g_fmt_vid()
2583 pix_mp->plane_fmt[i].sizeimage = mxc_jpeg_get_plane_size(q_data, i); in mxc_jpeg_g_fmt_vid()
2594 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in mxc_jpeg_dec_g_selection()
2595 return -EINVAL; in mxc_jpeg_dec_g_selection()
2597 q_data_cap = mxc_jpeg_get_q_data(ctx, s->type); in mxc_jpeg_dec_g_selection()
2599 switch (s->target) { in mxc_jpeg_dec_g_selection()
2602 s->r = q_data_cap->crop; in mxc_jpeg_dec_g_selection()
2606 s->r.left = 0; in mxc_jpeg_dec_g_selection()
2607 s->r.top = 0; in mxc_jpeg_dec_g_selection()
2608 s->r.width = q_data_cap->w_adjusted; in mxc_jpeg_dec_g_selection()
2609 s->r.height = q_data_cap->h_adjusted; in mxc_jpeg_dec_g_selection()
2612 return -EINVAL; in mxc_jpeg_dec_g_selection()
2623 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in mxc_jpeg_enc_g_selection()
2624 return -EINVAL; in mxc_jpeg_enc_g_selection()
2626 q_data_out = mxc_jpeg_get_q_data(ctx, s->type); in mxc_jpeg_enc_g_selection()
2628 switch (s->target) { in mxc_jpeg_enc_g_selection()
2631 s->r.left = 0; in mxc_jpeg_enc_g_selection()
2632 s->r.top = 0; in mxc_jpeg_enc_g_selection()
2633 s->r.width = q_data_out->w; in mxc_jpeg_enc_g_selection()
2634 s->r.height = q_data_out->h; in mxc_jpeg_enc_g_selection()
2637 s->r = q_data_out->crop; in mxc_jpeg_enc_g_selection()
2640 return -EINVAL; in mxc_jpeg_enc_g_selection()
2650 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_g_selection()
2661 if (ctx->mxc_jpeg->mode != MXC_JPEG_ENCODE) in mxc_jpeg_s_selection()
2662 return -ENOTTY; in mxc_jpeg_s_selection()
2664 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in mxc_jpeg_s_selection()
2665 return -EINVAL; in mxc_jpeg_s_selection()
2666 if (s->target != V4L2_SEL_TGT_CROP) in mxc_jpeg_s_selection()
2667 return -EINVAL; in mxc_jpeg_s_selection()
2669 q_data_out = mxc_jpeg_get_q_data(ctx, s->type); in mxc_jpeg_s_selection()
2670 if (s->r.left || s->r.top) in mxc_jpeg_s_selection()
2671 return -EINVAL; in mxc_jpeg_s_selection()
2672 if (s->r.width > q_data_out->w || s->r.height > q_data_out->h) in mxc_jpeg_s_selection()
2673 return -EINVAL; in mxc_jpeg_s_selection()
2675 q_data_out->crop.left = 0; in mxc_jpeg_s_selection()
2676 q_data_out->crop.top = 0; in mxc_jpeg_s_selection()
2677 q_data_out->crop.width = s->r.width; in mxc_jpeg_s_selection()
2678 q_data_out->crop.height = s->r.height; in mxc_jpeg_s_selection()
2686 switch (sub->type) { in mxc_jpeg_subscribe_event()
2694 return -EINVAL; in mxc_jpeg_subscribe_event()
2738 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data); in mxc_jpeg_release()
2739 struct device *dev = mxc_jpeg->dev; in mxc_jpeg_release()
2741 mutex_lock(&mxc_jpeg->lock); in mxc_jpeg_release()
2742 if (mxc_jpeg->mode == MXC_JPEG_DECODE) in mxc_jpeg_release()
2744 ctx->slot); in mxc_jpeg_release()
2747 ctx->slot); in mxc_jpeg_release()
2748 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in mxc_jpeg_release()
2749 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in mxc_jpeg_release()
2750 v4l2_fh_del(&ctx->fh); in mxc_jpeg_release()
2751 v4l2_fh_exit(&ctx->fh); in mxc_jpeg_release()
2753 mutex_unlock(&mxc_jpeg->lock); in mxc_jpeg_release()
2776 for (i = 0; i < jpeg->num_domains; i++) { in mxc_jpeg_detach_pm_domains()
2777 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) && in mxc_jpeg_detach_pm_domains()
2778 !pm_runtime_suspended(jpeg->pd_dev[i])) in mxc_jpeg_detach_pm_domains()
2779 pm_runtime_force_suspend(jpeg->pd_dev[i]); in mxc_jpeg_detach_pm_domains()
2780 if (!IS_ERR_OR_NULL(jpeg->pd_link[i])) in mxc_jpeg_detach_pm_domains()
2781 device_link_del(jpeg->pd_link[i]); in mxc_jpeg_detach_pm_domains()
2782 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i])) in mxc_jpeg_detach_pm_domains()
2783 dev_pm_domain_detach(jpeg->pd_dev[i], true); in mxc_jpeg_detach_pm_domains()
2784 jpeg->pd_dev[i] = NULL; in mxc_jpeg_detach_pm_domains()
2785 jpeg->pd_link[i] = NULL; in mxc_jpeg_detach_pm_domains()
2791 struct device *dev = jpeg->dev; in mxc_jpeg_attach_pm_domains()
2792 struct device_node *np = jpeg->pdev->dev.of_node; in mxc_jpeg_attach_pm_domains()
2796 jpeg->num_domains = of_count_phandle_with_args(np, "power-domains", in mxc_jpeg_attach_pm_domains()
2797 "#power-domain-cells"); in mxc_jpeg_attach_pm_domains()
2798 if (jpeg->num_domains < 0) { in mxc_jpeg_attach_pm_domains()
2800 return jpeg->num_domains; in mxc_jpeg_attach_pm_domains()
2802 if (jpeg->num_domains == 1) { in mxc_jpeg_attach_pm_domains()
2804 jpeg->num_domains = 0; in mxc_jpeg_attach_pm_domains()
2808 jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains, in mxc_jpeg_attach_pm_domains()
2809 sizeof(*jpeg->pd_dev), GFP_KERNEL); in mxc_jpeg_attach_pm_domains()
2810 if (!jpeg->pd_dev) in mxc_jpeg_attach_pm_domains()
2811 return -ENOMEM; in mxc_jpeg_attach_pm_domains()
2813 jpeg->pd_link = devm_kmalloc_array(dev, jpeg->num_domains, in mxc_jpeg_attach_pm_domains()
2814 sizeof(*jpeg->pd_link), GFP_KERNEL); in mxc_jpeg_attach_pm_domains()
2815 if (!jpeg->pd_link) in mxc_jpeg_attach_pm_domains()
2816 return -ENOMEM; in mxc_jpeg_attach_pm_domains()
2818 for (i = 0; i < jpeg->num_domains; i++) { in mxc_jpeg_attach_pm_domains()
2819 jpeg->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i); in mxc_jpeg_attach_pm_domains()
2820 if (IS_ERR(jpeg->pd_dev[i])) { in mxc_jpeg_attach_pm_domains()
2821 ret = PTR_ERR(jpeg->pd_dev[i]); in mxc_jpeg_attach_pm_domains()
2825 jpeg->pd_link[i] = device_link_add(dev, jpeg->pd_dev[i], in mxc_jpeg_attach_pm_domains()
2828 if (!jpeg->pd_link[i]) { in mxc_jpeg_attach_pm_domains()
2829 ret = -EINVAL; in mxc_jpeg_attach_pm_domains()
2843 struct device *dev = &pdev->dev; in mxc_jpeg_probe()
2849 of_id = of_match_node(mxc_jpeg_match, dev->of_node); in mxc_jpeg_probe()
2851 return -ENODEV; in mxc_jpeg_probe()
2852 mode = *(const int *)of_id->data; in mxc_jpeg_probe()
2856 return -ENOMEM; in mxc_jpeg_probe()
2858 mutex_init(&jpeg->lock); in mxc_jpeg_probe()
2859 spin_lock_init(&jpeg->hw_lock); in mxc_jpeg_probe()
2863 dev_err(&pdev->dev, "No suitable DMA available.\n"); in mxc_jpeg_probe()
2867 jpeg->base_reg = devm_platform_ioremap_resource(pdev, 0); in mxc_jpeg_probe()
2868 if (IS_ERR(jpeg->base_reg)) in mxc_jpeg_probe()
2869 return PTR_ERR(jpeg->base_reg); in mxc_jpeg_probe()
2871 ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot); in mxc_jpeg_probe()
2873 jpeg->slot_data.slot = 0; in mxc_jpeg_probe()
2874 dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); in mxc_jpeg_probe()
2880 ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, in mxc_jpeg_probe()
2881 0, pdev->name, jpeg); in mxc_jpeg_probe()
2883 dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", in mxc_jpeg_probe()
2888 jpeg->pdev = pdev; in mxc_jpeg_probe()
2889 jpeg->dev = dev; in mxc_jpeg_probe()
2890 jpeg->mode = mode; in mxc_jpeg_probe()
2893 ret = devm_clk_bulk_get_all(&pdev->dev, &jpeg->clks); in mxc_jpeg_probe()
2898 jpeg->num_clks = ret; in mxc_jpeg_probe()
2907 ret = v4l2_device_register(dev, &jpeg->v4l2_dev); in mxc_jpeg_probe()
2912 jpeg->m2m_dev = v4l2_m2m_init(&mxc_jpeg_m2m_ops); in mxc_jpeg_probe()
2913 if (IS_ERR(jpeg->m2m_dev)) { in mxc_jpeg_probe()
2915 ret = PTR_ERR(jpeg->m2m_dev); in mxc_jpeg_probe()
2919 jpeg->dec_vdev = video_device_alloc(); in mxc_jpeg_probe()
2920 if (!jpeg->dec_vdev) { in mxc_jpeg_probe()
2922 ret = -ENOMEM; in mxc_jpeg_probe()
2926 snprintf(jpeg->dec_vdev->name, in mxc_jpeg_probe()
2927 sizeof(jpeg->dec_vdev->name), in mxc_jpeg_probe()
2928 "%s-enc", MXC_JPEG_NAME); in mxc_jpeg_probe()
2930 snprintf(jpeg->dec_vdev->name, in mxc_jpeg_probe()
2931 sizeof(jpeg->dec_vdev->name), in mxc_jpeg_probe()
2932 "%s-dec", MXC_JPEG_NAME); in mxc_jpeg_probe()
2934 jpeg->dec_vdev->fops = &mxc_jpeg_fops; in mxc_jpeg_probe()
2935 jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops; in mxc_jpeg_probe()
2936 jpeg->dec_vdev->minor = -1; in mxc_jpeg_probe()
2937 jpeg->dec_vdev->release = video_device_release; in mxc_jpeg_probe()
2938 jpeg->dec_vdev->lock = &jpeg->lock; /* lock for ioctl serialization */ in mxc_jpeg_probe()
2939 jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev; in mxc_jpeg_probe()
2940 jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M; in mxc_jpeg_probe()
2941 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING | in mxc_jpeg_probe()
2943 video_set_drvdata(jpeg->dec_vdev, jpeg); in mxc_jpeg_probe()
2945 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD); in mxc_jpeg_probe()
2946 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD); in mxc_jpeg_probe()
2948 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_ENCODER_CMD); in mxc_jpeg_probe()
2949 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_ENCODER_CMD); in mxc_jpeg_probe()
2951 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_VIDEO, -1); in mxc_jpeg_probe()
2957 v4l2_info(&jpeg->v4l2_dev, in mxc_jpeg_probe()
2959 jpeg->dec_vdev->num, VIDEO_MAJOR, in mxc_jpeg_probe()
2960 jpeg->dec_vdev->minor); in mxc_jpeg_probe()
2962 v4l2_info(&jpeg->v4l2_dev, in mxc_jpeg_probe()
2964 jpeg->dec_vdev->num, VIDEO_MAJOR, in mxc_jpeg_probe()
2965 jpeg->dec_vdev->minor); in mxc_jpeg_probe()
2973 video_device_release(jpeg->dec_vdev); in mxc_jpeg_probe()
2976 v4l2_m2m_release(jpeg->m2m_dev); in mxc_jpeg_probe()
2979 v4l2_device_unregister(&jpeg->v4l2_dev); in mxc_jpeg_probe()
2994 ret = clk_bulk_prepare_enable(jpeg->num_clks, jpeg->clks); in mxc_jpeg_runtime_resume()
3007 clk_bulk_disable_unprepare(jpeg->num_clks, jpeg->clks); in mxc_jpeg_runtime_suspend()
3016 v4l2_m2m_suspend(jpeg->m2m_dev); in mxc_jpeg_suspend()
3029 v4l2_m2m_resume(jpeg->m2m_dev); in mxc_jpeg_resume()
3044 pm_runtime_disable(&pdev->dev); in mxc_jpeg_remove()
3045 video_unregister_device(jpeg->dec_vdev); in mxc_jpeg_remove()
3046 v4l2_m2m_release(jpeg->m2m_dev); in mxc_jpeg_remove()
3047 v4l2_device_unregister(&jpeg->v4l2_dev); in mxc_jpeg_remove()
3057 .name = "mxc-jpeg",