0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/clk.h>
0010 #include <linux/delay.h>
0011 #include <linux/gcd.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/mfd/syscon.h>
0014 #include <linux/module.h>
0015 #include <linux/of_device.h>
0016 #include <linux/of_graph.h>
0017 #include <linux/pinctrl/consumer.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/regmap.h>
0020 #include <linux/slab.h>
0021 #include <linux/spinlock.h>
0022 #include <linux/types.h>
0023
0024 #include <media/v4l2-device.h>
0025 #include <media/v4l2-fwnode.h>
0026 #include <media/v4l2-ioctl.h>
0027 #include <media/v4l2-mc.h>
0028 #include <media/v4l2-subdev.h>
0029 #include <media/videobuf2-dma-contig.h>
0030
0031 #define IMX7_CSI_PAD_SINK 0
0032 #define IMX7_CSI_PAD_SRC 1
0033 #define IMX7_CSI_PADS_NUM 2
0034
0035
0036 #define BIT_SWAP16_EN BIT(31)
0037 #define BIT_EXT_VSYNC BIT(30)
0038 #define BIT_EOF_INT_EN BIT(29)
0039 #define BIT_PRP_IF_EN BIT(28)
0040 #define BIT_CCIR_MODE BIT(27)
0041 #define BIT_COF_INT_EN BIT(26)
0042 #define BIT_SF_OR_INTEN BIT(25)
0043 #define BIT_RF_OR_INTEN BIT(24)
0044 #define BIT_SFF_DMA_DONE_INTEN BIT(22)
0045 #define BIT_STATFF_INTEN BIT(21)
0046 #define BIT_FB2_DMA_DONE_INTEN BIT(20)
0047 #define BIT_FB1_DMA_DONE_INTEN BIT(19)
0048 #define BIT_RXFF_INTEN BIT(18)
0049 #define BIT_SOF_POL BIT(17)
0050 #define BIT_SOF_INTEN BIT(16)
0051 #define BIT_MCLKDIV(n) ((n) << 12)
0052 #define BIT_MCLKDIV_MASK (0xf << 12)
0053 #define BIT_HSYNC_POL BIT(11)
0054 #define BIT_CCIR_EN BIT(10)
0055 #define BIT_MCLKEN BIT(9)
0056 #define BIT_FCC BIT(8)
0057 #define BIT_PACK_DIR BIT(7)
0058 #define BIT_CLR_STATFIFO BIT(6)
0059 #define BIT_CLR_RXFIFO BIT(5)
0060 #define BIT_GCLK_MODE BIT(4)
0061 #define BIT_INV_DATA BIT(3)
0062 #define BIT_INV_PCLK BIT(2)
0063 #define BIT_REDGE BIT(1)
0064 #define BIT_PIXEL_BIT BIT(0)
0065
0066
0067 #define BIT_DMA_BURST_TYPE_RFF_INCR4 (1 << 30)
0068 #define BIT_DMA_BURST_TYPE_RFF_INCR8 (2 << 30)
0069 #define BIT_DMA_BURST_TYPE_RFF_INCR16 (3 << 30)
0070 #define BIT_DMA_BURST_TYPE_RFF_MASK (3 << 30)
0071
0072
0073 #define BIT_FRMCNT(n) ((n) << 16)
0074 #define BIT_FRMCNT_MASK (0xffff << 16)
0075 #define BIT_FRMCNT_RST BIT(15)
0076 #define BIT_DMA_REFLASH_RFF BIT(14)
0077 #define BIT_DMA_REFLASH_SFF BIT(13)
0078 #define BIT_DMA_REQ_EN_RFF BIT(12)
0079 #define BIT_DMA_REQ_EN_SFF BIT(11)
0080 #define BIT_STATFF_LEVEL(n) ((n) << 8)
0081 #define BIT_STATFF_LEVEL_MASK (0x7 << 8)
0082 #define BIT_HRESP_ERR_EN BIT(7)
0083 #define BIT_RXFF_LEVEL(n) ((n) << 4)
0084 #define BIT_RXFF_LEVEL_MASK (0x7 << 4)
0085 #define BIT_TWO_8BIT_SENSOR BIT(3)
0086 #define BIT_ZERO_PACK_EN BIT(2)
0087 #define BIT_ECC_INT_EN BIT(1)
0088 #define BIT_ECC_AUTO_EN BIT(0)
0089
0090
0091 #define BIT_ADDR_CH_ERR_INT BIT(28)
0092 #define BIT_FIELD0_INT BIT(27)
0093 #define BIT_FIELD1_INT BIT(26)
0094 #define BIT_SFF_OR_INT BIT(25)
0095 #define BIT_RFF_OR_INT BIT(24)
0096 #define BIT_DMA_TSF_DONE_SFF BIT(22)
0097 #define BIT_STATFF_INT BIT(21)
0098 #define BIT_DMA_TSF_DONE_FB2 BIT(20)
0099 #define BIT_DMA_TSF_DONE_FB1 BIT(19)
0100 #define BIT_RXFF_INT BIT(18)
0101 #define BIT_EOF_INT BIT(17)
0102 #define BIT_SOF_INT BIT(16)
0103 #define BIT_F2_INT BIT(15)
0104 #define BIT_F1_INT BIT(14)
0105 #define BIT_COF_INT BIT(13)
0106 #define BIT_HRESP_ERR_INT BIT(7)
0107 #define BIT_ECC_INT BIT(1)
0108 #define BIT_DRDY BIT(0)
0109
0110
0111 #define BIT_IMAGE_WIDTH(n) ((n) << 16)
0112 #define BIT_IMAGE_HEIGHT(n) (n)
0113
0114
0115 #define BIT_CSI_HW_ENABLE BIT(31)
0116 #define BIT_MIPI_DATA_FORMAT_RAW8 (0x2a << 25)
0117 #define BIT_MIPI_DATA_FORMAT_RAW10 (0x2b << 25)
0118 #define BIT_MIPI_DATA_FORMAT_RAW12 (0x2c << 25)
0119 #define BIT_MIPI_DATA_FORMAT_RAW14 (0x2d << 25)
0120 #define BIT_MIPI_DATA_FORMAT_YUV422_8B (0x1e << 25)
0121 #define BIT_MIPI_DATA_FORMAT_MASK (0x3f << 25)
0122 #define BIT_DATA_FROM_MIPI BIT(22)
0123 #define BIT_MIPI_YU_SWAP BIT(21)
0124 #define BIT_MIPI_DOUBLE_CMPNT BIT(20)
0125 #define BIT_MASK_OPTION_FIRST_FRAME (0 << 18)
0126 #define BIT_MASK_OPTION_CSI_EN (1 << 18)
0127 #define BIT_MASK_OPTION_SECOND_FRAME (2 << 18)
0128 #define BIT_MASK_OPTION_ON_DATA (3 << 18)
0129 #define BIT_BASEADDR_CHG_ERR_EN BIT(9)
0130 #define BIT_BASEADDR_SWITCH_SEL BIT(5)
0131 #define BIT_BASEADDR_SWITCH_EN BIT(4)
0132 #define BIT_PARALLEL24_EN BIT(3)
0133 #define BIT_DEINTERLACE_EN BIT(2)
0134 #define BIT_TVDECODER_IN_EN BIT(1)
0135 #define BIT_NTSC_EN BIT(0)
0136
0137 #define CSI_MCLK_VF 1
0138 #define CSI_MCLK_ENC 2
0139 #define CSI_MCLK_RAW 4
0140 #define CSI_MCLK_I2C 8
0141
0142 #define CSI_CSICR1 0x00
0143 #define CSI_CSICR2 0x04
0144 #define CSI_CSICR3 0x08
0145 #define CSI_STATFIFO 0x0c
0146 #define CSI_CSIRXFIFO 0x10
0147 #define CSI_CSIRXCNT 0x14
0148 #define CSI_CSISR 0x18
0149
0150 #define CSI_CSIDBG 0x1c
0151 #define CSI_CSIDMASA_STATFIFO 0x20
0152 #define CSI_CSIDMATS_STATFIFO 0x24
0153 #define CSI_CSIDMASA_FB1 0x28
0154 #define CSI_CSIDMASA_FB2 0x2c
0155 #define CSI_CSIFBUF_PARA 0x30
0156 #define CSI_CSIIMAG_PARA 0x34
0157
0158 #define CSI_CSICR18 0x48
0159 #define CSI_CSICR19 0x4c
0160
0161 #define IMX7_CSI_VIDEO_NAME "imx-capture"
0162
0163 #define IMX7_CSI_VIDEO_MEM_LIMIT SZ_64M
0164 #define IMX7_CSI_VIDEO_EOF_TIMEOUT 2000
0165
0166 #define IMX7_CSI_DEF_MBUS_CODE MEDIA_BUS_FMT_UYVY8_2X8
0167 #define IMX7_CSI_DEF_PIX_FORMAT V4L2_PIX_FMT_UYVY
0168 #define IMX7_CSI_DEF_PIX_WIDTH 640
0169 #define IMX7_CSI_DEF_PIX_HEIGHT 480
0170
0171 enum imx_csi_model {
0172 IMX7_CSI_IMX7 = 0,
0173 IMX7_CSI_IMX8MQ,
0174 };
0175
0176 struct imx7_csi_pixfmt {
0177
0178 u32 fourcc;
0179
0180
0181
0182
0183 const u32 *codes;
0184 int bpp;
0185 bool yuv;
0186 };
0187
0188 struct imx7_csi_vb2_buffer {
0189 struct vb2_v4l2_buffer vbuf;
0190 struct list_head list;
0191 };
0192
0193 static inline struct imx7_csi_vb2_buffer *
0194 to_imx7_csi_vb2_buffer(struct vb2_buffer *vb)
0195 {
0196 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0197
0198 return container_of(vbuf, struct imx7_csi_vb2_buffer, vbuf);
0199 }
0200
0201 struct imx7_csi_dma_buf {
0202 void *virt;
0203 dma_addr_t phys;
0204 unsigned long len;
0205 };
0206
0207 struct imx7_csi {
0208 struct device *dev;
0209
0210
0211 void __iomem *regbase;
0212 int irq;
0213 struct clk *mclk;
0214
0215 struct mutex lock;
0216 spinlock_t irqlock;
0217
0218
0219 struct media_device mdev;
0220 struct v4l2_device v4l2_dev;
0221 struct v4l2_async_notifier notifier;
0222 struct media_pipeline pipe;
0223
0224 struct v4l2_subdev *src_sd;
0225 bool is_csi2;
0226
0227
0228 struct v4l2_subdev sd;
0229 struct media_pad pad[IMX7_CSI_PADS_NUM];
0230
0231 struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM];
0232 const struct imx7_csi_pixfmt *cc[IMX7_CSI_PADS_NUM];
0233
0234
0235 struct video_device *vdev;
0236 struct media_pad vdev_pad;
0237
0238 struct v4l2_pix_format vdev_fmt;
0239 const struct imx7_csi_pixfmt *vdev_cc;
0240 struct v4l2_rect vdev_compose;
0241
0242 struct mutex vdev_mutex;
0243
0244 struct vb2_queue q;
0245 struct list_head ready_q;
0246 spinlock_t q_lock;
0247
0248
0249 struct imx7_csi_vb2_buffer *active_vb2_buf[2];
0250 struct imx7_csi_dma_buf underrun_buf;
0251
0252 bool is_streaming;
0253 int buf_num;
0254 u32 frame_sequence;
0255
0256 bool last_eof;
0257 struct completion last_eof_completion;
0258
0259 enum imx_csi_model model;
0260 };
0261
0262 static struct imx7_csi *
0263 imx7_csi_notifier_to_dev(struct v4l2_async_notifier *n)
0264 {
0265 return container_of(n, struct imx7_csi, notifier);
0266 }
0267
0268
0269
0270
0271
0272 static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset)
0273 {
0274 return readl(csi->regbase + offset);
0275 }
0276
0277 static void imx7_csi_reg_write(struct imx7_csi *csi, unsigned int value,
0278 unsigned int offset)
0279 {
0280 writel(value, csi->regbase + offset);
0281 }
0282
0283 static u32 imx7_csi_irq_clear(struct imx7_csi *csi)
0284 {
0285 u32 isr;
0286
0287 isr = imx7_csi_reg_read(csi, CSI_CSISR);
0288 imx7_csi_reg_write(csi, isr, CSI_CSISR);
0289
0290 return isr;
0291 }
0292
0293 static void imx7_csi_init_default(struct imx7_csi *csi)
0294 {
0295 imx7_csi_reg_write(csi, BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE |
0296 BIT_HSYNC_POL | BIT_FCC | BIT_MCLKDIV(1) |
0297 BIT_MCLKEN, CSI_CSICR1);
0298 imx7_csi_reg_write(csi, 0, CSI_CSICR2);
0299 imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3);
0300
0301 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(IMX7_CSI_DEF_PIX_WIDTH) |
0302 BIT_IMAGE_HEIGHT(IMX7_CSI_DEF_PIX_HEIGHT),
0303 CSI_CSIIMAG_PARA);
0304
0305 imx7_csi_reg_write(csi, BIT_DMA_REFLASH_RFF, CSI_CSICR3);
0306 }
0307
0308 static void imx7_csi_hw_enable_irq(struct imx7_csi *csi)
0309 {
0310 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
0311
0312 cr1 |= BIT_RFF_OR_INT;
0313 cr1 |= BIT_FB1_DMA_DONE_INTEN;
0314 cr1 |= BIT_FB2_DMA_DONE_INTEN;
0315
0316 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
0317 }
0318
0319 static void imx7_csi_hw_disable_irq(struct imx7_csi *csi)
0320 {
0321 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
0322
0323 cr1 &= ~BIT_RFF_OR_INT;
0324 cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
0325 cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
0326
0327 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
0328 }
0329
0330 static void imx7_csi_hw_enable(struct imx7_csi *csi)
0331 {
0332 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
0333
0334 cr |= BIT_CSI_HW_ENABLE;
0335
0336 imx7_csi_reg_write(csi, cr, CSI_CSICR18);
0337 }
0338
0339 static void imx7_csi_hw_disable(struct imx7_csi *csi)
0340 {
0341 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
0342
0343 cr &= ~BIT_CSI_HW_ENABLE;
0344
0345 imx7_csi_reg_write(csi, cr, CSI_CSICR18);
0346 }
0347
0348 static void imx7_csi_dma_reflash(struct imx7_csi *csi)
0349 {
0350 u32 cr3;
0351
0352 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
0353 cr3 |= BIT_DMA_REFLASH_RFF;
0354 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
0355 }
0356
0357 static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi)
0358 {
0359 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1) & ~BIT_FCC;
0360
0361 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
0362 imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1);
0363 imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1);
0364 }
0365
0366 static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi)
0367 {
0368 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
0369
0370 cr3 |= BIT_DMA_REQ_EN_RFF;
0371 cr3 |= BIT_HRESP_ERR_EN;
0372 cr3 &= ~BIT_RXFF_LEVEL_MASK;
0373 cr3 |= BIT_RXFF_LEVEL(2);
0374
0375 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
0376 }
0377
0378 static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi)
0379 {
0380 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
0381
0382 cr3 &= ~BIT_DMA_REQ_EN_RFF;
0383 cr3 &= ~BIT_HRESP_ERR_EN;
0384 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
0385 }
0386
0387 static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys,
0388 int buf_num)
0389 {
0390 if (buf_num == 1)
0391 imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2);
0392 else
0393 imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1);
0394 }
0395
0396 static struct imx7_csi_vb2_buffer *imx7_csi_video_next_buf(struct imx7_csi *csi);
0397
0398 static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi)
0399 {
0400 struct imx7_csi_vb2_buffer *buf;
0401 struct vb2_buffer *vb2_buf;
0402 dma_addr_t phys[2];
0403 int i;
0404
0405 for (i = 0; i < 2; i++) {
0406 buf = imx7_csi_video_next_buf(csi);
0407 if (buf) {
0408 csi->active_vb2_buf[i] = buf;
0409 vb2_buf = &buf->vbuf.vb2_buf;
0410 phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
0411 } else {
0412 csi->active_vb2_buf[i] = NULL;
0413 phys[i] = csi->underrun_buf.phys;
0414 }
0415
0416 imx7_csi_update_buf(csi, phys[i], i);
0417 }
0418 }
0419
0420 static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi,
0421 enum vb2_buffer_state return_status)
0422 {
0423 struct imx7_csi_vb2_buffer *buf;
0424 int i;
0425
0426
0427 for (i = 0; i < 2; i++) {
0428 buf = csi->active_vb2_buf[i];
0429 if (buf) {
0430 struct vb2_buffer *vb = &buf->vbuf.vb2_buf;
0431
0432 vb->timestamp = ktime_get_ns();
0433 vb2_buffer_done(vb, return_status);
0434 csi->active_vb2_buf[i] = NULL;
0435 }
0436 }
0437 }
0438
0439 static void imx7_csi_free_dma_buf(struct imx7_csi *csi,
0440 struct imx7_csi_dma_buf *buf)
0441 {
0442 if (buf->virt)
0443 dma_free_coherent(csi->dev, buf->len, buf->virt, buf->phys);
0444
0445 buf->virt = NULL;
0446 buf->phys = 0;
0447 }
0448
0449 static int imx7_csi_alloc_dma_buf(struct imx7_csi *csi,
0450 struct imx7_csi_dma_buf *buf, int size)
0451 {
0452 imx7_csi_free_dma_buf(csi, buf);
0453
0454 buf->len = PAGE_ALIGN(size);
0455 buf->virt = dma_alloc_coherent(csi->dev, buf->len, &buf->phys,
0456 GFP_DMA | GFP_KERNEL);
0457 if (!buf->virt)
0458 return -ENOMEM;
0459
0460 return 0;
0461 }
0462
0463 static int imx7_csi_dma_setup(struct imx7_csi *csi)
0464 {
0465 int ret;
0466
0467 ret = imx7_csi_alloc_dma_buf(csi, &csi->underrun_buf,
0468 csi->vdev_fmt.sizeimage);
0469 if (ret < 0) {
0470 v4l2_warn(&csi->sd, "consider increasing the CMA area\n");
0471 return ret;
0472 }
0473
0474 csi->frame_sequence = 0;
0475 csi->last_eof = false;
0476 init_completion(&csi->last_eof_completion);
0477
0478 imx7_csi_setup_vb2_buf(csi);
0479
0480 return 0;
0481 }
0482
0483 static void imx7_csi_dma_cleanup(struct imx7_csi *csi,
0484 enum vb2_buffer_state return_status)
0485 {
0486 imx7_csi_dma_unsetup_vb2_buf(csi, return_status);
0487 imx7_csi_free_dma_buf(csi, &csi->underrun_buf);
0488 }
0489
0490 static void imx7_csi_dma_stop(struct imx7_csi *csi)
0491 {
0492 unsigned long timeout_jiffies;
0493 unsigned long flags;
0494 int ret;
0495
0496
0497 spin_lock_irqsave(&csi->irqlock, flags);
0498 csi->last_eof = true;
0499 spin_unlock_irqrestore(&csi->irqlock, flags);
0500
0501
0502
0503
0504 timeout_jiffies = msecs_to_jiffies(IMX7_CSI_VIDEO_EOF_TIMEOUT);
0505 ret = wait_for_completion_timeout(&csi->last_eof_completion,
0506 timeout_jiffies);
0507 if (ret == 0)
0508 v4l2_warn(&csi->sd, "wait last EOF timeout\n");
0509
0510 imx7_csi_hw_disable_irq(csi);
0511 }
0512
0513 static void imx7_csi_configure(struct imx7_csi *csi)
0514 {
0515 struct v4l2_pix_format *out_pix = &csi->vdev_fmt;
0516 int width = out_pix->width;
0517 u32 stride = 0;
0518 u32 cr3 = BIT_FRMCNT_RST;
0519 u32 cr1, cr18;
0520
0521 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
0522
0523 cr18 &= ~(BIT_CSI_HW_ENABLE | BIT_MIPI_DATA_FORMAT_MASK |
0524 BIT_DATA_FROM_MIPI | BIT_BASEADDR_CHG_ERR_EN |
0525 BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
0526 BIT_DEINTERLACE_EN);
0527
0528 if (out_pix->field == V4L2_FIELD_INTERLACED) {
0529 cr18 |= BIT_DEINTERLACE_EN;
0530 stride = out_pix->width;
0531 }
0532
0533 if (!csi->is_csi2) {
0534 cr1 = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL
0535 | BIT_FCC | BIT_MCLKDIV(1) | BIT_MCLKEN;
0536
0537 cr18 |= BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
0538 BIT_BASEADDR_CHG_ERR_EN;
0539
0540 if (out_pix->pixelformat == V4L2_PIX_FMT_UYVY ||
0541 out_pix->pixelformat == V4L2_PIX_FMT_YUYV)
0542 width *= 2;
0543 } else {
0544 cr1 = BIT_SOF_POL | BIT_REDGE | BIT_HSYNC_POL | BIT_FCC
0545 | BIT_MCLKDIV(1) | BIT_MCLKEN;
0546
0547 cr18 |= BIT_DATA_FROM_MIPI;
0548
0549 switch (csi->format_mbus[IMX7_CSI_PAD_SINK].code) {
0550 case MEDIA_BUS_FMT_Y8_1X8:
0551 case MEDIA_BUS_FMT_SBGGR8_1X8:
0552 case MEDIA_BUS_FMT_SGBRG8_1X8:
0553 case MEDIA_BUS_FMT_SGRBG8_1X8:
0554 case MEDIA_BUS_FMT_SRGGB8_1X8:
0555 cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;
0556 break;
0557 case MEDIA_BUS_FMT_Y10_1X10:
0558 case MEDIA_BUS_FMT_SBGGR10_1X10:
0559 case MEDIA_BUS_FMT_SGBRG10_1X10:
0560 case MEDIA_BUS_FMT_SGRBG10_1X10:
0561 case MEDIA_BUS_FMT_SRGGB10_1X10:
0562 cr3 |= BIT_TWO_8BIT_SENSOR;
0563 cr18 |= BIT_MIPI_DATA_FORMAT_RAW10;
0564 break;
0565 case MEDIA_BUS_FMT_Y12_1X12:
0566 case MEDIA_BUS_FMT_SBGGR12_1X12:
0567 case MEDIA_BUS_FMT_SGBRG12_1X12:
0568 case MEDIA_BUS_FMT_SGRBG12_1X12:
0569 case MEDIA_BUS_FMT_SRGGB12_1X12:
0570 cr3 |= BIT_TWO_8BIT_SENSOR;
0571 cr18 |= BIT_MIPI_DATA_FORMAT_RAW12;
0572 break;
0573 case MEDIA_BUS_FMT_Y14_1X14:
0574 case MEDIA_BUS_FMT_SBGGR14_1X14:
0575 case MEDIA_BUS_FMT_SGBRG14_1X14:
0576 case MEDIA_BUS_FMT_SGRBG14_1X14:
0577 case MEDIA_BUS_FMT_SRGGB14_1X14:
0578 cr3 |= BIT_TWO_8BIT_SENSOR;
0579 cr18 |= BIT_MIPI_DATA_FORMAT_RAW14;
0580 break;
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 case MEDIA_BUS_FMT_UYVY8_2X8:
0606 case MEDIA_BUS_FMT_YUYV8_2X8:
0607 cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B;
0608 break;
0609 case MEDIA_BUS_FMT_UYVY8_1X16:
0610 case MEDIA_BUS_FMT_YUYV8_1X16:
0611 cr3 |= BIT_TWO_8BIT_SENSOR;
0612 cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B |
0613 BIT_MIPI_DOUBLE_CMPNT;
0614 break;
0615 }
0616 }
0617
0618 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
0619 imx7_csi_reg_write(csi, BIT_DMA_BURST_TYPE_RFF_INCR16, CSI_CSICR2);
0620 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
0621 imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
0622
0623 imx7_csi_reg_write(csi, (width * out_pix->height) >> 2, CSI_CSIRXCNT);
0624 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(width) |
0625 BIT_IMAGE_HEIGHT(out_pix->height),
0626 CSI_CSIIMAG_PARA);
0627 imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA);
0628 }
0629
0630 static int imx7_csi_init(struct imx7_csi *csi)
0631 {
0632 int ret;
0633
0634 ret = clk_prepare_enable(csi->mclk);
0635 if (ret < 0)
0636 return ret;
0637
0638 imx7_csi_configure(csi);
0639
0640 ret = imx7_csi_dma_setup(csi);
0641 if (ret < 0)
0642 return ret;
0643
0644 return 0;
0645 }
0646
0647 static void imx7_csi_deinit(struct imx7_csi *csi,
0648 enum vb2_buffer_state return_status)
0649 {
0650 imx7_csi_dma_cleanup(csi, return_status);
0651 imx7_csi_init_default(csi);
0652 imx7_csi_dmareq_rff_disable(csi);
0653 clk_disable_unprepare(csi->mclk);
0654 }
0655
0656 static void imx7_csi_baseaddr_switch_on_second_frame(struct imx7_csi *csi)
0657 {
0658 u32 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
0659
0660 cr18 |= BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
0661 BIT_BASEADDR_CHG_ERR_EN;
0662 cr18 |= BIT_MASK_OPTION_SECOND_FRAME;
0663 imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
0664 }
0665
0666 static void imx7_csi_enable(struct imx7_csi *csi)
0667 {
0668
0669 imx7_csi_rx_fifo_clear(csi);
0670 imx7_csi_dma_reflash(csi);
0671
0672 usleep_range(2000, 3000);
0673
0674
0675 imx7_csi_irq_clear(csi);
0676 imx7_csi_hw_enable_irq(csi);
0677
0678
0679 imx7_csi_dmareq_rff_enable(csi);
0680 imx7_csi_hw_enable(csi);
0681
0682 if (csi->model == IMX7_CSI_IMX8MQ)
0683 imx7_csi_baseaddr_switch_on_second_frame(csi);
0684 }
0685
0686 static void imx7_csi_disable(struct imx7_csi *csi)
0687 {
0688 imx7_csi_dma_stop(csi);
0689
0690 imx7_csi_dmareq_rff_disable(csi);
0691
0692 imx7_csi_hw_disable_irq(csi);
0693
0694 imx7_csi_hw_disable(csi);
0695 }
0696
0697
0698
0699
0700
0701 static void imx7_csi_error_recovery(struct imx7_csi *csi)
0702 {
0703 imx7_csi_hw_disable(csi);
0704
0705 imx7_csi_rx_fifo_clear(csi);
0706
0707 imx7_csi_dma_reflash(csi);
0708
0709 imx7_csi_hw_enable(csi);
0710 }
0711
0712 static void imx7_csi_vb2_buf_done(struct imx7_csi *csi)
0713 {
0714 struct imx7_csi_vb2_buffer *done, *next;
0715 struct vb2_buffer *vb;
0716 dma_addr_t phys;
0717
0718 done = csi->active_vb2_buf[csi->buf_num];
0719 if (done) {
0720 done->vbuf.field = csi->vdev_fmt.field;
0721 done->vbuf.sequence = csi->frame_sequence;
0722 vb = &done->vbuf.vb2_buf;
0723 vb->timestamp = ktime_get_ns();
0724 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
0725 }
0726 csi->frame_sequence++;
0727
0728
0729 next = imx7_csi_video_next_buf(csi);
0730 if (next) {
0731 phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0);
0732 csi->active_vb2_buf[csi->buf_num] = next;
0733 } else {
0734 phys = csi->underrun_buf.phys;
0735 csi->active_vb2_buf[csi->buf_num] = NULL;
0736 }
0737
0738 imx7_csi_update_buf(csi, phys, csi->buf_num);
0739 }
0740
0741 static irqreturn_t imx7_csi_irq_handler(int irq, void *data)
0742 {
0743 struct imx7_csi *csi = data;
0744 u32 status;
0745
0746 spin_lock(&csi->irqlock);
0747
0748 status = imx7_csi_irq_clear(csi);
0749
0750 if (status & BIT_RFF_OR_INT) {
0751 dev_warn(csi->dev, "Rx fifo overflow\n");
0752 imx7_csi_error_recovery(csi);
0753 }
0754
0755 if (status & BIT_HRESP_ERR_INT) {
0756 dev_warn(csi->dev, "Hresponse error detected\n");
0757 imx7_csi_error_recovery(csi);
0758 }
0759
0760 if (status & BIT_ADDR_CH_ERR_INT) {
0761 imx7_csi_hw_disable(csi);
0762
0763 imx7_csi_dma_reflash(csi);
0764
0765 imx7_csi_hw_enable(csi);
0766 }
0767
0768 if ((status & BIT_DMA_TSF_DONE_FB1) &&
0769 (status & BIT_DMA_TSF_DONE_FB2)) {
0770
0771
0772
0773
0774
0775
0776
0777
0778 } else if (status & BIT_DMA_TSF_DONE_FB1) {
0779 csi->buf_num = 0;
0780 } else if (status & BIT_DMA_TSF_DONE_FB2) {
0781 csi->buf_num = 1;
0782 }
0783
0784 if ((status & BIT_DMA_TSF_DONE_FB1) ||
0785 (status & BIT_DMA_TSF_DONE_FB2)) {
0786 imx7_csi_vb2_buf_done(csi);
0787
0788 if (csi->last_eof) {
0789 complete(&csi->last_eof_completion);
0790 csi->last_eof = false;
0791 }
0792 }
0793
0794 spin_unlock(&csi->irqlock);
0795
0796 return IRQ_HANDLED;
0797 }
0798
0799
0800
0801
0802
0803 #define IMX_BUS_FMTS(fmt...) (const u32[]) {fmt, 0}
0804
0805
0806
0807
0808
0809
0810 static const struct imx7_csi_pixfmt pixel_formats[] = {
0811
0812 {
0813 .fourcc = V4L2_PIX_FMT_UYVY,
0814 .codes = IMX_BUS_FMTS(
0815 MEDIA_BUS_FMT_UYVY8_2X8,
0816 MEDIA_BUS_FMT_UYVY8_1X16
0817 ),
0818 .yuv = true,
0819 .bpp = 16,
0820 }, {
0821 .fourcc = V4L2_PIX_FMT_YUYV,
0822 .codes = IMX_BUS_FMTS(
0823 MEDIA_BUS_FMT_YUYV8_2X8,
0824 MEDIA_BUS_FMT_YUYV8_1X16
0825 ),
0826 .yuv = true,
0827 .bpp = 16,
0828 },
0829
0830 {
0831 .fourcc = V4L2_PIX_FMT_SBGGR8,
0832 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SBGGR8_1X8),
0833 .bpp = 8,
0834 }, {
0835 .fourcc = V4L2_PIX_FMT_SGBRG8,
0836 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGBRG8_1X8),
0837 .bpp = 8,
0838 }, {
0839 .fourcc = V4L2_PIX_FMT_SGRBG8,
0840 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGRBG8_1X8),
0841 .bpp = 8,
0842 }, {
0843 .fourcc = V4L2_PIX_FMT_SRGGB8,
0844 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SRGGB8_1X8),
0845 .bpp = 8,
0846 }, {
0847 .fourcc = V4L2_PIX_FMT_SBGGR10,
0848 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SBGGR10_1X10),
0849 .bpp = 16,
0850 }, {
0851 .fourcc = V4L2_PIX_FMT_SGBRG10,
0852 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGBRG10_1X10),
0853 .bpp = 16,
0854 }, {
0855 .fourcc = V4L2_PIX_FMT_SGRBG10,
0856 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGRBG10_1X10),
0857 .bpp = 16,
0858 }, {
0859 .fourcc = V4L2_PIX_FMT_SRGGB10,
0860 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SRGGB10_1X10),
0861 .bpp = 16,
0862 }, {
0863 .fourcc = V4L2_PIX_FMT_SBGGR12,
0864 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SBGGR12_1X12),
0865 .bpp = 16,
0866 }, {
0867 .fourcc = V4L2_PIX_FMT_SGBRG12,
0868 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGBRG12_1X12),
0869 .bpp = 16,
0870 }, {
0871 .fourcc = V4L2_PIX_FMT_SGRBG12,
0872 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGRBG12_1X12),
0873 .bpp = 16,
0874 }, {
0875 .fourcc = V4L2_PIX_FMT_SRGGB12,
0876 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SRGGB12_1X12),
0877 .bpp = 16,
0878 }, {
0879 .fourcc = V4L2_PIX_FMT_SBGGR14,
0880 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SBGGR14_1X14),
0881 .bpp = 16,
0882 }, {
0883 .fourcc = V4L2_PIX_FMT_SGBRG14,
0884 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGBRG14_1X14),
0885 .bpp = 16,
0886 }, {
0887 .fourcc = V4L2_PIX_FMT_SGRBG14,
0888 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGRBG14_1X14),
0889 .bpp = 16,
0890 }, {
0891 .fourcc = V4L2_PIX_FMT_SRGGB14,
0892 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SRGGB14_1X14),
0893 .bpp = 16,
0894 }, {
0895 .fourcc = V4L2_PIX_FMT_GREY,
0896 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_Y8_1X8),
0897 .bpp = 8,
0898 }, {
0899 .fourcc = V4L2_PIX_FMT_Y10,
0900 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_Y10_1X10),
0901 .bpp = 16,
0902 }, {
0903 .fourcc = V4L2_PIX_FMT_Y12,
0904 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_Y12_1X12),
0905 .bpp = 16,
0906 }, {
0907 .fourcc = V4L2_PIX_FMT_Y14,
0908 .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_Y14_1X14),
0909 .bpp = 16,
0910 },
0911 };
0912
0913
0914
0915
0916
0917 static const struct imx7_csi_pixfmt *imx7_csi_find_pixel_format(u32 fourcc)
0918 {
0919 unsigned int i;
0920
0921 for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
0922 const struct imx7_csi_pixfmt *fmt = &pixel_formats[i];
0923
0924 if (fmt->fourcc == fourcc)
0925 return fmt;
0926 }
0927
0928 return NULL;
0929 }
0930
0931
0932
0933
0934
0935 static const struct imx7_csi_pixfmt *imx7_csi_find_mbus_format(u32 code)
0936 {
0937 unsigned int i;
0938
0939 for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
0940 const struct imx7_csi_pixfmt *fmt = &pixel_formats[i];
0941 unsigned int j;
0942
0943 if (!fmt->codes)
0944 continue;
0945
0946 for (j = 0; fmt->codes[j]; j++) {
0947 if (code == fmt->codes[j])
0948 return fmt;
0949 }
0950 }
0951
0952 return NULL;
0953 }
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964 static int imx7_csi_enum_mbus_formats(u32 *code, u32 index)
0965 {
0966 unsigned int i;
0967
0968 for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
0969 const struct imx7_csi_pixfmt *fmt = &pixel_formats[i];
0970 unsigned int j;
0971
0972 if (!fmt->codes)
0973 continue;
0974
0975 for (j = 0; fmt->codes[j]; j++) {
0976 if (index == 0) {
0977 *code = fmt->codes[j];
0978 return 0;
0979 }
0980
0981 index--;
0982 }
0983 }
0984
0985 return -EINVAL;
0986 }
0987
0988 static int imx7_csi_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
0989 const struct v4l2_mbus_framefmt *mbus,
0990 const struct imx7_csi_pixfmt *cc)
0991 {
0992 u32 width;
0993 u32 stride;
0994
0995 if (!cc) {
0996 cc = imx7_csi_find_mbus_format(mbus->code);
0997 if (!cc)
0998 return -EINVAL;
0999 }
1000
1001
1002 width = round_up(mbus->width, 8);
1003
1004
1005 stride = round_up((width * cc->bpp) >> 3, 8);
1006
1007 pix->width = width;
1008 pix->height = mbus->height;
1009 pix->pixelformat = cc->fourcc;
1010 pix->colorspace = mbus->colorspace;
1011 pix->xfer_func = mbus->xfer_func;
1012 pix->ycbcr_enc = mbus->ycbcr_enc;
1013 pix->quantization = mbus->quantization;
1014 pix->field = mbus->field;
1015 pix->bytesperline = stride;
1016 pix->sizeimage = stride * pix->height;
1017
1018 return 0;
1019 }
1020
1021
1022
1023
1024
1025 static int imx7_csi_video_querycap(struct file *file, void *fh,
1026 struct v4l2_capability *cap)
1027 {
1028 struct imx7_csi *csi = video_drvdata(file);
1029
1030 strscpy(cap->driver, IMX7_CSI_VIDEO_NAME, sizeof(cap->driver));
1031 strscpy(cap->card, IMX7_CSI_VIDEO_NAME, sizeof(cap->card));
1032 snprintf(cap->bus_info, sizeof(cap->bus_info),
1033 "platform:%s", dev_name(csi->dev));
1034
1035 return 0;
1036 }
1037
1038 static int imx7_csi_video_enum_fmt_vid_cap(struct file *file, void *fh,
1039 struct v4l2_fmtdesc *f)
1040 {
1041 unsigned int index = f->index;
1042 unsigned int i;
1043
1044 for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
1045 const struct imx7_csi_pixfmt *fmt = &pixel_formats[i];
1046
1047
1048
1049
1050
1051 if (f->mbus_code) {
1052 unsigned int j;
1053
1054 if (!fmt->codes)
1055 continue;
1056
1057 for (j = 0; fmt->codes[j]; j++) {
1058 if (f->mbus_code == fmt->codes[j])
1059 break;
1060 }
1061
1062 if (!fmt->codes[j])
1063 continue;
1064 }
1065
1066 if (index == 0) {
1067 f->pixelformat = fmt->fourcc;
1068 return 0;
1069 }
1070
1071 index--;
1072 }
1073
1074 return -EINVAL;
1075 }
1076
1077 static int imx7_csi_video_enum_framesizes(struct file *file, void *fh,
1078 struct v4l2_frmsizeenum *fsize)
1079 {
1080 const struct imx7_csi_pixfmt *cc;
1081
1082 if (fsize->index > 0)
1083 return -EINVAL;
1084
1085 cc = imx7_csi_find_pixel_format(fsize->pixel_format);
1086 if (!cc)
1087 return -EINVAL;
1088
1089
1090
1091
1092
1093
1094 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
1095 fsize->stepwise.min_width = 1;
1096 fsize->stepwise.max_width = 65535;
1097 fsize->stepwise.min_height = 1;
1098 fsize->stepwise.max_height = 65535;
1099 fsize->stepwise.step_width = 1;
1100 fsize->stepwise.step_height = 1;
1101
1102 return 0;
1103 }
1104
1105 static int imx7_csi_video_g_fmt_vid_cap(struct file *file, void *fh,
1106 struct v4l2_format *f)
1107 {
1108 struct imx7_csi *csi = video_drvdata(file);
1109
1110 f->fmt.pix = csi->vdev_fmt;
1111
1112 return 0;
1113 }
1114
1115 static const struct imx7_csi_pixfmt *
1116 __imx7_csi_video_try_fmt(struct v4l2_pix_format *pixfmt,
1117 struct v4l2_rect *compose)
1118 {
1119 struct v4l2_mbus_framefmt fmt_src;
1120 const struct imx7_csi_pixfmt *cc;
1121
1122
1123
1124
1125
1126 cc = imx7_csi_find_pixel_format(pixfmt->pixelformat);
1127 if (!cc) {
1128 pixfmt->pixelformat = IMX7_CSI_DEF_PIX_FORMAT;
1129 cc = imx7_csi_find_pixel_format(pixfmt->pixelformat);
1130 }
1131
1132
1133 if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) {
1134 switch (pixfmt->field) {
1135 case V4L2_FIELD_SEQ_TB:
1136 pixfmt->field = V4L2_FIELD_INTERLACED_TB;
1137 break;
1138 case V4L2_FIELD_SEQ_BT:
1139 pixfmt->field = V4L2_FIELD_INTERLACED_BT;
1140 break;
1141 default:
1142 break;
1143 }
1144 }
1145
1146 v4l2_fill_mbus_format(&fmt_src, pixfmt, 0);
1147 imx7_csi_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src, cc);
1148
1149 if (compose) {
1150 compose->width = fmt_src.width;
1151 compose->height = fmt_src.height;
1152 }
1153
1154 return cc;
1155 }
1156
1157 static int imx7_csi_video_try_fmt_vid_cap(struct file *file, void *fh,
1158 struct v4l2_format *f)
1159 {
1160 __imx7_csi_video_try_fmt(&f->fmt.pix, NULL);
1161 return 0;
1162 }
1163
1164 static int imx7_csi_video_s_fmt_vid_cap(struct file *file, void *fh,
1165 struct v4l2_format *f)
1166 {
1167 struct imx7_csi *csi = video_drvdata(file);
1168 const struct imx7_csi_pixfmt *cc;
1169
1170 if (vb2_is_busy(&csi->q)) {
1171 dev_err(csi->dev, "%s queue busy\n", __func__);
1172 return -EBUSY;
1173 }
1174
1175 cc = __imx7_csi_video_try_fmt(&f->fmt.pix, &csi->vdev_compose);
1176
1177 csi->vdev_cc = cc;
1178 csi->vdev_fmt = f->fmt.pix;
1179
1180 return 0;
1181 }
1182
1183 static int imx7_csi_video_g_selection(struct file *file, void *fh,
1184 struct v4l2_selection *s)
1185 {
1186 struct imx7_csi *csi = video_drvdata(file);
1187
1188 switch (s->target) {
1189 case V4L2_SEL_TGT_COMPOSE:
1190 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1191 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1192
1193 s->r = csi->vdev_compose;
1194 break;
1195 case V4L2_SEL_TGT_COMPOSE_PADDED:
1196
1197
1198
1199
1200
1201 s->r.left = 0;
1202 s->r.top = 0;
1203 s->r.width = csi->vdev_fmt.width;
1204 s->r.height = csi->vdev_fmt.height;
1205 break;
1206 default:
1207 return -EINVAL;
1208 }
1209
1210 return 0;
1211 }
1212
1213 static const struct v4l2_ioctl_ops imx7_csi_video_ioctl_ops = {
1214 .vidioc_querycap = imx7_csi_video_querycap,
1215
1216 .vidioc_enum_fmt_vid_cap = imx7_csi_video_enum_fmt_vid_cap,
1217 .vidioc_enum_framesizes = imx7_csi_video_enum_framesizes,
1218
1219 .vidioc_g_fmt_vid_cap = imx7_csi_video_g_fmt_vid_cap,
1220 .vidioc_try_fmt_vid_cap = imx7_csi_video_try_fmt_vid_cap,
1221 .vidioc_s_fmt_vid_cap = imx7_csi_video_s_fmt_vid_cap,
1222
1223 .vidioc_g_selection = imx7_csi_video_g_selection,
1224
1225 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1226 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1227 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1228 .vidioc_querybuf = vb2_ioctl_querybuf,
1229 .vidioc_qbuf = vb2_ioctl_qbuf,
1230 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1231 .vidioc_expbuf = vb2_ioctl_expbuf,
1232 .vidioc_streamon = vb2_ioctl_streamon,
1233 .vidioc_streamoff = vb2_ioctl_streamoff,
1234 };
1235
1236
1237
1238
1239
1240 static int imx7_csi_video_queue_setup(struct vb2_queue *vq,
1241 unsigned int *nbuffers,
1242 unsigned int *nplanes,
1243 unsigned int sizes[],
1244 struct device *alloc_devs[])
1245 {
1246 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1247 struct v4l2_pix_format *pix = &csi->vdev_fmt;
1248 unsigned int count = *nbuffers;
1249
1250 if (vq->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1251 return -EINVAL;
1252
1253 if (*nplanes) {
1254 if (*nplanes != 1 || sizes[0] < pix->sizeimage)
1255 return -EINVAL;
1256 count += vq->num_buffers;
1257 }
1258
1259 count = min_t(__u32, IMX7_CSI_VIDEO_MEM_LIMIT / pix->sizeimage, count);
1260
1261 if (*nplanes)
1262 *nbuffers = (count < vq->num_buffers) ? 0 :
1263 count - vq->num_buffers;
1264 else
1265 *nbuffers = count;
1266
1267 *nplanes = 1;
1268 sizes[0] = pix->sizeimage;
1269
1270 return 0;
1271 }
1272
1273 static int imx7_csi_video_buf_init(struct vb2_buffer *vb)
1274 {
1275 struct imx7_csi_vb2_buffer *buf = to_imx7_csi_vb2_buffer(vb);
1276
1277 INIT_LIST_HEAD(&buf->list);
1278
1279 return 0;
1280 }
1281
1282 static int imx7_csi_video_buf_prepare(struct vb2_buffer *vb)
1283 {
1284 struct imx7_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
1285 struct v4l2_pix_format *pix = &csi->vdev_fmt;
1286
1287 if (vb2_plane_size(vb, 0) < pix->sizeimage) {
1288 dev_err(csi->dev,
1289 "data will not fit into plane (%lu < %lu)\n",
1290 vb2_plane_size(vb, 0), (long)pix->sizeimage);
1291 return -EINVAL;
1292 }
1293
1294 vb2_set_plane_payload(vb, 0, pix->sizeimage);
1295
1296 return 0;
1297 }
1298
1299 static void imx7_csi_video_buf_queue(struct vb2_buffer *vb)
1300 {
1301 struct imx7_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
1302 struct imx7_csi_vb2_buffer *buf = to_imx7_csi_vb2_buffer(vb);
1303 unsigned long flags;
1304
1305 spin_lock_irqsave(&csi->q_lock, flags);
1306
1307 list_add_tail(&buf->list, &csi->ready_q);
1308
1309 spin_unlock_irqrestore(&csi->q_lock, flags);
1310 }
1311
1312 static int imx7_csi_video_validate_fmt(struct imx7_csi *csi)
1313 {
1314 struct v4l2_subdev_format fmt_src;
1315 const struct imx7_csi_pixfmt *cc;
1316 int ret;
1317
1318
1319 fmt_src.pad = IMX7_CSI_PAD_SRC;
1320 fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1321 ret = v4l2_subdev_call(&csi->sd, pad, get_fmt, NULL, &fmt_src);
1322 if (ret)
1323 return ret;
1324
1325
1326
1327
1328
1329
1330
1331
1332 if (csi->vdev_compose.width != fmt_src.format.width ||
1333 csi->vdev_compose.height != fmt_src.format.height)
1334 return -EPIPE;
1335
1336
1337
1338
1339
1340 cc = imx7_csi_find_mbus_format(fmt_src.format.code);
1341 if (!cc || csi->vdev_cc->yuv != cc->yuv)
1342 return -EPIPE;
1343
1344 return 0;
1345 }
1346
1347 static int imx7_csi_video_start_streaming(struct vb2_queue *vq,
1348 unsigned int count)
1349 {
1350 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1351 struct imx7_csi_vb2_buffer *buf, *tmp;
1352 unsigned long flags;
1353 int ret;
1354
1355 ret = imx7_csi_video_validate_fmt(csi);
1356 if (ret) {
1357 dev_err(csi->dev, "capture format not valid\n");
1358 goto err_buffers;
1359 }
1360
1361 mutex_lock(&csi->mdev.graph_mutex);
1362
1363 ret = __media_pipeline_start(&csi->sd.entity, &csi->pipe);
1364 if (ret)
1365 goto err_unlock;
1366
1367 ret = v4l2_subdev_call(&csi->sd, video, s_stream, 1);
1368 if (ret)
1369 goto err_stop;
1370
1371 mutex_unlock(&csi->mdev.graph_mutex);
1372
1373 return 0;
1374
1375 err_stop:
1376 __media_pipeline_stop(&csi->sd.entity);
1377 err_unlock:
1378 mutex_unlock(&csi->mdev.graph_mutex);
1379 dev_err(csi->dev, "pipeline start failed with %d\n", ret);
1380 err_buffers:
1381 spin_lock_irqsave(&csi->q_lock, flags);
1382 list_for_each_entry_safe(buf, tmp, &csi->ready_q, list) {
1383 list_del(&buf->list);
1384 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
1385 }
1386 spin_unlock_irqrestore(&csi->q_lock, flags);
1387 return ret;
1388 }
1389
1390 static void imx7_csi_video_stop_streaming(struct vb2_queue *vq)
1391 {
1392 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1393 struct imx7_csi_vb2_buffer *frame;
1394 struct imx7_csi_vb2_buffer *tmp;
1395 unsigned long flags;
1396
1397 mutex_lock(&csi->mdev.graph_mutex);
1398 v4l2_subdev_call(&csi->sd, video, s_stream, 0);
1399 __media_pipeline_stop(&csi->sd.entity);
1400 mutex_unlock(&csi->mdev.graph_mutex);
1401
1402
1403 spin_lock_irqsave(&csi->q_lock, flags);
1404 list_for_each_entry_safe(frame, tmp, &csi->ready_q, list) {
1405 list_del(&frame->list);
1406 vb2_buffer_done(&frame->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
1407 }
1408 spin_unlock_irqrestore(&csi->q_lock, flags);
1409 }
1410
1411 static const struct vb2_ops imx7_csi_video_qops = {
1412 .queue_setup = imx7_csi_video_queue_setup,
1413 .buf_init = imx7_csi_video_buf_init,
1414 .buf_prepare = imx7_csi_video_buf_prepare,
1415 .buf_queue = imx7_csi_video_buf_queue,
1416 .wait_prepare = vb2_ops_wait_prepare,
1417 .wait_finish = vb2_ops_wait_finish,
1418 .start_streaming = imx7_csi_video_start_streaming,
1419 .stop_streaming = imx7_csi_video_stop_streaming,
1420 };
1421
1422
1423
1424
1425
1426 static int imx7_csi_video_open(struct file *file)
1427 {
1428 struct imx7_csi *csi = video_drvdata(file);
1429 int ret;
1430
1431 if (mutex_lock_interruptible(&csi->vdev_mutex))
1432 return -ERESTARTSYS;
1433
1434 ret = v4l2_fh_open(file);
1435 if (ret) {
1436 dev_err(csi->dev, "v4l2_fh_open failed\n");
1437 goto out;
1438 }
1439
1440 ret = v4l2_pipeline_pm_get(&csi->vdev->entity);
1441 if (ret)
1442 v4l2_fh_release(file);
1443
1444 out:
1445 mutex_unlock(&csi->vdev_mutex);
1446 return ret;
1447 }
1448
1449 static int imx7_csi_video_release(struct file *file)
1450 {
1451 struct imx7_csi *csi = video_drvdata(file);
1452 struct vb2_queue *vq = &csi->q;
1453
1454 mutex_lock(&csi->vdev_mutex);
1455
1456 if (file->private_data == vq->owner) {
1457 vb2_queue_release(vq);
1458 vq->owner = NULL;
1459 }
1460
1461 v4l2_pipeline_pm_put(&csi->vdev->entity);
1462
1463 v4l2_fh_release(file);
1464 mutex_unlock(&csi->vdev_mutex);
1465 return 0;
1466 }
1467
1468 static const struct v4l2_file_operations imx7_csi_video_fops = {
1469 .owner = THIS_MODULE,
1470 .open = imx7_csi_video_open,
1471 .release = imx7_csi_video_release,
1472 .poll = vb2_fop_poll,
1473 .unlocked_ioctl = video_ioctl2,
1474 .mmap = vb2_fop_mmap,
1475 };
1476
1477
1478
1479
1480
1481 static struct imx7_csi_vb2_buffer *imx7_csi_video_next_buf(struct imx7_csi *csi)
1482 {
1483 struct imx7_csi_vb2_buffer *buf = NULL;
1484 unsigned long flags;
1485
1486 spin_lock_irqsave(&csi->q_lock, flags);
1487
1488
1489 if (!list_empty(&csi->ready_q)) {
1490 buf = list_entry(csi->ready_q.next, struct imx7_csi_vb2_buffer,
1491 list);
1492 list_del(&buf->list);
1493 }
1494
1495 spin_unlock_irqrestore(&csi->q_lock, flags);
1496
1497 return buf;
1498 }
1499
1500 static int imx7_csi_video_init_format(struct imx7_csi *csi)
1501 {
1502 struct v4l2_subdev_format fmt_src = {
1503 .pad = IMX7_CSI_PAD_SRC,
1504 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1505 };
1506 fmt_src.format.code = IMX7_CSI_DEF_MBUS_CODE;
1507 fmt_src.format.width = IMX7_CSI_DEF_PIX_WIDTH;
1508 fmt_src.format.height = IMX7_CSI_DEF_PIX_HEIGHT;
1509
1510 imx7_csi_mbus_fmt_to_pix_fmt(&csi->vdev_fmt, &fmt_src.format, NULL);
1511 csi->vdev_compose.width = fmt_src.format.width;
1512 csi->vdev_compose.height = fmt_src.format.height;
1513
1514 csi->vdev_cc = imx7_csi_find_pixel_format(csi->vdev_fmt.pixelformat);
1515
1516 return 0;
1517 }
1518
1519 static int imx7_csi_video_register(struct imx7_csi *csi)
1520 {
1521 struct v4l2_subdev *sd = &csi->sd;
1522 struct v4l2_device *v4l2_dev = sd->v4l2_dev;
1523 struct video_device *vdev = csi->vdev;
1524 int ret;
1525
1526 vdev->v4l2_dev = v4l2_dev;
1527
1528
1529 ret = imx7_csi_video_init_format(csi);
1530 if (ret < 0)
1531 return ret;
1532
1533
1534 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1535 if (ret) {
1536 dev_err(csi->dev, "Failed to register video device\n");
1537 return ret;
1538 }
1539
1540 dev_info(csi->dev, "Registered %s as /dev/%s\n", vdev->name,
1541 video_device_node_name(vdev));
1542
1543
1544 ret = media_create_pad_link(&sd->entity, IMX7_CSI_PAD_SRC,
1545 &vdev->entity, 0, MEDIA_LNK_FL_IMMUTABLE |
1546 MEDIA_LNK_FL_ENABLED);
1547 if (ret) {
1548 dev_err(csi->dev, "failed to create link to device node\n");
1549 video_unregister_device(vdev);
1550 return ret;
1551 }
1552
1553 return 0;
1554 }
1555
1556 static void imx7_csi_video_unregister(struct imx7_csi *csi)
1557 {
1558 media_entity_cleanup(&csi->vdev->entity);
1559 video_unregister_device(csi->vdev);
1560 }
1561
1562 static int imx7_csi_video_init(struct imx7_csi *csi)
1563 {
1564 struct video_device *vdev;
1565 struct vb2_queue *vq;
1566 int ret;
1567
1568 mutex_init(&csi->vdev_mutex);
1569 INIT_LIST_HEAD(&csi->ready_q);
1570 spin_lock_init(&csi->q_lock);
1571
1572
1573 vdev = video_device_alloc();
1574 if (!vdev)
1575 return -ENOMEM;
1576
1577 vdev->fops = &imx7_csi_video_fops;
1578 vdev->ioctl_ops = &imx7_csi_video_ioctl_ops;
1579 vdev->minor = -1;
1580 vdev->release = video_device_release;
1581 vdev->vfl_dir = VFL_DIR_RX;
1582 vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1583 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
1584 | V4L2_CAP_IO_MC;
1585 vdev->lock = &csi->vdev_mutex;
1586 vdev->queue = &csi->q;
1587
1588 snprintf(vdev->name, sizeof(vdev->name), "%s capture", csi->sd.name);
1589
1590 video_set_drvdata(vdev, csi);
1591 csi->vdev = vdev;
1592
1593
1594 csi->vdev_pad.flags = MEDIA_PAD_FL_SINK;
1595 ret = media_entity_pads_init(&vdev->entity, 1, &csi->vdev_pad);
1596 if (ret) {
1597 video_device_release(vdev);
1598 return ret;
1599 }
1600
1601
1602 vq = &csi->q;
1603 vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1604 vq->io_modes = VB2_MMAP | VB2_DMABUF;
1605 vq->drv_priv = csi;
1606 vq->buf_struct_size = sizeof(struct imx7_csi_vb2_buffer);
1607 vq->ops = &imx7_csi_video_qops;
1608 vq->mem_ops = &vb2_dma_contig_memops;
1609 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1610 vq->lock = &csi->vdev_mutex;
1611 vq->min_buffers_needed = 2;
1612 vq->dev = csi->dev;
1613
1614 ret = vb2_queue_init(vq);
1615 if (ret) {
1616 dev_err(csi->dev, "vb2_queue_init failed\n");
1617 video_device_release(vdev);
1618 return ret;
1619 }
1620
1621 return 0;
1622 }
1623
1624
1625
1626
1627
1628 static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable)
1629 {
1630 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1631 int ret = 0;
1632
1633 mutex_lock(&csi->lock);
1634
1635 if (!csi->src_sd) {
1636 ret = -EPIPE;
1637 goto out_unlock;
1638 }
1639
1640 if (csi->is_streaming == !!enable)
1641 goto out_unlock;
1642
1643 if (enable) {
1644 ret = imx7_csi_init(csi);
1645 if (ret < 0)
1646 goto out_unlock;
1647
1648 ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1);
1649 if (ret < 0) {
1650 imx7_csi_deinit(csi, VB2_BUF_STATE_QUEUED);
1651 goto out_unlock;
1652 }
1653
1654 imx7_csi_enable(csi);
1655 } else {
1656 imx7_csi_disable(csi);
1657
1658 v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
1659
1660 imx7_csi_deinit(csi, VB2_BUF_STATE_ERROR);
1661 }
1662
1663 csi->is_streaming = !!enable;
1664
1665 out_unlock:
1666 mutex_unlock(&csi->lock);
1667
1668 return ret;
1669 }
1670
1671 static struct v4l2_mbus_framefmt *
1672 imx7_csi_get_format(struct imx7_csi *csi,
1673 struct v4l2_subdev_state *sd_state,
1674 unsigned int pad,
1675 enum v4l2_subdev_format_whence which)
1676 {
1677 if (which == V4L2_SUBDEV_FORMAT_TRY)
1678 return v4l2_subdev_get_try_format(&csi->sd, sd_state, pad);
1679
1680 return &csi->format_mbus[pad];
1681 }
1682
1683 static int imx7_csi_init_cfg(struct v4l2_subdev *sd,
1684 struct v4l2_subdev_state *sd_state)
1685 {
1686 const enum v4l2_subdev_format_whence which =
1687 sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1688 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1689 const struct imx7_csi_pixfmt *cc;
1690 int i;
1691
1692 cc = imx7_csi_find_mbus_format(IMX7_CSI_DEF_MBUS_CODE);
1693
1694 for (i = 0; i < IMX7_CSI_PADS_NUM; i++) {
1695 struct v4l2_mbus_framefmt *mf =
1696 imx7_csi_get_format(csi, sd_state, i, which);
1697
1698 mf->code = IMX7_CSI_DEF_MBUS_CODE;
1699 mf->width = IMX7_CSI_DEF_PIX_WIDTH;
1700 mf->height = IMX7_CSI_DEF_PIX_HEIGHT;
1701 mf->field = V4L2_FIELD_NONE;
1702
1703 mf->colorspace = V4L2_COLORSPACE_SRGB;
1704 mf->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(mf->colorspace);
1705 mf->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(mf->colorspace);
1706 mf->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(!cc->yuv,
1707 mf->colorspace, mf->ycbcr_enc);
1708
1709 csi->cc[i] = cc;
1710 }
1711
1712 return 0;
1713 }
1714
1715 static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd,
1716 struct v4l2_subdev_state *sd_state,
1717 struct v4l2_subdev_mbus_code_enum *code)
1718 {
1719 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1720 struct v4l2_mbus_framefmt *in_fmt;
1721 int ret = 0;
1722
1723 mutex_lock(&csi->lock);
1724
1725 in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK,
1726 code->which);
1727
1728 switch (code->pad) {
1729 case IMX7_CSI_PAD_SINK:
1730 ret = imx7_csi_enum_mbus_formats(&code->code, code->index);
1731 break;
1732 case IMX7_CSI_PAD_SRC:
1733 if (code->index != 0) {
1734 ret = -EINVAL;
1735 goto out_unlock;
1736 }
1737
1738 code->code = in_fmt->code;
1739 break;
1740 default:
1741 ret = -EINVAL;
1742 }
1743
1744 out_unlock:
1745 mutex_unlock(&csi->lock);
1746
1747 return ret;
1748 }
1749
1750 static int imx7_csi_get_fmt(struct v4l2_subdev *sd,
1751 struct v4l2_subdev_state *sd_state,
1752 struct v4l2_subdev_format *sdformat)
1753 {
1754 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1755 struct v4l2_mbus_framefmt *fmt;
1756 int ret = 0;
1757
1758 mutex_lock(&csi->lock);
1759
1760 fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad,
1761 sdformat->which);
1762 if (!fmt) {
1763 ret = -EINVAL;
1764 goto out_unlock;
1765 }
1766
1767 sdformat->format = *fmt;
1768
1769 out_unlock:
1770 mutex_unlock(&csi->lock);
1771
1772 return ret;
1773 }
1774
1775
1776
1777
1778
1779
1780
1781
1782 static void imx7_csi_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt)
1783 {
1784 const struct imx7_csi_pixfmt *cc;
1785 bool is_rgb = false;
1786
1787 cc = imx7_csi_find_mbus_format(tryfmt->code);
1788 if (cc && !cc->yuv)
1789 is_rgb = true;
1790
1791 switch (tryfmt->colorspace) {
1792 case V4L2_COLORSPACE_SMPTE170M:
1793 case V4L2_COLORSPACE_REC709:
1794 case V4L2_COLORSPACE_JPEG:
1795 case V4L2_COLORSPACE_SRGB:
1796 case V4L2_COLORSPACE_BT2020:
1797 case V4L2_COLORSPACE_OPRGB:
1798 case V4L2_COLORSPACE_DCI_P3:
1799 case V4L2_COLORSPACE_RAW:
1800 break;
1801 default:
1802 tryfmt->colorspace = V4L2_COLORSPACE_SRGB;
1803 break;
1804 }
1805
1806 if (tryfmt->xfer_func == V4L2_XFER_FUNC_DEFAULT)
1807 tryfmt->xfer_func =
1808 V4L2_MAP_XFER_FUNC_DEFAULT(tryfmt->colorspace);
1809
1810 if (tryfmt->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
1811 tryfmt->ycbcr_enc =
1812 V4L2_MAP_YCBCR_ENC_DEFAULT(tryfmt->colorspace);
1813
1814 if (tryfmt->quantization == V4L2_QUANTIZATION_DEFAULT)
1815 tryfmt->quantization =
1816 V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb,
1817 tryfmt->colorspace,
1818 tryfmt->ycbcr_enc);
1819 }
1820
1821 static int imx7_csi_try_fmt(struct imx7_csi *csi,
1822 struct v4l2_subdev_state *sd_state,
1823 struct v4l2_subdev_format *sdformat,
1824 const struct imx7_csi_pixfmt **cc)
1825 {
1826 const struct imx7_csi_pixfmt *in_cc;
1827 struct v4l2_mbus_framefmt *in_fmt;
1828 u32 code;
1829
1830 in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK,
1831 sdformat->which);
1832 if (!in_fmt)
1833 return -EINVAL;
1834
1835 switch (sdformat->pad) {
1836 case IMX7_CSI_PAD_SRC:
1837 in_cc = imx7_csi_find_mbus_format(in_fmt->code);
1838
1839 sdformat->format.width = in_fmt->width;
1840 sdformat->format.height = in_fmt->height;
1841 sdformat->format.code = in_fmt->code;
1842 sdformat->format.field = in_fmt->field;
1843 *cc = in_cc;
1844
1845 sdformat->format.colorspace = in_fmt->colorspace;
1846 sdformat->format.xfer_func = in_fmt->xfer_func;
1847 sdformat->format.quantization = in_fmt->quantization;
1848 sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc;
1849 break;
1850 case IMX7_CSI_PAD_SINK:
1851 *cc = imx7_csi_find_mbus_format(sdformat->format.code);
1852 if (!*cc) {
1853 code = IMX7_CSI_DEF_MBUS_CODE;
1854 *cc = imx7_csi_find_mbus_format(code);
1855 sdformat->format.code = code;
1856 }
1857
1858 if (sdformat->format.field != V4L2_FIELD_INTERLACED)
1859 sdformat->format.field = V4L2_FIELD_NONE;
1860 break;
1861 default:
1862 return -EINVAL;
1863 }
1864
1865 imx7_csi_try_colorimetry(&sdformat->format);
1866
1867 return 0;
1868 }
1869
1870 static int imx7_csi_set_fmt(struct v4l2_subdev *sd,
1871 struct v4l2_subdev_state *sd_state,
1872 struct v4l2_subdev_format *sdformat)
1873 {
1874 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1875 const struct imx7_csi_pixfmt *outcc;
1876 struct v4l2_mbus_framefmt *outfmt;
1877 const struct imx7_csi_pixfmt *cc;
1878 struct v4l2_mbus_framefmt *fmt;
1879 struct v4l2_subdev_format format;
1880 int ret = 0;
1881
1882 if (sdformat->pad >= IMX7_CSI_PADS_NUM)
1883 return -EINVAL;
1884
1885 mutex_lock(&csi->lock);
1886
1887 if (csi->is_streaming) {
1888 ret = -EBUSY;
1889 goto out_unlock;
1890 }
1891
1892 ret = imx7_csi_try_fmt(csi, sd_state, sdformat, &cc);
1893 if (ret < 0)
1894 goto out_unlock;
1895
1896 fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad,
1897 sdformat->which);
1898 if (!fmt) {
1899 ret = -EINVAL;
1900 goto out_unlock;
1901 }
1902
1903 *fmt = sdformat->format;
1904
1905 if (sdformat->pad == IMX7_CSI_PAD_SINK) {
1906
1907 format.pad = IMX7_CSI_PAD_SRC;
1908 format.which = sdformat->which;
1909 format.format = sdformat->format;
1910 if (imx7_csi_try_fmt(csi, sd_state, &format, &outcc)) {
1911 ret = -EINVAL;
1912 goto out_unlock;
1913 }
1914 outfmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SRC,
1915 sdformat->which);
1916 *outfmt = format.format;
1917
1918 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1919 csi->cc[IMX7_CSI_PAD_SRC] = outcc;
1920 }
1921
1922 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1923 csi->cc[sdformat->pad] = cc;
1924
1925 out_unlock:
1926 mutex_unlock(&csi->lock);
1927
1928 return ret;
1929 }
1930
1931 static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd,
1932 struct media_link *link,
1933 struct v4l2_subdev_format *source_fmt,
1934 struct v4l2_subdev_format *sink_fmt)
1935 {
1936 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1937 struct media_pad *pad = NULL;
1938 unsigned int i;
1939 int ret;
1940
1941 if (!csi->src_sd)
1942 return -EPIPE;
1943
1944
1945
1946
1947
1948 ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt);
1949 if (ret)
1950 return ret;
1951
1952 switch (csi->src_sd->entity.function) {
1953 case MEDIA_ENT_F_VID_IF_BRIDGE:
1954
1955 csi->is_csi2 = true;
1956 break;
1957
1958 case MEDIA_ENT_F_VID_MUX:
1959
1960 for (i = 0; i < csi->src_sd->entity.num_pads; i++) {
1961 struct media_pad *spad = &csi->src_sd->entity.pads[i];
1962
1963 if (!(spad->flags & MEDIA_PAD_FL_SINK))
1964 continue;
1965
1966 pad = media_pad_remote_pad_first(spad);
1967 if (pad)
1968 break;
1969 }
1970
1971 if (!pad)
1972 return -ENODEV;
1973
1974 csi->is_csi2 = pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE;
1975 break;
1976
1977 default:
1978
1979
1980
1981
1982 csi->is_csi2 = false;
1983 break;
1984 }
1985
1986 return 0;
1987 }
1988
1989 static int imx7_csi_registered(struct v4l2_subdev *sd)
1990 {
1991 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1992 int ret;
1993
1994 ret = imx7_csi_video_init(csi);
1995 if (ret)
1996 return ret;
1997
1998 ret = imx7_csi_video_register(csi);
1999 if (ret)
2000 return ret;
2001
2002 ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
2003 if (ret)
2004 goto err_unreg;
2005
2006 ret = media_device_register(&csi->mdev);
2007 if (ret)
2008 goto err_unreg;
2009
2010 return 0;
2011
2012 err_unreg:
2013 imx7_csi_video_unregister(csi);
2014 return ret;
2015 }
2016
2017 static void imx7_csi_unregistered(struct v4l2_subdev *sd)
2018 {
2019 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
2020
2021 imx7_csi_video_unregister(csi);
2022 }
2023
2024 static const struct v4l2_subdev_video_ops imx7_csi_video_ops = {
2025 .s_stream = imx7_csi_s_stream,
2026 };
2027
2028 static const struct v4l2_subdev_pad_ops imx7_csi_pad_ops = {
2029 .init_cfg = imx7_csi_init_cfg,
2030 .enum_mbus_code = imx7_csi_enum_mbus_code,
2031 .get_fmt = imx7_csi_get_fmt,
2032 .set_fmt = imx7_csi_set_fmt,
2033 .link_validate = imx7_csi_pad_link_validate,
2034 };
2035
2036 static const struct v4l2_subdev_ops imx7_csi_subdev_ops = {
2037 .video = &imx7_csi_video_ops,
2038 .pad = &imx7_csi_pad_ops,
2039 };
2040
2041 static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = {
2042 .registered = imx7_csi_registered,
2043 .unregistered = imx7_csi_unregistered,
2044 };
2045
2046
2047
2048
2049
2050 static const struct media_entity_operations imx7_csi_entity_ops = {
2051 .link_validate = v4l2_subdev_link_validate,
2052 .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
2053 };
2054
2055
2056
2057
2058
2059 static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
2060 struct v4l2_subdev *sd,
2061 struct v4l2_async_subdev *asd)
2062 {
2063 struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
2064 struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
2065
2066 csi->src_sd = sd;
2067
2068 return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED |
2069 MEDIA_LNK_FL_IMMUTABLE);
2070 }
2071
2072 static int imx7_csi_notify_complete(struct v4l2_async_notifier *notifier)
2073 {
2074 struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
2075
2076 return v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
2077 }
2078
2079 static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = {
2080 .bound = imx7_csi_notify_bound,
2081 .complete = imx7_csi_notify_complete,
2082 };
2083
2084 static int imx7_csi_async_register(struct imx7_csi *csi)
2085 {
2086 struct v4l2_async_subdev *asd;
2087 struct fwnode_handle *ep;
2088 int ret;
2089
2090 v4l2_async_nf_init(&csi->notifier);
2091
2092 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
2093 FWNODE_GRAPH_ENDPOINT_NEXT);
2094 if (ep) {
2095 asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep,
2096 struct v4l2_async_subdev);
2097
2098 fwnode_handle_put(ep);
2099
2100 if (IS_ERR(asd)) {
2101 ret = PTR_ERR(asd);
2102
2103 if (ret != -EEXIST)
2104 return ret;
2105 }
2106 }
2107
2108 csi->notifier.ops = &imx7_csi_notify_ops;
2109
2110 ret = v4l2_async_nf_register(&csi->v4l2_dev, &csi->notifier);
2111 if (ret)
2112 return ret;
2113
2114 return 0;
2115 }
2116
2117 static void imx7_csi_media_cleanup(struct imx7_csi *csi)
2118 {
2119 v4l2_device_unregister(&csi->v4l2_dev);
2120 media_device_unregister(&csi->mdev);
2121 media_device_cleanup(&csi->mdev);
2122 }
2123
2124 static const struct media_device_ops imx7_csi_media_ops = {
2125 .link_notify = v4l2_pipeline_link_notify,
2126 };
2127
2128 static int imx7_csi_media_dev_init(struct imx7_csi *csi)
2129 {
2130 int ret;
2131
2132 strscpy(csi->mdev.model, "imx-media", sizeof(csi->mdev.model));
2133 csi->mdev.ops = &imx7_csi_media_ops;
2134 csi->mdev.dev = csi->dev;
2135
2136 csi->v4l2_dev.mdev = &csi->mdev;
2137 strscpy(csi->v4l2_dev.name, "imx-media",
2138 sizeof(csi->v4l2_dev.name));
2139 snprintf(csi->mdev.bus_info, sizeof(csi->mdev.bus_info),
2140 "platform:%s", dev_name(csi->mdev.dev));
2141
2142 media_device_init(&csi->mdev);
2143
2144 ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);
2145 if (ret < 0) {
2146 v4l2_err(&csi->v4l2_dev,
2147 "Failed to register v4l2_device: %d\n", ret);
2148 goto cleanup;
2149 }
2150
2151 return 0;
2152
2153 cleanup:
2154 media_device_cleanup(&csi->mdev);
2155
2156 return ret;
2157 }
2158
2159 static int imx7_csi_media_init(struct imx7_csi *csi)
2160 {
2161 unsigned int i;
2162 int ret;
2163
2164
2165 ret = imx7_csi_media_dev_init(csi);
2166 if (ret)
2167 return ret;
2168
2169 v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops);
2170 v4l2_set_subdevdata(&csi->sd, csi);
2171 csi->sd.internal_ops = &imx7_csi_internal_ops;
2172 csi->sd.entity.ops = &imx7_csi_entity_ops;
2173 csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
2174 csi->sd.dev = csi->dev;
2175 csi->sd.owner = THIS_MODULE;
2176 csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
2177 snprintf(csi->sd.name, sizeof(csi->sd.name), "csi");
2178
2179 for (i = 0; i < IMX7_CSI_PADS_NUM; i++)
2180 csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ?
2181 MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
2182
2183 ret = media_entity_pads_init(&csi->sd.entity, IMX7_CSI_PADS_NUM,
2184 csi->pad);
2185 if (ret)
2186 goto error;
2187
2188 ret = v4l2_device_register_subdev(&csi->v4l2_dev, &csi->sd);
2189 if (ret)
2190 goto error;
2191
2192 return 0;
2193
2194 error:
2195 imx7_csi_media_cleanup(csi);
2196 return ret;
2197 }
2198
2199 static int imx7_csi_probe(struct platform_device *pdev)
2200 {
2201 struct device *dev = &pdev->dev;
2202 struct imx7_csi *csi;
2203 int ret;
2204
2205 csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
2206 if (!csi)
2207 return -ENOMEM;
2208
2209 csi->dev = dev;
2210 platform_set_drvdata(pdev, csi);
2211
2212 spin_lock_init(&csi->irqlock);
2213 mutex_init(&csi->lock);
2214
2215
2216 csi->mclk = devm_clk_get(&pdev->dev, "mclk");
2217 if (IS_ERR(csi->mclk)) {
2218 ret = PTR_ERR(csi->mclk);
2219 dev_err(dev, "Failed to get mclk: %d", ret);
2220 goto destroy_mutex;
2221 }
2222
2223 csi->irq = platform_get_irq(pdev, 0);
2224 if (csi->irq < 0) {
2225 ret = csi->irq;
2226 goto destroy_mutex;
2227 }
2228
2229 csi->regbase = devm_platform_ioremap_resource(pdev, 0);
2230 if (IS_ERR(csi->regbase)) {
2231 ret = PTR_ERR(csi->regbase);
2232 goto destroy_mutex;
2233 }
2234
2235 csi->model = (enum imx_csi_model)(uintptr_t)of_device_get_match_data(&pdev->dev);
2236
2237 ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi",
2238 (void *)csi);
2239 if (ret < 0) {
2240 dev_err(dev, "Request CSI IRQ failed.\n");
2241 goto destroy_mutex;
2242 }
2243
2244
2245 ret = imx7_csi_media_init(csi);
2246 if (ret)
2247 goto destroy_mutex;
2248
2249
2250 ret = imx7_csi_init_cfg(&csi->sd, NULL);
2251 if (ret)
2252 goto media_cleanup;
2253
2254 ret = imx7_csi_async_register(csi);
2255 if (ret)
2256 goto subdev_notifier_cleanup;
2257
2258 return 0;
2259
2260 subdev_notifier_cleanup:
2261 v4l2_async_nf_unregister(&csi->notifier);
2262 v4l2_async_nf_cleanup(&csi->notifier);
2263 media_cleanup:
2264 imx7_csi_media_cleanup(csi);
2265
2266 destroy_mutex:
2267 mutex_destroy(&csi->lock);
2268
2269 return ret;
2270 }
2271
2272 static int imx7_csi_remove(struct platform_device *pdev)
2273 {
2274 struct imx7_csi *csi = platform_get_drvdata(pdev);
2275
2276 imx7_csi_media_cleanup(csi);
2277
2278 v4l2_async_nf_unregister(&csi->notifier);
2279 v4l2_async_nf_cleanup(&csi->notifier);
2280 v4l2_async_unregister_subdev(&csi->sd);
2281
2282 mutex_destroy(&csi->lock);
2283
2284 return 0;
2285 }
2286
2287 static const struct of_device_id imx7_csi_of_match[] = {
2288 { .compatible = "fsl,imx8mq-csi", .data = (void *)IMX7_CSI_IMX8MQ },
2289 { .compatible = "fsl,imx7-csi", .data = (void *)IMX7_CSI_IMX7 },
2290 { .compatible = "fsl,imx6ul-csi", .data = (void *)IMX7_CSI_IMX7 },
2291 { },
2292 };
2293 MODULE_DEVICE_TABLE(of, imx7_csi_of_match);
2294
2295 static struct platform_driver imx7_csi_driver = {
2296 .probe = imx7_csi_probe,
2297 .remove = imx7_csi_remove,
2298 .driver = {
2299 .of_match_table = imx7_csi_of_match,
2300 .name = "imx7-csi",
2301 },
2302 };
2303 module_platform_driver(imx7_csi_driver);
2304
2305 MODULE_DESCRIPTION("i.MX7 CSI subdev driver");
2306 MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>");
2307 MODULE_LICENSE("GPL v2");
2308 MODULE_ALIAS("platform:imx7-csi");