1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * V4L2 Capture CSI Subdev for Freescale i.MX6UL/L / i.MX7 SOC
4  *
5  * Copyright (c) 2019 Linaro Ltd
6  *
7  */
8 
9 #include <linux/clk.h>
10 #include <linux/delay.h>
11 #include <linux/gcd.h>
12 #include <linux/interrupt.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/of_graph.h>
16 #include <linux/pinctrl/consumer.h>
17 #include <linux/platform_device.h>
18 #include <linux/regmap.h>
19 #include <linux/types.h>
20 
21 #include <media/v4l2-ctrls.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-event.h>
24 #include <media/v4l2-fwnode.h>
25 #include <media/v4l2-mc.h>
26 #include <media/v4l2-subdev.h>
27 #include <media/videobuf2-dma-contig.h>
28 
29 #include <media/imx.h>
30 #include "imx-media.h"
31 
32 #define IMX7_CSI_PAD_SINK	0
33 #define IMX7_CSI_PAD_SRC	1
34 #define IMX7_CSI_PADS_NUM	2
35 
36 /* reset values */
37 #define CSICR1_RESET_VAL	0x40000800
38 #define CSICR2_RESET_VAL	0x0
39 #define CSICR3_RESET_VAL	0x0
40 
41 /* csi control reg 1 */
42 #define BIT_SWAP16_EN		BIT(31)
43 #define BIT_EXT_VSYNC		BIT(30)
44 #define BIT_EOF_INT_EN		BIT(29)
45 #define BIT_PRP_IF_EN		BIT(28)
46 #define BIT_CCIR_MODE		BIT(27)
47 #define BIT_COF_INT_EN		BIT(26)
48 #define BIT_SF_OR_INTEN		BIT(25)
49 #define BIT_RF_OR_INTEN		BIT(24)
50 #define BIT_SFF_DMA_DONE_INTEN  BIT(22)
51 #define BIT_STATFF_INTEN	BIT(21)
52 #define BIT_FB2_DMA_DONE_INTEN  BIT(20)
53 #define BIT_FB1_DMA_DONE_INTEN  BIT(19)
54 #define BIT_RXFF_INTEN		BIT(18)
55 #define BIT_SOF_POL		BIT(17)
56 #define BIT_SOF_INTEN		BIT(16)
57 #define BIT_MCLKDIV		(0xF << 12)
58 #define BIT_HSYNC_POL		BIT(11)
59 #define BIT_CCIR_EN		BIT(10)
60 #define BIT_MCLKEN		BIT(9)
61 #define BIT_FCC			BIT(8)
62 #define BIT_PACK_DIR		BIT(7)
63 #define BIT_CLR_STATFIFO	BIT(6)
64 #define BIT_CLR_RXFIFO		BIT(5)
65 #define BIT_GCLK_MODE		BIT(4)
66 #define BIT_INV_DATA		BIT(3)
67 #define BIT_INV_PCLK		BIT(2)
68 #define BIT_REDGE		BIT(1)
69 #define BIT_PIXEL_BIT		BIT(0)
70 
71 #define SHIFT_MCLKDIV		12
72 
73 /* control reg 3 */
74 #define BIT_FRMCNT		(0xFFFF << 16)
75 #define BIT_FRMCNT_RST		BIT(15)
76 #define BIT_DMA_REFLASH_RFF	BIT(14)
77 #define BIT_DMA_REFLASH_SFF	BIT(13)
78 #define BIT_DMA_REQ_EN_RFF	BIT(12)
79 #define BIT_DMA_REQ_EN_SFF	BIT(11)
80 #define BIT_STATFF_LEVEL	(0x7 << 8)
81 #define BIT_HRESP_ERR_EN	BIT(7)
82 #define BIT_RXFF_LEVEL		(0x7 << 4)
83 #define BIT_TWO_8BIT_SENSOR	BIT(3)
84 #define BIT_ZERO_PACK_EN	BIT(2)
85 #define BIT_ECC_INT_EN		BIT(1)
86 #define BIT_ECC_AUTO_EN		BIT(0)
87 
88 #define SHIFT_FRMCNT		16
89 #define SHIFT_RXFIFO_LEVEL	4
90 
91 /* csi status reg */
92 #define BIT_ADDR_CH_ERR_INT	BIT(28)
93 #define BIT_FIELD0_INT		BIT(27)
94 #define BIT_FIELD1_INT		BIT(26)
95 #define BIT_SFF_OR_INT		BIT(25)
96 #define BIT_RFF_OR_INT		BIT(24)
97 #define BIT_DMA_TSF_DONE_SFF	BIT(22)
98 #define BIT_STATFF_INT		BIT(21)
99 #define BIT_DMA_TSF_DONE_FB2	BIT(20)
100 #define BIT_DMA_TSF_DONE_FB1	BIT(19)
101 #define BIT_RXFF_INT		BIT(18)
102 #define BIT_EOF_INT		BIT(17)
103 #define BIT_SOF_INT		BIT(16)
104 #define BIT_F2_INT		BIT(15)
105 #define BIT_F1_INT		BIT(14)
106 #define BIT_COF_INT		BIT(13)
107 #define BIT_HRESP_ERR_INT	BIT(7)
108 #define BIT_ECC_INT		BIT(1)
109 #define BIT_DRDY		BIT(0)
110 
111 /* csi control reg 18 */
112 #define BIT_CSI_HW_ENABLE		BIT(31)
113 #define BIT_MIPI_DATA_FORMAT_RAW8	(0x2a << 25)
114 #define BIT_MIPI_DATA_FORMAT_RAW10	(0x2b << 25)
115 #define BIT_MIPI_DATA_FORMAT_RAW12	(0x2c << 25)
116 #define BIT_MIPI_DATA_FORMAT_RAW14	(0x2d << 25)
117 #define BIT_MIPI_DATA_FORMAT_YUV422_8B	(0x1e << 25)
118 #define BIT_MIPI_DATA_FORMAT_MASK	(0x3F << 25)
119 #define BIT_MIPI_DATA_FORMAT_OFFSET	25
120 #define BIT_DATA_FROM_MIPI		BIT(22)
121 #define BIT_MIPI_YU_SWAP		BIT(21)
122 #define BIT_MIPI_DOUBLE_CMPNT		BIT(20)
123 #define BIT_BASEADDR_CHG_ERR_EN		BIT(9)
124 #define BIT_BASEADDR_SWITCH_SEL		BIT(5)
125 #define BIT_BASEADDR_SWITCH_EN		BIT(4)
126 #define BIT_PARALLEL24_EN		BIT(3)
127 #define BIT_DEINTERLACE_EN		BIT(2)
128 #define BIT_TVDECODER_IN_EN		BIT(1)
129 #define BIT_NTSC_EN			BIT(0)
130 
131 #define CSI_MCLK_VF		1
132 #define CSI_MCLK_ENC		2
133 #define CSI_MCLK_RAW		4
134 #define CSI_MCLK_I2C		8
135 
136 #define CSI_CSICR1		0x0
137 #define CSI_CSICR2		0x4
138 #define CSI_CSICR3		0x8
139 #define CSI_STATFIFO		0xC
140 #define CSI_CSIRXFIFO		0x10
141 #define CSI_CSIRXCNT		0x14
142 #define CSI_CSISR		0x18
143 
144 #define CSI_CSIDBG		0x1C
145 #define CSI_CSIDMASA_STATFIFO	0x20
146 #define CSI_CSIDMATS_STATFIFO	0x24
147 #define CSI_CSIDMASA_FB1	0x28
148 #define CSI_CSIDMASA_FB2	0x2C
149 #define CSI_CSIFBUF_PARA	0x30
150 #define CSI_CSIIMAG_PARA	0x34
151 
152 #define CSI_CSICR18		0x48
153 #define CSI_CSICR19		0x4c
154 
155 struct imx7_csi {
156 	struct device *dev;
157 	struct v4l2_subdev sd;
158 	struct v4l2_async_notifier notifier;
159 	struct imx_media_video_dev *vdev;
160 	struct imx_media_dev *imxmd;
161 	struct media_pad pad[IMX7_CSI_PADS_NUM];
162 
163 	/* lock to protect members below */
164 	struct mutex lock;
165 	/* lock to protect irq handler when stop streaming */
166 	spinlock_t irqlock;
167 
168 	struct v4l2_subdev *src_sd;
169 
170 	struct media_entity *sink;
171 
172 	struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM];
173 	const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM];
174 	struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM];
175 
176 	struct v4l2_ctrl_handler ctrl_hdlr;
177 
178 	void __iomem *regbase;
179 	int irq;
180 	struct clk *mclk;
181 
182 	/* active vb2 buffers to send to video dev sink */
183 	struct imx_media_buffer *active_vb2_buf[2];
184 	struct imx_media_dma_buf underrun_buf;
185 
186 	int buf_num;
187 	u32 frame_sequence;
188 
189 	bool last_eof;
190 	bool is_init;
191 	bool is_streaming;
192 	bool is_csi2;
193 
194 	struct completion last_eof_completion;
195 };
196 
197 static struct imx7_csi *
imx7_csi_notifier_to_dev(struct v4l2_async_notifier * n)198 imx7_csi_notifier_to_dev(struct v4l2_async_notifier *n)
199 {
200 	return container_of(n, struct imx7_csi, notifier);
201 }
202 
imx7_csi_reg_read(struct imx7_csi * csi,unsigned int offset)203 static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset)
204 {
205 	return readl(csi->regbase + offset);
206 }
207 
imx7_csi_reg_write(struct imx7_csi * csi,unsigned int value,unsigned int offset)208 static void imx7_csi_reg_write(struct imx7_csi *csi, unsigned int value,
209 			       unsigned int offset)
210 {
211 	writel(value, csi->regbase + offset);
212 }
213 
imx7_csi_hw_reset(struct imx7_csi * csi)214 static void imx7_csi_hw_reset(struct imx7_csi *csi)
215 {
216 	imx7_csi_reg_write(csi,
217 			   imx7_csi_reg_read(csi, CSI_CSICR3) | BIT_FRMCNT_RST,
218 			   CSI_CSICR3);
219 
220 	imx7_csi_reg_write(csi, CSICR1_RESET_VAL, CSI_CSICR1);
221 	imx7_csi_reg_write(csi, CSICR2_RESET_VAL, CSI_CSICR2);
222 	imx7_csi_reg_write(csi, CSICR3_RESET_VAL, CSI_CSICR3);
223 }
224 
imx7_csi_irq_clear(struct imx7_csi * csi)225 static u32 imx7_csi_irq_clear(struct imx7_csi *csi)
226 {
227 	u32 isr;
228 
229 	isr = imx7_csi_reg_read(csi, CSI_CSISR);
230 	imx7_csi_reg_write(csi, isr, CSI_CSISR);
231 
232 	return isr;
233 }
234 
imx7_csi_init_interface(struct imx7_csi * csi)235 static void imx7_csi_init_interface(struct imx7_csi *csi)
236 {
237 	unsigned int val = 0;
238 	unsigned int imag_para;
239 
240 	val = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL |
241 		BIT_FCC | 1 << SHIFT_MCLKDIV | BIT_MCLKEN;
242 	imx7_csi_reg_write(csi, val, CSI_CSICR1);
243 
244 	imag_para = (800 << 16) | 600;
245 	imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA);
246 
247 	val = BIT_DMA_REFLASH_RFF;
248 	imx7_csi_reg_write(csi, val, CSI_CSICR3);
249 }
250 
imx7_csi_hw_enable_irq(struct imx7_csi * csi)251 static void imx7_csi_hw_enable_irq(struct imx7_csi *csi)
252 {
253 	u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
254 
255 	cr1 |= BIT_SOF_INTEN;
256 	cr1 |= BIT_RFF_OR_INT;
257 
258 	/* still capture needs DMA interrupt */
259 	cr1 |= BIT_FB1_DMA_DONE_INTEN;
260 	cr1 |= BIT_FB2_DMA_DONE_INTEN;
261 
262 	cr1 |= BIT_EOF_INT_EN;
263 
264 	imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
265 }
266 
imx7_csi_hw_disable_irq(struct imx7_csi * csi)267 static void imx7_csi_hw_disable_irq(struct imx7_csi *csi)
268 {
269 	u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
270 
271 	cr1 &= ~BIT_SOF_INTEN;
272 	cr1 &= ~BIT_RFF_OR_INT;
273 	cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
274 	cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
275 	cr1 &= ~BIT_EOF_INT_EN;
276 
277 	imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
278 }
279 
imx7_csi_hw_enable(struct imx7_csi * csi)280 static void imx7_csi_hw_enable(struct imx7_csi *csi)
281 {
282 	u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
283 
284 	cr |= BIT_CSI_HW_ENABLE;
285 
286 	imx7_csi_reg_write(csi, cr, CSI_CSICR18);
287 }
288 
imx7_csi_hw_disable(struct imx7_csi * csi)289 static void imx7_csi_hw_disable(struct imx7_csi *csi)
290 {
291 	u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
292 
293 	cr &= ~BIT_CSI_HW_ENABLE;
294 
295 	imx7_csi_reg_write(csi, cr, CSI_CSICR18);
296 }
297 
imx7_csi_dma_reflash(struct imx7_csi * csi)298 static void imx7_csi_dma_reflash(struct imx7_csi *csi)
299 {
300 	u32 cr3;
301 
302 	cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
303 	cr3 |= BIT_DMA_REFLASH_RFF;
304 	imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
305 }
306 
imx7_csi_rx_fifo_clear(struct imx7_csi * csi)307 static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi)
308 {
309 	u32 cr1;
310 
311 	cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
312 	imx7_csi_reg_write(csi, cr1 & ~BIT_FCC, CSI_CSICR1);
313 	cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
314 	imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1);
315 
316 	cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
317 	imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1);
318 }
319 
imx7_csi_buf_stride_set(struct imx7_csi * csi,u32 stride)320 static void imx7_csi_buf_stride_set(struct imx7_csi *csi, u32 stride)
321 {
322 	imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA);
323 }
324 
imx7_csi_deinterlace_enable(struct imx7_csi * csi,bool enable)325 static void imx7_csi_deinterlace_enable(struct imx7_csi *csi, bool enable)
326 {
327 	u32 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
328 
329 	if (enable)
330 		cr18 |= BIT_DEINTERLACE_EN;
331 	else
332 		cr18 &= ~BIT_DEINTERLACE_EN;
333 
334 	imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
335 }
336 
imx7_csi_dmareq_rff_enable(struct imx7_csi * csi)337 static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi)
338 {
339 	u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
340 	u32 cr2 = imx7_csi_reg_read(csi, CSI_CSICR2);
341 
342 	/* Burst Type of DMA Transfer from RxFIFO. INCR16 */
343 	cr2 |= 0xC0000000;
344 
345 	cr3 |= BIT_DMA_REQ_EN_RFF;
346 	cr3 |= BIT_HRESP_ERR_EN;
347 	cr3 &= ~BIT_RXFF_LEVEL;
348 	cr3 |= 0x2 << 4;
349 
350 	imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
351 	imx7_csi_reg_write(csi, cr2, CSI_CSICR2);
352 }
353 
imx7_csi_dmareq_rff_disable(struct imx7_csi * csi)354 static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi)
355 {
356 	u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
357 
358 	cr3 &= ~BIT_DMA_REQ_EN_RFF;
359 	cr3 &= ~BIT_HRESP_ERR_EN;
360 	imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
361 }
362 
imx7_csi_set_imagpara(struct imx7_csi * csi,int width,int height)363 static void imx7_csi_set_imagpara(struct imx7_csi *csi, int width, int height)
364 {
365 	int imag_para;
366 	int rx_count;
367 
368 	rx_count = (width * height) >> 2;
369 	imx7_csi_reg_write(csi, rx_count, CSI_CSIRXCNT);
370 
371 	imag_para = (width << 16) | height;
372 	imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA);
373 
374 	/* reflash the embedded DMA controller */
375 	imx7_csi_dma_reflash(csi);
376 }
377 
imx7_csi_sw_reset(struct imx7_csi * csi)378 static void imx7_csi_sw_reset(struct imx7_csi *csi)
379 {
380 	imx7_csi_hw_disable(csi);
381 
382 	imx7_csi_rx_fifo_clear(csi);
383 
384 	imx7_csi_dma_reflash(csi);
385 
386 	usleep_range(2000, 3000);
387 
388 	imx7_csi_irq_clear(csi);
389 
390 	imx7_csi_hw_enable(csi);
391 }
392 
imx7_csi_error_recovery(struct imx7_csi * csi)393 static void imx7_csi_error_recovery(struct imx7_csi *csi)
394 {
395 	imx7_csi_hw_disable(csi);
396 
397 	imx7_csi_rx_fifo_clear(csi);
398 
399 	imx7_csi_dma_reflash(csi);
400 
401 	imx7_csi_hw_enable(csi);
402 }
403 
imx7_csi_init(struct imx7_csi * csi)404 static int imx7_csi_init(struct imx7_csi *csi)
405 {
406 	int ret;
407 
408 	if (csi->is_init)
409 		return 0;
410 
411 	ret = clk_prepare_enable(csi->mclk);
412 	if (ret < 0)
413 		return ret;
414 	imx7_csi_hw_reset(csi);
415 	imx7_csi_init_interface(csi);
416 	imx7_csi_dmareq_rff_enable(csi);
417 
418 	csi->is_init = true;
419 
420 	return 0;
421 }
422 
imx7_csi_deinit(struct imx7_csi * csi)423 static void imx7_csi_deinit(struct imx7_csi *csi)
424 {
425 	if (!csi->is_init)
426 		return;
427 
428 	imx7_csi_hw_reset(csi);
429 	imx7_csi_init_interface(csi);
430 	imx7_csi_dmareq_rff_disable(csi);
431 	clk_disable_unprepare(csi->mclk);
432 
433 	csi->is_init = false;
434 }
435 
imx7_csi_link_setup(struct media_entity * entity,const struct media_pad * local,const struct media_pad * remote,u32 flags)436 static int imx7_csi_link_setup(struct media_entity *entity,
437 			       const struct media_pad *local,
438 			       const struct media_pad *remote, u32 flags)
439 {
440 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
441 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
442 	struct v4l2_subdev *remote_sd;
443 	int ret = 0;
444 
445 	dev_dbg(csi->dev, "link setup %s -> %s\n", remote->entity->name,
446 		local->entity->name);
447 
448 	mutex_lock(&csi->lock);
449 
450 	if (local->flags & MEDIA_PAD_FL_SINK) {
451 		if (!is_media_entity_v4l2_subdev(remote->entity)) {
452 			ret = -EINVAL;
453 			goto unlock;
454 		}
455 
456 		remote_sd = media_entity_to_v4l2_subdev(remote->entity);
457 
458 		if (flags & MEDIA_LNK_FL_ENABLED) {
459 			if (csi->src_sd) {
460 				ret = -EBUSY;
461 				goto unlock;
462 			}
463 			csi->src_sd = remote_sd;
464 		} else {
465 			csi->src_sd = NULL;
466 		}
467 
468 		goto init;
469 	}
470 
471 	/* source pad */
472 	if (flags & MEDIA_LNK_FL_ENABLED) {
473 		if (csi->sink) {
474 			ret = -EBUSY;
475 			goto unlock;
476 		}
477 		csi->sink = remote->entity;
478 	} else {
479 		v4l2_ctrl_handler_free(&csi->ctrl_hdlr);
480 		v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0);
481 		csi->sink = NULL;
482 	}
483 
484 init:
485 	if (csi->sink || csi->src_sd)
486 		ret = imx7_csi_init(csi);
487 	else
488 		imx7_csi_deinit(csi);
489 
490 unlock:
491 	mutex_unlock(&csi->lock);
492 
493 	return ret;
494 }
495 
imx7_csi_pad_link_validate(struct v4l2_subdev * sd,struct media_link * link,struct v4l2_subdev_format * source_fmt,struct v4l2_subdev_format * sink_fmt)496 static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd,
497 				      struct media_link *link,
498 				      struct v4l2_subdev_format *source_fmt,
499 				      struct v4l2_subdev_format *sink_fmt)
500 {
501 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
502 	struct media_pad *pad;
503 	int ret;
504 
505 	ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt);
506 	if (ret)
507 		return ret;
508 
509 	if (!csi->src_sd)
510 		return -EPIPE;
511 
512 	/*
513 	 * find the entity that is selected by the CSI mux. This is needed
514 	 * to distinguish between a parallel or CSI-2 pipeline.
515 	 */
516 	pad = imx_media_pipeline_pad(&csi->src_sd->entity, 0, 0, true);
517 	if (!pad)
518 		return -ENODEV;
519 
520 	mutex_lock(&csi->lock);
521 
522 	csi->is_csi2 = (pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE);
523 
524 	mutex_unlock(&csi->lock);
525 
526 	return 0;
527 }
528 
imx7_csi_update_buf(struct imx7_csi * csi,dma_addr_t phys,int buf_num)529 static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys,
530 				int buf_num)
531 {
532 	if (buf_num == 1)
533 		imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2);
534 	else
535 		imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1);
536 }
537 
imx7_csi_setup_vb2_buf(struct imx7_csi * csi)538 static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi)
539 {
540 	struct imx_media_video_dev *vdev = csi->vdev;
541 	struct imx_media_buffer *buf;
542 	struct vb2_buffer *vb2_buf;
543 	dma_addr_t phys[2];
544 	int i;
545 
546 	for (i = 0; i < 2; i++) {
547 		buf = imx_media_capture_device_next_buf(vdev);
548 		if (buf) {
549 			csi->active_vb2_buf[i] = buf;
550 			vb2_buf = &buf->vbuf.vb2_buf;
551 			phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
552 		} else {
553 			csi->active_vb2_buf[i] = NULL;
554 			phys[i] = csi->underrun_buf.phys;
555 		}
556 
557 		imx7_csi_update_buf(csi, phys[i], i);
558 	}
559 }
560 
imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi * csi,enum vb2_buffer_state return_status)561 static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi,
562 					 enum vb2_buffer_state return_status)
563 {
564 	struct imx_media_buffer *buf;
565 	int i;
566 
567 	/* return any remaining active frames with return_status */
568 	for (i = 0; i < 2; i++) {
569 		buf = csi->active_vb2_buf[i];
570 		if (buf) {
571 			struct vb2_buffer *vb = &buf->vbuf.vb2_buf;
572 
573 			vb->timestamp = ktime_get_ns();
574 			vb2_buffer_done(vb, return_status);
575 		}
576 	}
577 }
578 
imx7_csi_vb2_buf_done(struct imx7_csi * csi)579 static void imx7_csi_vb2_buf_done(struct imx7_csi *csi)
580 {
581 	struct imx_media_video_dev *vdev = csi->vdev;
582 	struct imx_media_buffer *done, *next;
583 	struct vb2_buffer *vb;
584 	dma_addr_t phys;
585 
586 	done = csi->active_vb2_buf[csi->buf_num];
587 	if (done) {
588 		done->vbuf.field = vdev->fmt.fmt.pix.field;
589 		done->vbuf.sequence = csi->frame_sequence;
590 		vb = &done->vbuf.vb2_buf;
591 		vb->timestamp = ktime_get_ns();
592 		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
593 	}
594 	csi->frame_sequence++;
595 
596 	/* get next queued buffer */
597 	next = imx_media_capture_device_next_buf(vdev);
598 	if (next) {
599 		phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0);
600 		csi->active_vb2_buf[csi->buf_num] = next;
601 	} else {
602 		phys = csi->underrun_buf.phys;
603 		csi->active_vb2_buf[csi->buf_num] = NULL;
604 	}
605 
606 	imx7_csi_update_buf(csi, phys, csi->buf_num);
607 }
608 
imx7_csi_irq_handler(int irq,void * data)609 static irqreturn_t imx7_csi_irq_handler(int irq, void *data)
610 {
611 	struct imx7_csi *csi =  data;
612 	u32 status;
613 
614 	spin_lock(&csi->irqlock);
615 
616 	status = imx7_csi_irq_clear(csi);
617 
618 	if (status & BIT_RFF_OR_INT) {
619 		dev_warn(csi->dev, "Rx fifo overflow\n");
620 		imx7_csi_error_recovery(csi);
621 	}
622 
623 	if (status & BIT_HRESP_ERR_INT) {
624 		dev_warn(csi->dev, "Hresponse error detected\n");
625 		imx7_csi_error_recovery(csi);
626 	}
627 
628 	if (status & BIT_ADDR_CH_ERR_INT) {
629 		imx7_csi_hw_disable(csi);
630 
631 		imx7_csi_dma_reflash(csi);
632 
633 		imx7_csi_hw_enable(csi);
634 	}
635 
636 	if ((status & BIT_DMA_TSF_DONE_FB1) &&
637 	    (status & BIT_DMA_TSF_DONE_FB2)) {
638 		/*
639 		 * For both FB1 and FB2 interrupter bits set case,
640 		 * CSI DMA is work in one of FB1 and FB2 buffer,
641 		 * but software can not know the state.
642 		 * Skip it to avoid base address updated
643 		 * when csi work in field0 and field1 will write to
644 		 * new base address.
645 		 */
646 	} else if (status & BIT_DMA_TSF_DONE_FB1) {
647 		csi->buf_num = 0;
648 	} else if (status & BIT_DMA_TSF_DONE_FB2) {
649 		csi->buf_num = 1;
650 	}
651 
652 	if ((status & BIT_DMA_TSF_DONE_FB1) ||
653 	    (status & BIT_DMA_TSF_DONE_FB2)) {
654 		imx7_csi_vb2_buf_done(csi);
655 
656 		if (csi->last_eof) {
657 			complete(&csi->last_eof_completion);
658 			csi->last_eof = false;
659 		}
660 	}
661 
662 	spin_unlock(&csi->irqlock);
663 
664 	return IRQ_HANDLED;
665 }
666 
imx7_csi_dma_start(struct imx7_csi * csi)667 static int imx7_csi_dma_start(struct imx7_csi *csi)
668 {
669 	struct imx_media_video_dev *vdev = csi->vdev;
670 	struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix;
671 	int ret;
672 
673 	ret = imx_media_alloc_dma_buf(csi->dev, &csi->underrun_buf,
674 				      out_pix->sizeimage);
675 	if (ret < 0) {
676 		v4l2_warn(&csi->sd, "consider increasing the CMA area\n");
677 		return ret;
678 	}
679 
680 	csi->frame_sequence = 0;
681 	csi->last_eof = false;
682 	init_completion(&csi->last_eof_completion);
683 
684 	imx7_csi_setup_vb2_buf(csi);
685 
686 	return 0;
687 }
688 
imx7_csi_dma_stop(struct imx7_csi * csi)689 static void imx7_csi_dma_stop(struct imx7_csi *csi)
690 {
691 	unsigned long timeout_jiffies;
692 	unsigned long flags;
693 	int ret;
694 
695 	/* mark next EOF interrupt as the last before stream off */
696 	spin_lock_irqsave(&csi->irqlock, flags);
697 	csi->last_eof = true;
698 	spin_unlock_irqrestore(&csi->irqlock, flags);
699 
700 	/*
701 	 * and then wait for interrupt handler to mark completion.
702 	 */
703 	timeout_jiffies = msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT);
704 	ret = wait_for_completion_timeout(&csi->last_eof_completion,
705 					  timeout_jiffies);
706 	if (ret == 0)
707 		v4l2_warn(&csi->sd, "wait last EOF timeout\n");
708 
709 	imx7_csi_hw_disable_irq(csi);
710 
711 	imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR);
712 
713 	imx_media_free_dma_buf(csi->dev, &csi->underrun_buf);
714 }
715 
imx7_csi_configure(struct imx7_csi * csi)716 static int imx7_csi_configure(struct imx7_csi *csi)
717 {
718 	struct imx_media_video_dev *vdev = csi->vdev;
719 	struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix;
720 	__u32 in_code = csi->format_mbus[IMX7_CSI_PAD_SINK].code;
721 	u32 cr1, cr18;
722 	int width = out_pix->width;
723 
724 	if (out_pix->field == V4L2_FIELD_INTERLACED) {
725 		imx7_csi_deinterlace_enable(csi, true);
726 		imx7_csi_buf_stride_set(csi, out_pix->width);
727 	} else {
728 		imx7_csi_deinterlace_enable(csi, false);
729 		imx7_csi_buf_stride_set(csi, 0);
730 	}
731 
732 	cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
733 
734 	if (!csi->is_csi2) {
735 		if (out_pix->pixelformat == V4L2_PIX_FMT_UYVY ||
736 		    out_pix->pixelformat == V4L2_PIX_FMT_YUYV)
737 			width *= 2;
738 
739 		imx7_csi_set_imagpara(csi, width, out_pix->height);
740 
741 		cr18 |= (BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
742 			BIT_BASEADDR_CHG_ERR_EN);
743 		imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
744 
745 		return 0;
746 	}
747 
748 	imx7_csi_set_imagpara(csi, width, out_pix->height);
749 
750 	cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
751 	cr1 &= ~BIT_GCLK_MODE;
752 
753 	cr18 &= BIT_MIPI_DATA_FORMAT_MASK;
754 	cr18 |= BIT_DATA_FROM_MIPI;
755 
756 	switch (out_pix->pixelformat) {
757 	case V4L2_PIX_FMT_UYVY:
758 	case V4L2_PIX_FMT_YUYV:
759 		cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B;
760 		break;
761 	case V4L2_PIX_FMT_GREY:
762 		if (in_code == MEDIA_BUS_FMT_Y8_1X8)
763 			cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;
764 		else if (in_code == MEDIA_BUS_FMT_Y10_1X10)
765 			cr18 |= BIT_MIPI_DATA_FORMAT_RAW10;
766 		else
767 			cr18 |= BIT_MIPI_DATA_FORMAT_RAW12;
768 		break;
769 	case V4L2_PIX_FMT_Y10:
770 		cr18 |= BIT_MIPI_DATA_FORMAT_RAW10;
771 		cr1 |= BIT_PIXEL_BIT;
772 		break;
773 	case V4L2_PIX_FMT_Y12:
774 		cr18 |= BIT_MIPI_DATA_FORMAT_RAW12;
775 		cr1 |= BIT_PIXEL_BIT;
776 		break;
777 	case V4L2_PIX_FMT_SBGGR8:
778 		cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;
779 		break;
780 	case V4L2_PIX_FMT_SBGGR16:
781 		if (in_code == MEDIA_BUS_FMT_SBGGR10_1X10)
782 			cr18 |= BIT_MIPI_DATA_FORMAT_RAW10;
783 		else if (in_code == MEDIA_BUS_FMT_SBGGR12_1X12)
784 			cr18 |= BIT_MIPI_DATA_FORMAT_RAW12;
785 		else if (in_code == MEDIA_BUS_FMT_SBGGR14_1X14)
786 			cr18 |= BIT_MIPI_DATA_FORMAT_RAW14;
787 		cr1 |= BIT_PIXEL_BIT;
788 		break;
789 	default:
790 		return -EINVAL;
791 	}
792 
793 	imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
794 	imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
795 
796 	return 0;
797 }
798 
imx7_csi_enable(struct imx7_csi * csi)799 static void imx7_csi_enable(struct imx7_csi *csi)
800 {
801 	imx7_csi_sw_reset(csi);
802 
803 	imx7_csi_dmareq_rff_enable(csi);
804 	imx7_csi_hw_enable_irq(csi);
805 	imx7_csi_hw_enable(csi);
806 }
807 
imx7_csi_disable(struct imx7_csi * csi)808 static void imx7_csi_disable(struct imx7_csi *csi)
809 {
810 	imx7_csi_dmareq_rff_disable(csi);
811 
812 	imx7_csi_hw_disable_irq(csi);
813 
814 	imx7_csi_buf_stride_set(csi, 0);
815 
816 	imx7_csi_hw_disable(csi);
817 }
818 
imx7_csi_streaming_start(struct imx7_csi * csi)819 static int imx7_csi_streaming_start(struct imx7_csi *csi)
820 {
821 	int ret;
822 
823 	ret = imx7_csi_dma_start(csi);
824 	if (ret < 0)
825 		return ret;
826 
827 	ret = imx7_csi_configure(csi);
828 	if (ret < 0)
829 		goto dma_stop;
830 
831 	imx7_csi_enable(csi);
832 
833 	return 0;
834 
835 dma_stop:
836 	imx7_csi_dma_stop(csi);
837 
838 	return ret;
839 }
840 
imx7_csi_streaming_stop(struct imx7_csi * csi)841 static int imx7_csi_streaming_stop(struct imx7_csi *csi)
842 {
843 	imx7_csi_dma_stop(csi);
844 
845 	imx7_csi_disable(csi);
846 
847 	return 0;
848 }
849 
imx7_csi_s_stream(struct v4l2_subdev * sd,int enable)850 static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable)
851 {
852 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
853 	int ret = 0;
854 
855 	mutex_lock(&csi->lock);
856 
857 	if (!csi->src_sd || !csi->sink) {
858 		ret = -EPIPE;
859 		goto out_unlock;
860 	}
861 
862 	if (csi->is_streaming == !!enable)
863 		goto out_unlock;
864 
865 	if (enable) {
866 		ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1);
867 		if (ret < 0)
868 			goto out_unlock;
869 
870 		ret = imx7_csi_streaming_start(csi);
871 		if (ret < 0) {
872 			v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
873 			goto out_unlock;
874 		}
875 	} else {
876 		imx7_csi_streaming_stop(csi);
877 
878 		v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
879 	}
880 
881 	csi->is_streaming = !!enable;
882 
883 out_unlock:
884 	mutex_unlock(&csi->lock);
885 
886 	return ret;
887 }
888 
889 static struct v4l2_mbus_framefmt *
imx7_csi_get_format(struct imx7_csi * csi,struct v4l2_subdev_pad_config * cfg,unsigned int pad,enum v4l2_subdev_format_whence which)890 imx7_csi_get_format(struct imx7_csi *csi,
891 		    struct v4l2_subdev_pad_config *cfg,
892 		    unsigned int pad,
893 		    enum v4l2_subdev_format_whence which)
894 {
895 	if (which == V4L2_SUBDEV_FORMAT_TRY)
896 		return v4l2_subdev_get_try_format(&csi->sd, cfg, pad);
897 
898 	return &csi->format_mbus[pad];
899 }
900 
imx7_csi_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)901 static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd,
902 				   struct v4l2_subdev_pad_config *cfg,
903 				   struct v4l2_subdev_mbus_code_enum *code)
904 {
905 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
906 	struct v4l2_mbus_framefmt *in_fmt;
907 	int ret = 0;
908 
909 	mutex_lock(&csi->lock);
910 
911 	in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK, code->which);
912 
913 	switch (code->pad) {
914 	case IMX7_CSI_PAD_SINK:
915 		ret = imx_media_enum_mbus_formats(&code->code, code->index,
916 						  PIXFMT_SEL_ANY);
917 		break;
918 	case IMX7_CSI_PAD_SRC:
919 		if (code->index != 0) {
920 			ret = -EINVAL;
921 			goto out_unlock;
922 		}
923 
924 		code->code = in_fmt->code;
925 		break;
926 	default:
927 		ret = -EINVAL;
928 	}
929 
930 out_unlock:
931 	mutex_unlock(&csi->lock);
932 
933 	return ret;
934 }
935 
imx7_csi_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * sdformat)936 static int imx7_csi_get_fmt(struct v4l2_subdev *sd,
937 			    struct v4l2_subdev_pad_config *cfg,
938 			    struct v4l2_subdev_format *sdformat)
939 {
940 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
941 	struct v4l2_mbus_framefmt *fmt;
942 	int ret = 0;
943 
944 	mutex_lock(&csi->lock);
945 
946 	fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which);
947 	if (!fmt) {
948 		ret = -EINVAL;
949 		goto out_unlock;
950 	}
951 
952 	sdformat->format = *fmt;
953 
954 out_unlock:
955 	mutex_unlock(&csi->lock);
956 
957 	return ret;
958 }
959 
imx7_csi_try_fmt(struct imx7_csi * csi,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * sdformat,const struct imx_media_pixfmt ** cc)960 static int imx7_csi_try_fmt(struct imx7_csi *csi,
961 			    struct v4l2_subdev_pad_config *cfg,
962 			    struct v4l2_subdev_format *sdformat,
963 			    const struct imx_media_pixfmt **cc)
964 {
965 	const struct imx_media_pixfmt *in_cc;
966 	struct v4l2_mbus_framefmt *in_fmt;
967 	u32 code;
968 
969 	in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK,
970 				     sdformat->which);
971 	if (!in_fmt)
972 		return -EINVAL;
973 
974 	switch (sdformat->pad) {
975 	case IMX7_CSI_PAD_SRC:
976 		in_cc = imx_media_find_mbus_format(in_fmt->code,
977 						   PIXFMT_SEL_ANY);
978 
979 		sdformat->format.width = in_fmt->width;
980 		sdformat->format.height = in_fmt->height;
981 		sdformat->format.code = in_fmt->code;
982 		sdformat->format.field = in_fmt->field;
983 		*cc = in_cc;
984 
985 		sdformat->format.colorspace = in_fmt->colorspace;
986 		sdformat->format.xfer_func = in_fmt->xfer_func;
987 		sdformat->format.quantization = in_fmt->quantization;
988 		sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc;
989 		break;
990 	case IMX7_CSI_PAD_SINK:
991 		*cc = imx_media_find_mbus_format(sdformat->format.code,
992 						 PIXFMT_SEL_ANY);
993 		if (!*cc) {
994 			imx_media_enum_mbus_formats(&code, 0,
995 						    PIXFMT_SEL_YUV_RGB);
996 			*cc = imx_media_find_mbus_format(code,
997 							 PIXFMT_SEL_YUV_RGB);
998 			sdformat->format.code = (*cc)->codes[0];
999 		}
1000 
1001 		if (sdformat->format.field != V4L2_FIELD_INTERLACED)
1002 			sdformat->format.field = V4L2_FIELD_NONE;
1003 		break;
1004 	default:
1005 		return -EINVAL;
1006 	}
1007 
1008 	imx_media_try_colorimetry(&sdformat->format, false);
1009 
1010 	return 0;
1011 }
1012 
imx7_csi_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * sdformat)1013 static int imx7_csi_set_fmt(struct v4l2_subdev *sd,
1014 			    struct v4l2_subdev_pad_config *cfg,
1015 			    struct v4l2_subdev_format *sdformat)
1016 {
1017 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1018 	const struct imx_media_pixfmt *outcc;
1019 	struct v4l2_mbus_framefmt *outfmt;
1020 	const struct imx_media_pixfmt *cc;
1021 	struct v4l2_mbus_framefmt *fmt;
1022 	struct v4l2_subdev_format format;
1023 	int ret = 0;
1024 
1025 	if (sdformat->pad >= IMX7_CSI_PADS_NUM)
1026 		return -EINVAL;
1027 
1028 	mutex_lock(&csi->lock);
1029 
1030 	if (csi->is_streaming) {
1031 		ret = -EBUSY;
1032 		goto out_unlock;
1033 	}
1034 
1035 	ret = imx7_csi_try_fmt(csi, cfg, sdformat, &cc);
1036 	if (ret < 0)
1037 		goto out_unlock;
1038 
1039 	fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which);
1040 	if (!fmt) {
1041 		ret = -EINVAL;
1042 		goto out_unlock;
1043 	}
1044 
1045 	*fmt = sdformat->format;
1046 
1047 	if (sdformat->pad == IMX7_CSI_PAD_SINK) {
1048 		/* propagate format to source pads */
1049 		format.pad = IMX7_CSI_PAD_SRC;
1050 		format.which = sdformat->which;
1051 		format.format = sdformat->format;
1052 		if (imx7_csi_try_fmt(csi, cfg, &format, &outcc)) {
1053 			ret = -EINVAL;
1054 			goto out_unlock;
1055 		}
1056 		outfmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SRC,
1057 					     sdformat->which);
1058 		*outfmt = format.format;
1059 
1060 		if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1061 			csi->cc[IMX7_CSI_PAD_SRC] = outcc;
1062 	}
1063 
1064 	if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1065 		csi->cc[sdformat->pad] = cc;
1066 
1067 out_unlock:
1068 	mutex_unlock(&csi->lock);
1069 
1070 	return ret;
1071 }
1072 
imx7_csi_registered(struct v4l2_subdev * sd)1073 static int imx7_csi_registered(struct v4l2_subdev *sd)
1074 {
1075 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1076 	int ret;
1077 	int i;
1078 
1079 	for (i = 0; i < IMX7_CSI_PADS_NUM; i++) {
1080 		/* set a default mbus format  */
1081 		ret = imx_media_init_mbus_fmt(&csi->format_mbus[i],
1082 					      800, 600, 0, V4L2_FIELD_NONE,
1083 					      &csi->cc[i]);
1084 		if (ret < 0)
1085 			return ret;
1086 
1087 		/* init default frame interval */
1088 		csi->frame_interval[i].numerator = 1;
1089 		csi->frame_interval[i].denominator = 30;
1090 	}
1091 
1092 	csi->vdev = imx_media_capture_device_init(csi->sd.dev, &csi->sd,
1093 						  IMX7_CSI_PAD_SRC);
1094 	if (IS_ERR(csi->vdev))
1095 		return PTR_ERR(csi->vdev);
1096 
1097 	ret = imx_media_capture_device_register(csi->vdev);
1098 	if (ret)
1099 		imx_media_capture_device_remove(csi->vdev);
1100 
1101 	return ret;
1102 }
1103 
imx7_csi_unregistered(struct v4l2_subdev * sd)1104 static void imx7_csi_unregistered(struct v4l2_subdev *sd)
1105 {
1106 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1107 
1108 	imx_media_capture_device_unregister(csi->vdev);
1109 	imx_media_capture_device_remove(csi->vdev);
1110 }
1111 
imx7_csi_init_cfg(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg)1112 static int imx7_csi_init_cfg(struct v4l2_subdev *sd,
1113 			     struct v4l2_subdev_pad_config *cfg)
1114 {
1115 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1116 	struct v4l2_mbus_framefmt *mf;
1117 	int ret;
1118 	int i;
1119 
1120 	for (i = 0; i < IMX7_CSI_PADS_NUM; i++) {
1121 		mf = v4l2_subdev_get_try_format(sd, cfg, i);
1122 
1123 		ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE,
1124 					      &csi->cc[i]);
1125 		if (ret < 0)
1126 			return ret;
1127 	}
1128 
1129 	return 0;
1130 }
1131 
1132 static const struct media_entity_operations imx7_csi_entity_ops = {
1133 	.link_setup	= imx7_csi_link_setup,
1134 	.link_validate	= v4l2_subdev_link_validate,
1135 	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
1136 };
1137 
1138 static const struct v4l2_subdev_video_ops imx7_csi_video_ops = {
1139 	.s_stream		= imx7_csi_s_stream,
1140 };
1141 
1142 static const struct v4l2_subdev_pad_ops imx7_csi_pad_ops = {
1143 	.init_cfg =		imx7_csi_init_cfg,
1144 	.enum_mbus_code =	imx7_csi_enum_mbus_code,
1145 	.get_fmt =		imx7_csi_get_fmt,
1146 	.set_fmt =		imx7_csi_set_fmt,
1147 	.link_validate =	imx7_csi_pad_link_validate,
1148 };
1149 
1150 static const struct v4l2_subdev_ops imx7_csi_subdev_ops = {
1151 	.video =	&imx7_csi_video_ops,
1152 	.pad =		&imx7_csi_pad_ops,
1153 };
1154 
1155 static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = {
1156 	.registered	= imx7_csi_registered,
1157 	.unregistered	= imx7_csi_unregistered,
1158 };
1159 
imx7_csi_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * sd,struct v4l2_async_subdev * asd)1160 static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
1161 				 struct v4l2_subdev *sd,
1162 				 struct v4l2_async_subdev *asd)
1163 {
1164 	struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
1165 	struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
1166 
1167 	/* The bound subdev must always be the CSI mux */
1168 	if (WARN_ON(sd->entity.function != MEDIA_ENT_F_VID_MUX))
1169 		return -ENXIO;
1170 
1171 	/* Mark it as such via its group id */
1172 	sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
1173 
1174 	return v4l2_create_fwnode_links_to_pad(sd, sink);
1175 }
1176 
1177 static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = {
1178 	.bound = imx7_csi_notify_bound,
1179 };
1180 
imx7_csi_async_register(struct imx7_csi * csi)1181 static int imx7_csi_async_register(struct imx7_csi *csi)
1182 {
1183 	struct v4l2_async_subdev *asd = NULL;
1184 	struct fwnode_handle *ep;
1185 	int ret;
1186 
1187 	v4l2_async_notifier_init(&csi->notifier);
1188 
1189 	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
1190 					     FWNODE_GRAPH_ENDPOINT_NEXT);
1191 	if (ep) {
1192 		asd = kzalloc(sizeof(*asd), GFP_KERNEL);
1193 		if (!asd) {
1194 			fwnode_handle_put(ep);
1195 			return -ENOMEM;
1196 		}
1197 
1198 		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
1199 			&csi->notifier, ep, asd);
1200 
1201 		fwnode_handle_put(ep);
1202 
1203 		if (ret) {
1204 			kfree(asd);
1205 			/* OK if asd already exists */
1206 			if (ret != -EEXIST)
1207 				return ret;
1208 		}
1209 	}
1210 
1211 	csi->notifier.ops = &imx7_csi_notify_ops;
1212 
1213 	ret = v4l2_async_subdev_notifier_register(&csi->sd, &csi->notifier);
1214 	if (ret)
1215 		return ret;
1216 
1217 	return v4l2_async_register_subdev(&csi->sd);
1218 }
1219 
imx7_csi_probe(struct platform_device * pdev)1220 static int imx7_csi_probe(struct platform_device *pdev)
1221 {
1222 	struct device *dev = &pdev->dev;
1223 	struct device_node *node = dev->of_node;
1224 	struct imx_media_dev *imxmd;
1225 	struct imx7_csi *csi;
1226 	int i, ret;
1227 
1228 	csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
1229 	if (!csi)
1230 		return -ENOMEM;
1231 
1232 	csi->dev = dev;
1233 
1234 	csi->mclk = devm_clk_get(&pdev->dev, "mclk");
1235 	if (IS_ERR(csi->mclk)) {
1236 		ret = PTR_ERR(csi->mclk);
1237 		dev_err(dev, "Failed to get mclk: %d", ret);
1238 		return ret;
1239 	}
1240 
1241 	csi->irq = platform_get_irq(pdev, 0);
1242 	if (csi->irq < 0)
1243 		return csi->irq;
1244 
1245 	csi->regbase = devm_platform_ioremap_resource(pdev, 0);
1246 	if (IS_ERR(csi->regbase))
1247 		return PTR_ERR(csi->regbase);
1248 
1249 	spin_lock_init(&csi->irqlock);
1250 	mutex_init(&csi->lock);
1251 
1252 	/* install interrupt handler */
1253 	ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi",
1254 			       (void *)csi);
1255 	if (ret < 0) {
1256 		dev_err(dev, "Request CSI IRQ failed.\n");
1257 		goto destroy_mutex;
1258 	}
1259 
1260 	/* add media device */
1261 	imxmd = imx_media_dev_init(dev, NULL);
1262 	if (IS_ERR(imxmd)) {
1263 		ret = PTR_ERR(imxmd);
1264 		goto destroy_mutex;
1265 	}
1266 	platform_set_drvdata(pdev, &csi->sd);
1267 
1268 	ret = imx_media_of_add_csi(imxmd, node);
1269 	if (ret < 0 && ret != -ENODEV && ret != -EEXIST)
1270 		goto cleanup;
1271 
1272 	ret = imx_media_dev_notifier_register(imxmd, NULL);
1273 	if (ret < 0)
1274 		goto cleanup;
1275 
1276 	csi->imxmd = imxmd;
1277 	v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops);
1278 	v4l2_set_subdevdata(&csi->sd, csi);
1279 	csi->sd.internal_ops = &imx7_csi_internal_ops;
1280 	csi->sd.entity.ops = &imx7_csi_entity_ops;
1281 	csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
1282 	csi->sd.dev = &pdev->dev;
1283 	csi->sd.owner = THIS_MODULE;
1284 	csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1285 	csi->sd.grp_id = IMX_MEDIA_GRP_ID_CSI;
1286 	snprintf(csi->sd.name, sizeof(csi->sd.name), "csi");
1287 
1288 	v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0);
1289 	csi->sd.ctrl_handler = &csi->ctrl_hdlr;
1290 
1291 	for (i = 0; i < IMX7_CSI_PADS_NUM; i++)
1292 		csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ?
1293 			MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
1294 
1295 	ret = media_entity_pads_init(&csi->sd.entity, IMX7_CSI_PADS_NUM,
1296 				     csi->pad);
1297 	if (ret < 0)
1298 		goto free;
1299 
1300 	ret = imx7_csi_async_register(csi);
1301 	if (ret)
1302 		goto subdev_notifier_cleanup;
1303 
1304 	return 0;
1305 
1306 subdev_notifier_cleanup:
1307 	v4l2_async_notifier_unregister(&csi->notifier);
1308 	v4l2_async_notifier_cleanup(&csi->notifier);
1309 
1310 free:
1311 	v4l2_ctrl_handler_free(&csi->ctrl_hdlr);
1312 
1313 cleanup:
1314 	v4l2_async_notifier_unregister(&imxmd->notifier);
1315 	v4l2_async_notifier_cleanup(&imxmd->notifier);
1316 	v4l2_device_unregister(&imxmd->v4l2_dev);
1317 	media_device_unregister(&imxmd->md);
1318 	media_device_cleanup(&imxmd->md);
1319 
1320 destroy_mutex:
1321 	mutex_destroy(&csi->lock);
1322 
1323 	return ret;
1324 }
1325 
imx7_csi_remove(struct platform_device * pdev)1326 static int imx7_csi_remove(struct platform_device *pdev)
1327 {
1328 	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
1329 	struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1330 	struct imx_media_dev *imxmd = csi->imxmd;
1331 
1332 	v4l2_async_notifier_unregister(&imxmd->notifier);
1333 	v4l2_async_notifier_cleanup(&imxmd->notifier);
1334 
1335 	media_device_unregister(&imxmd->md);
1336 	v4l2_device_unregister(&imxmd->v4l2_dev);
1337 	media_device_cleanup(&imxmd->md);
1338 
1339 	v4l2_async_notifier_unregister(&csi->notifier);
1340 	v4l2_async_notifier_cleanup(&csi->notifier);
1341 	v4l2_async_unregister_subdev(sd);
1342 	v4l2_ctrl_handler_free(&csi->ctrl_hdlr);
1343 
1344 	mutex_destroy(&csi->lock);
1345 
1346 	return 0;
1347 }
1348 
1349 static const struct of_device_id imx7_csi_of_match[] = {
1350 	{ .compatible = "fsl,imx7-csi" },
1351 	{ .compatible = "fsl,imx6ul-csi" },
1352 	{ },
1353 };
1354 MODULE_DEVICE_TABLE(of, imx7_csi_of_match);
1355 
1356 static struct platform_driver imx7_csi_driver = {
1357 	.probe = imx7_csi_probe,
1358 	.remove = imx7_csi_remove,
1359 	.driver = {
1360 		.of_match_table = imx7_csi_of_match,
1361 		.name = "imx7-csi",
1362 	},
1363 };
1364 module_platform_driver(imx7_csi_driver);
1365 
1366 MODULE_DESCRIPTION("i.MX7 CSI subdev driver");
1367 MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>");
1368 MODULE_LICENSE("GPL v2");
1369 MODULE_ALIAS("platform:imx7-csi");
1370