Lines Matching +full:de +full:- +full:interlacing
1 // SPDX-License-Identifier: GPL-2.0-only
3 * TI VPE mem2mem driver, based on the virtual v4l2-mem2mem example driver
10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
14 * Based on the virtual v4l2-mem2mem example device
18 #include <linux/dma-mapping.h>
34 #include <media/v4l2-common.h>
35 #include <media/v4l2-ctrls.h>
36 #include <media/v4l2-device.h>
37 #include <media/v4l2-event.h>
38 #include <media/v4l2-ioctl.h>
39 #include <media/v4l2-mem2mem.h>
40 #include <media/videobuf2-v4l2.h>
41 #include <media/videobuf2-dma-contig.h>
71 #define VPE_MAX_SRC_BUFS 3 /* need 3 src fields to de-interlace */
83 dev_dbg((vpedev)->v4l2_dev.dev, fmt, ##arg)
85 dev_err((vpedev)->v4l2_dev.dev, fmt, ##arg)
150 * The port_data structure contains per-port data.
154 u8 vb_index; /* input frame f, f-1, f-2 index */
155 u8 vb_part; /* plane index for co-panar formats */
318 * per-queue, driver-specific private data.
356 if (fmt->fourcc == fourcc) in __find_format()
365 return __find_format(f->fmt.pix.pixelformat); in find_format()
419 bool deinterlacing; /* using de-interlacer */
436 return &ctx->q_data[Q_DATA_SRC]; in get_q_data()
439 return &ctx->q_data[Q_DATA_DST]; in get_q_data()
448 return ioread32(dev->base + offset); in read_reg()
453 iowrite32(value, dev->base + offset); in write_reg()
516 ((obj)->res->start - ctx->dev->res->start + reg)
519 VPDMA_SET_MMR_ADB_HDR(ctx->mmr_adb, vpe_mmr_adb, hdr, regs, offset_a)
531 GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC0)); in init_adb_hdrs()
533 GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC8)); in init_adb_hdrs()
535 GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC17)); in init_adb_hdrs()
537 GET_OFFSET_TOP(ctx, ctx->dev->csc, CSC_CSC00)); in init_adb_hdrs()
541 * Allocate or re-allocate the motion vector DMA buffers
549 struct device *dev = ctx->dev->v4l2_dev.dev; in realloc_mv_buffers()
551 if (ctx->mv_buf_size == size) in realloc_mv_buffers()
554 if (ctx->mv_buf[0]) in realloc_mv_buffers()
555 dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[0], in realloc_mv_buffers()
556 ctx->mv_buf_dma[0]); in realloc_mv_buffers()
558 if (ctx->mv_buf[1]) in realloc_mv_buffers()
559 dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[1], in realloc_mv_buffers()
560 ctx->mv_buf_dma[1]); in realloc_mv_buffers()
565 ctx->mv_buf[0] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[0], in realloc_mv_buffers()
567 if (!ctx->mv_buf[0]) { in realloc_mv_buffers()
568 vpe_err(ctx->dev, "failed to allocate motion vector buffer\n"); in realloc_mv_buffers()
569 return -ENOMEM; in realloc_mv_buffers()
572 ctx->mv_buf[1] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[1], in realloc_mv_buffers()
574 if (!ctx->mv_buf[1]) { in realloc_mv_buffers()
575 vpe_err(ctx->dev, "failed to allocate motion vector buffer\n"); in realloc_mv_buffers()
576 dma_free_coherent(dev, size, ctx->mv_buf[0], in realloc_mv_buffers()
577 ctx->mv_buf_dma[0]); in realloc_mv_buffers()
579 return -ENOMEM; in realloc_mv_buffers()
582 ctx->mv_buf_size = size; in realloc_mv_buffers()
583 ctx->src_mv_buf_selector = 0; in realloc_mv_buffers()
594 * While de-interlacing, we keep the two most recent input buffers
600 struct vpe_dev *dev = ctx->dev; in free_vbs()
603 if (ctx->src_vbs[2] == NULL) in free_vbs()
606 spin_lock_irqsave(&dev->lock, flags); in free_vbs()
607 if (ctx->src_vbs[2]) { in free_vbs()
608 v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_DONE); in free_vbs()
609 if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2])) in free_vbs()
610 v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE); in free_vbs()
611 ctx->src_vbs[2] = NULL; in free_vbs()
612 ctx->src_vbs[1] = NULL; in free_vbs()
614 spin_unlock_irqrestore(&dev->lock, flags); in free_vbs()
657 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; in set_us_coefficients()
658 struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; in set_us_coefficients()
659 u32 *us1_reg = &mmr_adb->us1_regs[0]; in set_us_coefficients()
660 u32 *us2_reg = &mmr_adb->us2_regs[0]; in set_us_coefficients()
661 u32 *us3_reg = &mmr_adb->us3_regs[0]; in set_us_coefficients()
666 if (s_q_data->flags & Q_IS_INTERLACED) /* interlaced */ in set_us_coefficients()
677 ctx->load_mmrs = true; in set_us_coefficients()
685 struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt; in set_cfg_modes()
686 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; in set_cfg_modes()
687 u32 *us1_reg0 = &mmr_adb->us1_regs[0]; in set_cfg_modes()
688 u32 *us2_reg0 = &mmr_adb->us2_regs[0]; in set_cfg_modes()
689 u32 *us3_reg0 = &mmr_adb->us3_regs[0]; in set_cfg_modes()
693 * Cfg Mode 0: YUV420 source, enable upsampler, DEI is de-interlacing. in set_cfg_modes()
694 * Cfg Mode 1: YUV422 source, disable upsampler, DEI is de-interlacing. in set_cfg_modes()
697 if (fmt->fourcc == V4L2_PIX_FMT_NV12 || in set_cfg_modes()
698 fmt->fourcc == V4L2_PIX_FMT_NV21) in set_cfg_modes()
705 ctx->load_mmrs = true; in set_cfg_modes()
710 struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt; in set_line_modes()
713 if (fmt->fourcc == V4L2_PIX_FMT_NV12 || in set_line_modes()
714 fmt->fourcc == V4L2_PIX_FMT_NV21) in set_line_modes()
718 vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA1_IN); in set_line_modes()
719 vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA2_IN); in set_line_modes()
720 vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA3_IN); in set_line_modes()
723 vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, in set_line_modes()
725 vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, in set_line_modes()
727 vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, in set_line_modes()
731 vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, in set_line_modes()
733 vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, in set_line_modes()
735 vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, in set_line_modes()
739 vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, in set_line_modes()
758 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; in set_dst_registers()
759 struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt; in set_dst_registers()
763 finfo = v4l2_format_info(fmt->fourcc); in set_dst_registers()
766 vpdma_set_bg_color(ctx->dev->vpdma, in set_dst_registers()
767 (struct vpdma_data_format *)fmt->vpdma_fmt[0], 0xff); in set_dst_registers()
768 } else if (fmt->fourcc == V4L2_PIX_FMT_NV16) in set_dst_registers()
777 if (fmt->fourcc != V4L2_PIX_FMT_NV12 && in set_dst_registers()
778 fmt->fourcc != V4L2_PIX_FMT_NV21) in set_dst_registers()
781 mmr_adb->out_fmt_reg[0] = val; in set_dst_registers()
783 ctx->load_mmrs = true; in set_dst_registers()
787 * Set the de-interlacer shadow register values
791 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; in set_dei_regs()
792 struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; in set_dei_regs()
793 unsigned int src_h = s_q_data->c_rect.height; in set_dei_regs()
794 unsigned int src_w = s_q_data->c_rect.width; in set_dei_regs()
795 u32 *dei_mmr0 = &mmr_adb->dei_regs[0]; in set_dei_regs()
805 if (!(s_q_data->flags & Q_IS_INTERLACED) || !ctx->deinterlacing) { in set_dei_regs()
818 ctx->load_mmrs = true; in set_dei_regs()
823 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; in set_dei_shadow_registers()
824 u32 *dei_mmr = &mmr_adb->dei_regs[0]; in set_dei_shadow_registers()
827 dei_mmr[2] = cur->mdt_spacial_freq_thr_reg; in set_dei_shadow_registers()
828 dei_mmr[3] = cur->edi_config_reg; in set_dei_shadow_registers()
829 dei_mmr[4] = cur->edi_lut_reg0; in set_dei_shadow_registers()
830 dei_mmr[5] = cur->edi_lut_reg1; in set_dei_shadow_registers()
831 dei_mmr[6] = cur->edi_lut_reg2; in set_dei_shadow_registers()
832 dei_mmr[7] = cur->edi_lut_reg3; in set_dei_shadow_registers()
834 ctx->load_mmrs = true; in set_dei_shadow_registers()
839 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; in config_edi_input_mode()
840 u32 *edi_config_reg = &mmr_adb->dei_regs[3]; in config_edi_input_mode()
851 ctx->load_mmrs = true; in config_edi_input_mode()
860 struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; in set_srcdst_params()
861 struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; in set_srcdst_params()
862 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; in set_srcdst_params()
863 unsigned int src_w = s_q_data->c_rect.width; in set_srcdst_params()
864 unsigned int src_h = s_q_data->c_rect.height; in set_srcdst_params()
865 unsigned int dst_w = d_q_data->c_rect.width; in set_srcdst_params()
866 unsigned int dst_h = d_q_data->c_rect.height; in set_srcdst_params()
871 ctx->sequence = 0; in set_srcdst_params()
872 ctx->field = V4L2_FIELD_TOP; in set_srcdst_params()
873 spix = &s_q_data->format.fmt.pix_mp; in set_srcdst_params()
875 if ((s_q_data->flags & Q_IS_INTERLACED) && in set_srcdst_params()
876 !(d_q_data->flags & Q_IS_INTERLACED)) { in set_srcdst_params()
885 * extra space will not be used by the de-interlacer, but will in set_srcdst_params()
888 bytes_per_line = ALIGN((spix->width * mv->depth) >> 3, in set_srcdst_params()
890 mv_buf_size = bytes_per_line * spix->height; in set_srcdst_params()
892 ctx->deinterlacing = true; in set_srcdst_params()
895 ctx->deinterlacing = false; in set_srcdst_params()
900 ctx->src_vbs[2] = ctx->src_vbs[1] = ctx->src_vbs[0] = NULL; in set_srcdst_params()
909 csc_set_coeff(ctx->dev->csc, &mmr_adb->csc_regs[0], in set_srcdst_params()
910 &s_q_data->format, &d_q_data->format); in set_srcdst_params()
912 sc_set_hs_coeffs(ctx->dev->sc, ctx->sc_coeff_h.addr, src_w, dst_w); in set_srcdst_params()
913 sc_set_vs_coeffs(ctx->dev->sc, ctx->sc_coeff_v.addr, src_h, dst_h); in set_srcdst_params()
915 sc_config_scaler(ctx->dev->sc, &mmr_adb->sc_regs0[0], in set_srcdst_params()
916 &mmr_adb->sc_regs8[0], &mmr_adb->sc_regs17[0], in set_srcdst_params()
927 * job_ready() - check whether an instance is ready to be scheduled to run
938 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) <= 0 || in job_ready()
939 v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) <= 0) in job_ready()
950 ctx->aborting = 1; in job_abort()
955 #define DUMPREG(r) vpe_dbg(dev, "%-35s %08x\n", #r, read_reg(dev, VPE_##r)) in vpe_dump_regs()
1012 sc_dump_regs(dev->sc); in vpe_dump_regs()
1013 csc_dump_regs(dev->csc); in vpe_dump_regs()
1018 struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST]; in add_out_dtd()
1020 struct vb2_buffer *vb = &ctx->dst_vb->vb2_buf; in add_out_dtd()
1021 struct vpe_fmt *fmt = q_data->fmt; in add_out_dtd()
1023 int mv_buf_selector = !ctx->src_mv_buf_selector; in add_out_dtd()
1032 dma_addr = ctx->mv_buf_dma[mv_buf_selector]; in add_out_dtd()
1033 q_data = &ctx->q_data[Q_DATA_SRC]; in add_out_dtd()
1034 pix = &q_data->format.fmt.pix_mp; in add_out_dtd()
1035 stride = ALIGN((pix->width * vpdma_fmt->depth) >> 3, in add_out_dtd()
1039 int plane = fmt->coplanar ? p_data->vb_part : 0; in add_out_dtd()
1041 pix = &q_data->format.fmt.pix_mp; in add_out_dtd()
1042 vpdma_fmt = fmt->vpdma_fmt[plane]; in add_out_dtd()
1047 if (pix->num_planes == 1 && plane) { in add_out_dtd()
1050 offset = pix->plane_fmt[0].bytesperline * pix->height; in add_out_dtd()
1057 vpe_err(ctx->dev, in add_out_dtd()
1064 stride = pix->plane_fmt[VPE_LUMA].bytesperline; in add_out_dtd()
1067 if (q_data->flags & Q_DATA_FRAME_1D) in add_out_dtd()
1069 if (q_data->flags & Q_DATA_MODE_TILED) in add_out_dtd()
1072 vpdma_set_max_size(ctx->dev->vpdma, VPDMA_MAX_SIZE1, in add_out_dtd()
1075 vpdma_add_out_dtd(&ctx->desc_list, pix->width, in add_out_dtd()
1076 stride, &q_data->c_rect, in add_out_dtd()
1078 MAX_OUT_HEIGHT_REG1, p_data->channel, flags); in add_out_dtd()
1083 struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC]; in add_in_dtd()
1085 struct vb2_buffer *vb = &ctx->src_vbs[p_data->vb_index]->vb2_buf; in add_in_dtd()
1087 struct vpe_fmt *fmt = q_data->fmt; in add_in_dtd()
1090 int mv_buf_selector = ctx->src_mv_buf_selector; in add_in_dtd()
1091 int field = vbuf->field == V4L2_FIELD_BOTTOM; in add_in_dtd()
1098 pix = &q_data->format.fmt.pix_mp; in add_in_dtd()
1101 dma_addr = ctx->mv_buf_dma[mv_buf_selector]; in add_in_dtd()
1102 stride = ALIGN((pix->width * vpdma_fmt->depth) >> 3, in add_in_dtd()
1106 int plane = fmt->coplanar ? p_data->vb_part : 0; in add_in_dtd()
1108 vpdma_fmt = fmt->vpdma_fmt[plane]; in add_in_dtd()
1113 if (pix->num_planes == 1 && plane) { in add_in_dtd()
1116 offset = pix->plane_fmt[0].bytesperline * pix->height; in add_in_dtd()
1123 vpe_err(ctx->dev, in add_in_dtd()
1130 stride = pix->plane_fmt[VPE_LUMA].bytesperline; in add_in_dtd()
1135 * For each de-interlacing operation, f,f-1,f-2 should be one in add_in_dtd()
1138 if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB || in add_in_dtd()
1139 q_data->flags & Q_DATA_INTERLACED_SEQ_BT) { in add_in_dtd()
1141 if (q_data->flags & Q_DATA_INTERLACED_SEQ_BT) in add_in_dtd()
1147 field = (field + p_data->vb_index + ctx->sequence) % 2; in add_in_dtd()
1150 int height = pix->height / 2; in add_in_dtd()
1153 if (fmt->fourcc == V4L2_PIX_FMT_NV12 || in add_in_dtd()
1154 fmt->fourcc == V4L2_PIX_FMT_NV21) in add_in_dtd()
1157 bpp = vpdma_fmt->depth >> 3; in add_in_dtd()
1162 dma_addr += pix->width * height * bpp; in add_in_dtd()
1167 if (q_data->flags & Q_DATA_FRAME_1D) in add_in_dtd()
1169 if (q_data->flags & Q_DATA_MODE_TILED) in add_in_dtd()
1172 frame_width = q_data->c_rect.width; in add_in_dtd()
1173 frame_height = q_data->c_rect.height; in add_in_dtd()
1175 if (p_data->vb_part && (fmt->fourcc == V4L2_PIX_FMT_NV12 || in add_in_dtd()
1176 fmt->fourcc == V4L2_PIX_FMT_NV21)) in add_in_dtd()
1179 vpdma_add_in_dtd(&ctx->desc_list, pix->width, stride, in add_in_dtd()
1180 &q_data->c_rect, vpdma_fmt, dma_addr, in add_in_dtd()
1181 p_data->channel, field, flags, frame_width, in add_in_dtd()
1190 write_reg(ctx->dev, VPE_INT0_ENABLE0_SET, VPE_INT0_LIST0_COMPLETE); in enable_irqs()
1191 write_reg(ctx->dev, VPE_INT0_ENABLE1_SET, VPE_DEI_ERROR_INT | in enable_irqs()
1194 vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, true); in enable_irqs()
1199 write_reg(ctx->dev, VPE_INT0_ENABLE0_CLR, 0xffffffff); in disable_irqs()
1200 write_reg(ctx->dev, VPE_INT0_ENABLE1_CLR, 0xffffffff); in disable_irqs()
1202 vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, false); in disable_irqs()
1205 /* device_run() - prepares and starts the device
1213 struct sc_data *sc = ctx->dev->sc; in device_run()
1214 struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; in device_run()
1215 struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; in device_run()
1218 d_finfo = v4l2_format_info(d_q_data->fmt->fourcc); in device_run()
1220 if (ctx->deinterlacing && s_q_data->flags & Q_IS_SEQ_XX && in device_run()
1221 ctx->sequence % 2 == 0) { in device_run()
1225 * Alternate between two operations:- in device_run()
1229 ctx->src_vbs[0] = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in device_run()
1230 WARN_ON(ctx->src_vbs[0] == NULL); in device_run()
1232 ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in device_run()
1233 WARN_ON(ctx->src_vbs[0] == NULL); in device_run()
1236 ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in device_run()
1237 WARN_ON(ctx->dst_vb == NULL); in device_run()
1239 if (ctx->deinterlacing) { in device_run()
1241 if (ctx->src_vbs[2] == NULL) { in device_run()
1242 ctx->src_vbs[2] = ctx->src_vbs[0]; in device_run()
1243 WARN_ON(ctx->src_vbs[2] == NULL); in device_run()
1244 ctx->src_vbs[1] = ctx->src_vbs[0]; in device_run()
1245 WARN_ON(ctx->src_vbs[1] == NULL); in device_run()
1250 * now switch to EDI de-interlacer in device_run()
1252 if (ctx->sequence == 2) in device_run()
1257 if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) { in device_run()
1258 vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb); in device_run()
1259 vpdma_add_cfd_adb(&ctx->desc_list, CFD_MMR_CLIENT, &ctx->mmr_adb); in device_run()
1263 ctx->dev->loaded_mmrs = ctx->mmr_adb.dma_addr; in device_run()
1264 ctx->load_mmrs = false; in device_run()
1267 if (sc->loaded_coeff_h != ctx->sc_coeff_h.dma_addr || in device_run()
1268 sc->load_coeff_h) { in device_run()
1269 vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_h); in device_run()
1270 vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT, in device_run()
1271 &ctx->sc_coeff_h, 0); in device_run()
1273 sc->loaded_coeff_h = ctx->sc_coeff_h.dma_addr; in device_run()
1274 sc->load_coeff_h = false; in device_run()
1277 if (sc->loaded_coeff_v != ctx->sc_coeff_v.dma_addr || in device_run()
1278 sc->load_coeff_v) { in device_run()
1279 vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_v); in device_run()
1280 vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT, in device_run()
1281 &ctx->sc_coeff_v, SC_COEF_SRAM_SIZE >> 4); in device_run()
1283 sc->loaded_coeff_v = ctx->sc_coeff_v.dma_addr; in device_run()
1284 sc->load_coeff_v = false; in device_run()
1288 if (ctx->deinterlacing) in device_run()
1295 if (d_q_data->fmt->coplanar) in device_run()
1300 if (ctx->deinterlacing) { in device_run()
1311 if (ctx->deinterlacing) in device_run()
1315 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA1_IN); in device_run()
1316 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA1_IN); in device_run()
1318 if (ctx->deinterlacing) { in device_run()
1319 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, in device_run()
1321 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, in device_run()
1324 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, in device_run()
1326 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, in device_run()
1329 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_IN); in device_run()
1334 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, in device_run()
1337 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, in device_run()
1339 if (d_q_data->fmt->coplanar) in device_run()
1340 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, in device_run()
1344 if (ctx->deinterlacing) in device_run()
1345 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT); in device_run()
1349 vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->desc_list.buf); in device_run()
1350 vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list, 0); in device_run()
1355 dev_warn(ctx->dev->v4l2_dev.dev, in dei_error()
1361 dev_warn(ctx->dev->v4l2_dev.dev, in ds1_uv_error()
1387 ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); in vpe_irq()
1406 vpdma_clear_list_stat(ctx->dev->vpdma, 0, 0); in vpe_irq()
1413 …dev_warn(dev->v4l2_dev.dev, "Unexpected interrupt: INT0_STATUS0 = 0x%08x, INT0_STATUS1 = 0x%08x\n", in vpe_irq()
1426 vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf); in vpe_irq()
1427 vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb); in vpe_irq()
1428 vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h); in vpe_irq()
1429 vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v); in vpe_irq()
1431 vpdma_reset_desc_list(&ctx->desc_list); in vpe_irq()
1434 ctx->src_mv_buf_selector = !ctx->src_mv_buf_selector; in vpe_irq()
1436 s_vb = ctx->src_vbs[0]; in vpe_irq()
1437 d_vb = ctx->dst_vb; in vpe_irq()
1439 d_vb->flags = s_vb->flags; in vpe_irq()
1440 d_vb->vb2_buf.timestamp = s_vb->vb2_buf.timestamp; in vpe_irq()
1442 if (s_vb->flags & V4L2_BUF_FLAG_TIMECODE) in vpe_irq()
1443 d_vb->timecode = s_vb->timecode; in vpe_irq()
1445 d_vb->sequence = ctx->sequence; in vpe_irq()
1446 s_vb->sequence = ctx->sequence; in vpe_irq()
1448 d_q_data = &ctx->q_data[Q_DATA_DST]; in vpe_irq()
1449 if (d_q_data->flags & Q_IS_INTERLACED) { in vpe_irq()
1450 d_vb->field = ctx->field; in vpe_irq()
1451 if (ctx->field == V4L2_FIELD_BOTTOM) { in vpe_irq()
1452 ctx->sequence++; in vpe_irq()
1453 ctx->field = V4L2_FIELD_TOP; in vpe_irq()
1455 WARN_ON(ctx->field != V4L2_FIELD_TOP); in vpe_irq()
1456 ctx->field = V4L2_FIELD_BOTTOM; in vpe_irq()
1459 d_vb->field = V4L2_FIELD_NONE; in vpe_irq()
1460 ctx->sequence++; in vpe_irq()
1463 if (ctx->deinterlacing) { in vpe_irq()
1469 * This ensures that driver will keep (n-2)th (n-1)th and (n)th in vpe_irq()
1472 if (ctx->src_vbs[2] != ctx->src_vbs[1]) in vpe_irq()
1473 s_vb = ctx->src_vbs[2]; in vpe_irq()
1478 spin_lock_irqsave(&dev->lock, flags); in vpe_irq()
1485 spin_unlock_irqrestore(&dev->lock, flags); in vpe_irq()
1487 if (ctx->deinterlacing) { in vpe_irq()
1488 ctx->src_vbs[2] = ctx->src_vbs[1]; in vpe_irq()
1489 ctx->src_vbs[1] = ctx->src_vbs[0]; in vpe_irq()
1497 ctx->src_vbs[0] = NULL; in vpe_irq()
1498 ctx->dst_vb = NULL; in vpe_irq()
1500 if (ctx->aborting) in vpe_irq()
1503 ctx->bufs_completed++; in vpe_irq()
1504 if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) { in vpe_irq()
1510 vpe_dbg(ctx->dev, "finishing transaction\n"); in vpe_irq()
1511 ctx->bufs_completed = 0; in vpe_irq()
1512 v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx); in vpe_irq()
1523 strscpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver)); in vpe_querycap()
1524 strscpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card)); in vpe_querycap()
1525 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", in vpe_querycap()
1538 if (index == f->index) { in __enum_fmt()
1547 return -EINVAL; in __enum_fmt()
1549 f->pixelformat = fmt->fourcc; in __enum_fmt()
1556 if (V4L2_TYPE_IS_OUTPUT(f->type)) in vpe_enum_fmt()
1564 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; in vpe_g_fmt()
1565 struct vpe_ctx *ctx = file->private_data; in vpe_g_fmt()
1569 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in vpe_g_fmt()
1571 return -EINVAL; in vpe_g_fmt()
1573 q_data = get_q_data(ctx, f->type); in vpe_g_fmt()
1575 return -EINVAL; in vpe_g_fmt()
1577 *f = q_data->format; in vpe_g_fmt()
1579 if (V4L2_TYPE_IS_CAPTURE(f->type)) { in vpe_g_fmt()
1585 spix = &s_q_data->format.fmt.pix_mp; in vpe_g_fmt()
1587 pix->colorspace = spix->colorspace; in vpe_g_fmt()
1588 pix->xfer_func = spix->xfer_func; in vpe_g_fmt()
1589 pix->ycbcr_enc = spix->ycbcr_enc; in vpe_g_fmt()
1590 pix->quantization = spix->quantization; in vpe_g_fmt()
1599 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; in __vpe_try_fmt()
1606 if (!fmt || !(fmt->types & type)) { in __vpe_try_fmt()
1607 vpe_dbg(ctx->dev, "Fourcc format (0x%08x) invalid.\n", in __vpe_try_fmt()
1608 pix->pixelformat); in __vpe_try_fmt()
1612 if (pix->field != V4L2_FIELD_NONE && in __vpe_try_fmt()
1613 pix->field != V4L2_FIELD_ALTERNATE && in __vpe_try_fmt()
1614 pix->field != V4L2_FIELD_SEQ_TB && in __vpe_try_fmt()
1615 pix->field != V4L2_FIELD_SEQ_BT) in __vpe_try_fmt()
1616 pix->field = V4L2_FIELD_NONE; in __vpe_try_fmt()
1618 depth = fmt->vpdma_fmt[VPE_LUMA]->depth; in __vpe_try_fmt()
1654 v4l_bound_align_image(&pix->width, MIN_W, MAX_W, w_align, in __vpe_try_fmt()
1655 &pix->height, MIN_H, MAX_H, H_ALIGN, in __vpe_try_fmt()
1658 if (!pix->num_planes || pix->num_planes > 2) in __vpe_try_fmt()
1659 pix->num_planes = fmt->coplanar ? 2 : 1; in __vpe_try_fmt()
1660 else if (pix->num_planes > 1 && !fmt->coplanar) in __vpe_try_fmt()
1661 pix->num_planes = 1; in __vpe_try_fmt()
1663 pix->pixelformat = fmt->fourcc; in __vpe_try_fmt()
1664 finfo = v4l2_format_info(fmt->fourcc); in __vpe_try_fmt()
1670 if (pix->field == V4L2_FIELD_SEQ_TB || pix->field == V4L2_FIELD_SEQ_BT) in __vpe_try_fmt()
1671 height = pix->height / 2; in __vpe_try_fmt()
1673 height = pix->height; in __vpe_try_fmt()
1675 if (!pix->colorspace) { in __vpe_try_fmt()
1677 pix->colorspace = V4L2_COLORSPACE_SRGB; in __vpe_try_fmt()
1680 pix->colorspace = V4L2_COLORSPACE_REC709; in __vpe_try_fmt()
1682 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; in __vpe_try_fmt()
1686 for (i = 0; i < pix->num_planes; i++) { in __vpe_try_fmt()
1687 plane_fmt = &pix->plane_fmt[i]; in __vpe_try_fmt()
1688 depth = fmt->vpdma_fmt[i]->depth; in __vpe_try_fmt()
1690 stride = (pix->width * fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3; in __vpe_try_fmt()
1691 if (stride > plane_fmt->bytesperline) in __vpe_try_fmt()
1692 plane_fmt->bytesperline = stride; in __vpe_try_fmt()
1694 plane_fmt->bytesperline = clamp_t(u32, plane_fmt->bytesperline, in __vpe_try_fmt()
1698 plane_fmt->bytesperline = ALIGN(plane_fmt->bytesperline, in __vpe_try_fmt()
1702 plane_fmt->sizeimage = pix->height * in __vpe_try_fmt()
1703 plane_fmt->bytesperline; in __vpe_try_fmt()
1705 if (pix->num_planes == 1 && fmt->coplanar) in __vpe_try_fmt()
1706 plane_fmt->sizeimage += pix->height * in __vpe_try_fmt()
1707 plane_fmt->bytesperline * in __vpe_try_fmt()
1708 fmt->vpdma_fmt[VPE_CHROMA]->depth >> 3; in __vpe_try_fmt()
1711 plane_fmt->sizeimage = (pix->height * in __vpe_try_fmt()
1712 plane_fmt->bytesperline * in __vpe_try_fmt()
1722 struct vpe_ctx *ctx = file->private_data; in vpe_try_fmt()
1725 if (V4L2_TYPE_IS_OUTPUT(f->type)) in vpe_try_fmt()
1733 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; in __vpe_s_fmt()
1738 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in __vpe_s_fmt()
1740 return -EINVAL; in __vpe_s_fmt()
1743 vpe_err(ctx->dev, "queue busy\n"); in __vpe_s_fmt()
1744 return -EBUSY; in __vpe_s_fmt()
1747 q_data = get_q_data(ctx, f->type); in __vpe_s_fmt()
1749 return -EINVAL; in __vpe_s_fmt()
1751 qpix = &q_data->format.fmt.pix_mp; in __vpe_s_fmt()
1752 q_data->fmt = find_format(f); in __vpe_s_fmt()
1753 q_data->format = *f; in __vpe_s_fmt()
1755 q_data->c_rect.left = 0; in __vpe_s_fmt()
1756 q_data->c_rect.top = 0; in __vpe_s_fmt()
1757 q_data->c_rect.width = pix->width; in __vpe_s_fmt()
1758 q_data->c_rect.height = pix->height; in __vpe_s_fmt()
1760 if (qpix->field == V4L2_FIELD_ALTERNATE) in __vpe_s_fmt()
1761 q_data->flags |= Q_DATA_INTERLACED_ALTERNATE; in __vpe_s_fmt()
1762 else if (qpix->field == V4L2_FIELD_SEQ_TB) in __vpe_s_fmt()
1763 q_data->flags |= Q_DATA_INTERLACED_SEQ_TB; in __vpe_s_fmt()
1764 else if (qpix->field == V4L2_FIELD_SEQ_BT) in __vpe_s_fmt()
1765 q_data->flags |= Q_DATA_INTERLACED_SEQ_BT; in __vpe_s_fmt()
1767 q_data->flags &= ~Q_IS_INTERLACED; in __vpe_s_fmt()
1770 if (q_data->flags & Q_IS_SEQ_XX) in __vpe_s_fmt()
1771 q_data->c_rect.height /= 2; in __vpe_s_fmt()
1773 vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d", in __vpe_s_fmt()
1774 f->type, pix->width, pix->height, pix->pixelformat, in __vpe_s_fmt()
1775 pix->plane_fmt[0].bytesperline); in __vpe_s_fmt()
1776 if (pix->num_planes == 2) in __vpe_s_fmt()
1777 vpe_dbg(ctx->dev, " bpl_uv %d\n", in __vpe_s_fmt()
1778 pix->plane_fmt[1].bytesperline); in __vpe_s_fmt()
1786 struct vpe_ctx *ctx = file->private_data; in vpe_s_fmt()
1796 if (V4L2_TYPE_IS_OUTPUT(f->type)) in vpe_s_fmt()
1810 if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && in __vpe_try_selection()
1811 (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)) in __vpe_try_selection()
1812 return -EINVAL; in __vpe_try_selection()
1814 q_data = get_q_data(ctx, s->type); in __vpe_try_selection()
1816 return -EINVAL; in __vpe_try_selection()
1818 pix = &q_data->format.fmt.pix_mp; in __vpe_try_selection()
1820 switch (s->target) { in __vpe_try_selection()
1826 if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in __vpe_try_selection()
1827 return -EINVAL; in __vpe_try_selection()
1834 if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in __vpe_try_selection()
1835 return -EINVAL; in __vpe_try_selection()
1842 return -EINVAL; in __vpe_try_selection()
1849 if (q_data->flags & Q_IS_SEQ_XX) in __vpe_try_selection()
1850 height = pix->height / 2; in __vpe_try_selection()
1852 height = pix->height; in __vpe_try_selection()
1854 if (s->r.top < 0 || s->r.left < 0) { in __vpe_try_selection()
1855 vpe_err(ctx->dev, "negative values for top and left\n"); in __vpe_try_selection()
1856 s->r.top = s->r.left = 0; in __vpe_try_selection()
1859 v4l_bound_align_image(&s->r.width, MIN_W, pix->width, 1, in __vpe_try_selection()
1860 &s->r.height, MIN_H, height, H_ALIGN, S_ALIGN); in __vpe_try_selection()
1863 if (s->r.left + s->r.width > pix->width) in __vpe_try_selection()
1864 s->r.left = pix->width - s->r.width; in __vpe_try_selection()
1865 if (s->r.top + s->r.height > pix->height) in __vpe_try_selection()
1866 s->r.top = pix->height - s->r.height; in __vpe_try_selection()
1874 struct vpe_ctx *ctx = file->private_data; in vpe_g_selection()
1879 if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && in vpe_g_selection()
1880 (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)) in vpe_g_selection()
1881 return -EINVAL; in vpe_g_selection()
1883 q_data = get_q_data(ctx, s->type); in vpe_g_selection()
1885 return -EINVAL; in vpe_g_selection()
1887 pix = &q_data->format.fmt.pix_mp; in vpe_g_selection()
1889 switch (s->target) { in vpe_g_selection()
1892 if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in vpe_g_selection()
1893 return -EINVAL; in vpe_g_selection()
1897 if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in vpe_g_selection()
1898 return -EINVAL; in vpe_g_selection()
1901 if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in vpe_g_selection()
1902 return -EINVAL; in vpe_g_selection()
1906 if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in vpe_g_selection()
1907 return -EINVAL; in vpe_g_selection()
1911 return -EINVAL; in vpe_g_selection()
1919 s->r = q_data->c_rect; in vpe_g_selection()
1925 s->r.left = 0; in vpe_g_selection()
1926 s->r.top = 0; in vpe_g_selection()
1927 s->r.width = pix->width; in vpe_g_selection()
1928 s->r.height = pix->height; in vpe_g_selection()
1938 struct vpe_ctx *ctx = file->private_data; in vpe_s_selection()
1949 return -EINVAL; in vpe_s_selection()
1951 if ((q_data->c_rect.left == sel.r.left) && in vpe_s_selection()
1952 (q_data->c_rect.top == sel.r.top) && in vpe_s_selection()
1953 (q_data->c_rect.width == sel.r.width) && in vpe_s_selection()
1954 (q_data->c_rect.height == sel.r.height)) { in vpe_s_selection()
1955 vpe_dbg(ctx->dev, in vpe_s_selection()
1960 q_data->c_rect = sel.r; in vpe_s_selection()
1974 container_of(ctrl->handler, struct vpe_ctx, hdl); in vpe_s_ctrl()
1976 switch (ctrl->id) { in vpe_s_ctrl()
1978 ctx->bufs_per_job = ctrl->val; in vpe_s_ctrl()
1982 vpe_err(ctx->dev, "Invalid control\n"); in vpe_s_ctrl()
1983 return -EINVAL; in vpe_s_ctrl()
2033 q_data = get_q_data(ctx, vq->type); in vpe_queue_setup()
2035 return -EINVAL; in vpe_queue_setup()
2037 pix = &q_data->format.fmt.pix_mp; in vpe_queue_setup()
2038 *nplanes = pix->num_planes; in vpe_queue_setup()
2041 sizes[i] = pix->plane_fmt[i].sizeimage; in vpe_queue_setup()
2043 vpe_dbg(ctx->dev, "get %d buffer(s) of size %d", *nbuffers, in vpe_queue_setup()
2046 vpe_dbg(ctx->dev, " and %d\n", sizes[VPE_CHROMA]); in vpe_queue_setup()
2054 struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in vpe_buf_prepare()
2059 vpe_dbg(ctx->dev, "type: %d\n", vb->vb2_queue->type); in vpe_buf_prepare()
2061 q_data = get_q_data(ctx, vb->vb2_queue->type); in vpe_buf_prepare()
2063 return -EINVAL; in vpe_buf_prepare()
2065 pix = &q_data->format.fmt.pix_mp; in vpe_buf_prepare()
2067 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { in vpe_buf_prepare()
2068 if (!(q_data->flags & Q_IS_INTERLACED)) { in vpe_buf_prepare()
2069 vbuf->field = V4L2_FIELD_NONE; in vpe_buf_prepare()
2071 if (vbuf->field != V4L2_FIELD_TOP && in vpe_buf_prepare()
2072 vbuf->field != V4L2_FIELD_BOTTOM && in vpe_buf_prepare()
2073 vbuf->field != V4L2_FIELD_SEQ_TB && in vpe_buf_prepare()
2074 vbuf->field != V4L2_FIELD_SEQ_BT) in vpe_buf_prepare()
2075 return -EINVAL; in vpe_buf_prepare()
2079 for (i = 0; i < pix->num_planes; i++) { in vpe_buf_prepare()
2080 if (vb2_plane_size(vb, i) < pix->plane_fmt[i].sizeimage) { in vpe_buf_prepare()
2081 vpe_err(ctx->dev, in vpe_buf_prepare()
2084 (long)pix->plane_fmt[i].sizeimage); in vpe_buf_prepare()
2085 return -EINVAL; in vpe_buf_prepare()
2089 for (i = 0; i < pix->num_planes; i++) in vpe_buf_prepare()
2090 vb2_set_plane_payload(vb, i, pix->plane_fmt[i].sizeimage); in vpe_buf_prepare()
2098 struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in vpe_buf_queue()
2100 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in vpe_buf_queue()
2105 struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; in check_srcdst_sizes()
2106 struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; in check_srcdst_sizes()
2107 unsigned int src_w = s_q_data->c_rect.width; in check_srcdst_sizes()
2108 unsigned int src_h = s_q_data->c_rect.height; in check_srcdst_sizes()
2109 unsigned int dst_w = d_q_data->c_rect.width; in check_srcdst_sizes()
2110 unsigned int dst_h = d_q_data->c_rect.height; in check_srcdst_sizes()
2121 return -1; in check_srcdst_sizes()
2131 if (V4L2_TYPE_IS_OUTPUT(q->type)) in vpe_return_all_buffers()
2132 vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in vpe_return_all_buffers()
2134 vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in vpe_return_all_buffers()
2137 spin_lock_irqsave(&ctx->dev->lock, flags); in vpe_return_all_buffers()
2139 spin_unlock_irqrestore(&ctx->dev->lock, flags); in vpe_return_all_buffers()
2143 * Cleanup the in-transit vb2 buffers that have been in vpe_return_all_buffers()
2147 if (V4L2_TYPE_IS_OUTPUT(q->type)) { in vpe_return_all_buffers()
2148 spin_lock_irqsave(&ctx->dev->lock, flags); in vpe_return_all_buffers()
2150 if (ctx->src_vbs[2]) in vpe_return_all_buffers()
2151 v4l2_m2m_buf_done(ctx->src_vbs[2], state); in vpe_return_all_buffers()
2153 if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2])) in vpe_return_all_buffers()
2154 v4l2_m2m_buf_done(ctx->src_vbs[1], state); in vpe_return_all_buffers()
2156 if (ctx->src_vbs[0] && in vpe_return_all_buffers()
2157 (ctx->src_vbs[0] != ctx->src_vbs[1]) && in vpe_return_all_buffers()
2158 (ctx->src_vbs[0] != ctx->src_vbs[2])) in vpe_return_all_buffers()
2159 v4l2_m2m_buf_done(ctx->src_vbs[0], state); in vpe_return_all_buffers()
2161 ctx->src_vbs[2] = NULL; in vpe_return_all_buffers()
2162 ctx->src_vbs[1] = NULL; in vpe_return_all_buffers()
2163 ctx->src_vbs[0] = NULL; in vpe_return_all_buffers()
2165 spin_unlock_irqrestore(&ctx->dev->lock, flags); in vpe_return_all_buffers()
2167 if (ctx->dst_vb) { in vpe_return_all_buffers()
2168 spin_lock_irqsave(&ctx->dev->lock, flags); in vpe_return_all_buffers()
2170 v4l2_m2m_buf_done(ctx->dst_vb, state); in vpe_return_all_buffers()
2171 ctx->dst_vb = NULL; in vpe_return_all_buffers()
2172 spin_unlock_irqrestore(&ctx->dev->lock, flags); in vpe_return_all_buffers()
2183 vpe_err(ctx->dev, in vpe_start_streaming()
2187 return -EINVAL; in vpe_start_streaming()
2190 if (ctx->deinterlacing) in vpe_start_streaming()
2193 if (ctx->sequence != 0) in vpe_start_streaming()
2203 vpe_dump_regs(ctx->dev); in vpe_stop_streaming()
2204 vpdma_dump_regs(ctx->dev->vpdma); in vpe_stop_streaming()
2223 struct vpe_dev *dev = ctx->dev; in queue_init()
2227 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; in queue_init()
2228 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; in queue_init()
2229 src_vq->drv_priv = ctx; in queue_init()
2230 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
2231 src_vq->ops = &vpe_qops; in queue_init()
2232 src_vq->mem_ops = &vb2_dma_contig_memops; in queue_init()
2233 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
2234 src_vq->lock = &dev->dev_mutex; in queue_init()
2235 src_vq->dev = dev->v4l2_dev.dev; in queue_init()
2242 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in queue_init()
2243 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; in queue_init()
2244 dst_vq->drv_priv = ctx; in queue_init()
2245 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
2246 dst_vq->ops = &vpe_qops; in queue_init()
2247 dst_vq->mem_ops = &vb2_dma_contig_memops; in queue_init()
2248 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
2249 dst_vq->lock = &dev->dev_mutex; in queue_init()
2250 dst_vq->dev = dev->v4l2_dev.dev; in queue_init()
2282 return -ENOMEM; in vpe_open()
2284 ctx->dev = dev; in vpe_open()
2286 if (mutex_lock_interruptible(&dev->dev_mutex)) { in vpe_open()
2287 ret = -ERESTARTSYS; in vpe_open()
2291 ret = vpdma_create_desc_list(&ctx->desc_list, VPE_DESC_LIST_SIZE, in vpe_open()
2296 ret = vpdma_alloc_desc_buf(&ctx->mmr_adb, sizeof(struct vpe_mmr_adb)); in vpe_open()
2300 ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_h, SC_COEF_SRAM_SIZE); in vpe_open()
2304 ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_v, SC_COEF_SRAM_SIZE); in vpe_open()
2310 v4l2_fh_init(&ctx->fh, video_devdata(file)); in vpe_open()
2311 file->private_data = ctx; in vpe_open()
2313 hdl = &ctx->hdl; in vpe_open()
2316 if (hdl->error) { in vpe_open()
2317 ret = hdl->error; in vpe_open()
2320 ctx->fh.ctrl_handler = hdl; in vpe_open()
2323 s_q_data = &ctx->q_data[Q_DATA_SRC]; in vpe_open()
2324 pix = &s_q_data->format.fmt.pix_mp; in vpe_open()
2325 s_q_data->fmt = __find_format(V4L2_PIX_FMT_YUYV); in vpe_open()
2326 pix->pixelformat = s_q_data->fmt->fourcc; in vpe_open()
2327 s_q_data->format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; in vpe_open()
2328 pix->width = 1920; in vpe_open()
2329 pix->height = 1080; in vpe_open()
2330 pix->num_planes = 1; in vpe_open()
2331 pix->plane_fmt[VPE_LUMA].bytesperline = (pix->width * in vpe_open()
2332 s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3; in vpe_open()
2333 pix->plane_fmt[VPE_LUMA].sizeimage = in vpe_open()
2334 pix->plane_fmt[VPE_LUMA].bytesperline * in vpe_open()
2335 pix->height; in vpe_open()
2336 pix->colorspace = V4L2_COLORSPACE_REC709; in vpe_open()
2337 pix->xfer_func = V4L2_XFER_FUNC_DEFAULT; in vpe_open()
2338 pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in vpe_open()
2339 pix->quantization = V4L2_QUANTIZATION_DEFAULT; in vpe_open()
2340 pix->field = V4L2_FIELD_NONE; in vpe_open()
2341 s_q_data->c_rect.left = 0; in vpe_open()
2342 s_q_data->c_rect.top = 0; in vpe_open()
2343 s_q_data->c_rect.width = pix->width; in vpe_open()
2344 s_q_data->c_rect.height = pix->height; in vpe_open()
2345 s_q_data->flags = 0; in vpe_open()
2347 ctx->q_data[Q_DATA_DST] = *s_q_data; in vpe_open()
2348 ctx->q_data[Q_DATA_DST].format.type = in vpe_open()
2358 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); in vpe_open()
2360 if (IS_ERR(ctx->fh.m2m_ctx)) { in vpe_open()
2361 ret = PTR_ERR(ctx->fh.m2m_ctx); in vpe_open()
2365 v4l2_fh_add(&ctx->fh); in vpe_open()
2372 if (atomic_inc_return(&dev->num_instances) == 1) in vpe_open()
2375 ctx->bufs_per_job = VPE_DEF_BUFS_PER_JOB; in vpe_open()
2377 ctx->load_mmrs = true; in vpe_open()
2380 ctx, ctx->fh.m2m_ctx); in vpe_open()
2382 mutex_unlock(&dev->dev_mutex); in vpe_open()
2387 v4l2_fh_exit(&ctx->fh); in vpe_open()
2388 vpdma_free_desc_buf(&ctx->sc_coeff_v); in vpe_open()
2390 vpdma_free_desc_buf(&ctx->sc_coeff_h); in vpe_open()
2392 vpdma_free_desc_buf(&ctx->mmr_adb); in vpe_open()
2394 vpdma_free_desc_list(&ctx->desc_list); in vpe_open()
2396 mutex_unlock(&dev->dev_mutex); in vpe_open()
2405 struct vpe_ctx *ctx = file->private_data; in vpe_release()
2409 mutex_lock(&dev->dev_mutex); in vpe_release()
2412 vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf); in vpe_release()
2413 vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb); in vpe_release()
2414 vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h); in vpe_release()
2415 vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v); in vpe_release()
2417 vpdma_free_desc_list(&ctx->desc_list); in vpe_release()
2418 vpdma_free_desc_buf(&ctx->mmr_adb); in vpe_release()
2420 vpdma_free_desc_buf(&ctx->sc_coeff_v); in vpe_release()
2421 vpdma_free_desc_buf(&ctx->sc_coeff_h); in vpe_release()
2423 v4l2_fh_del(&ctx->fh); in vpe_release()
2424 v4l2_fh_exit(&ctx->fh); in vpe_release()
2425 v4l2_ctrl_handler_free(&ctx->hdl); in vpe_release()
2426 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in vpe_release()
2435 if (atomic_dec_return(&dev->num_instances) == 0) in vpe_release()
2438 mutex_unlock(&dev->dev_mutex); in vpe_release()
2456 .minor = -1,
2472 dev_dbg(&pdev->dev, "vpe_runtime_get\n"); in vpe_runtime_get()
2474 r = pm_runtime_resume_and_get(&pdev->dev); in vpe_runtime_get()
2484 dev_dbg(&pdev->dev, "vpe_runtime_put\n"); in vpe_runtime_put()
2486 r = pm_runtime_put_sync(&pdev->dev); in vpe_runtime_put()
2487 WARN_ON(r < 0 && r != -ENOSYS); in vpe_runtime_put()
2496 vfd = &dev->vfd; in vpe_fw_cb()
2498 vfd->lock = &dev->dev_mutex; in vpe_fw_cb()
2499 vfd->v4l2_dev = &dev->v4l2_dev; in vpe_fw_cb()
2507 pm_runtime_disable(&pdev->dev); in vpe_fw_cb()
2508 v4l2_m2m_release(dev->m2m_dev); in vpe_fw_cb()
2509 v4l2_device_unregister(&dev->v4l2_dev); in vpe_fw_cb()
2515 dev_info(dev->v4l2_dev.dev, "Device registered as /dev/video%d\n", in vpe_fw_cb()
2516 vfd->num); in vpe_fw_cb()
2524 ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); in vpe_probe()
2526 dev_err(&pdev->dev, in vpe_probe()
2527 "32-bit consistent DMA enable failed\n"); in vpe_probe()
2531 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in vpe_probe()
2533 return -ENOMEM; in vpe_probe()
2535 spin_lock_init(&dev->lock); in vpe_probe()
2537 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); in vpe_probe()
2541 atomic_set(&dev->num_instances, 0); in vpe_probe()
2542 mutex_init(&dev->dev_mutex); in vpe_probe()
2544 dev->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, in vpe_probe()
2546 if (!dev->res) { in vpe_probe()
2547 dev_err(&pdev->dev, "missing 'vpe_top' resources data\n"); in vpe_probe()
2548 return -ENODEV; in vpe_probe()
2557 dev->base = devm_ioremap(&pdev->dev, dev->res->start, SZ_32K); in vpe_probe()
2558 if (!dev->base) { in vpe_probe()
2559 ret = -ENOMEM; in vpe_probe()
2564 ret = devm_request_irq(&pdev->dev, irq, vpe_irq, 0, VPE_MODULE_NAME, in vpe_probe()
2571 dev->m2m_dev = v4l2_m2m_init(&m2m_ops); in vpe_probe()
2572 if (IS_ERR(dev->m2m_dev)) { in vpe_probe()
2574 ret = PTR_ERR(dev->m2m_dev); in vpe_probe()
2578 pm_runtime_enable(&pdev->dev); in vpe_probe()
2595 dev->sc = sc_create(pdev, "sc"); in vpe_probe()
2596 if (IS_ERR(dev->sc)) { in vpe_probe()
2597 ret = PTR_ERR(dev->sc); in vpe_probe()
2601 dev->csc = csc_create(pdev, "csc"); in vpe_probe()
2602 if (IS_ERR(dev->csc)) { in vpe_probe()
2603 ret = PTR_ERR(dev->csc); in vpe_probe()
2607 dev->vpdma = &dev->vpdma_data; in vpe_probe()
2608 ret = vpdma_create(pdev, dev->vpdma, vpe_fw_cb); in vpe_probe()
2617 pm_runtime_disable(&pdev->dev); in vpe_probe()
2618 v4l2_m2m_release(dev->m2m_dev); in vpe_probe()
2620 v4l2_device_unregister(&dev->v4l2_dev); in vpe_probe()
2629 v4l2_info(&dev->v4l2_dev, "Removing " VPE_MODULE_NAME); in vpe_remove()
2631 v4l2_m2m_release(dev->m2m_dev); in vpe_remove()
2632 video_unregister_device(&dev->vfd); in vpe_remove()
2633 v4l2_device_unregister(&dev->v4l2_dev); in vpe_remove()
2637 pm_runtime_disable(&pdev->dev); in vpe_remove()
2643 .compatible = "ti,dra7-vpe",