[media] media: imx: capture: add frame sizes/interval enumeration
[linux-2.6-block.git] / drivers / staging / media / imx / imx-media-csi.c
CommitLineData
4a34ec8e
SL
1/*
2 * V4L2 Capture CSI Subdev for Freescale i.MX5/6 SOC
3 *
4 * Copyright (c) 2014-2017 Mentor Graphics Inc.
fb30ee79 5 * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
4a34ec8e
SL
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12#include <linux/delay.h>
fb30ee79 13#include <linux/gcd.h>
4a34ec8e
SL
14#include <linux/interrupt.h>
15#include <linux/module.h>
16#include <linux/pinctrl/consumer.h>
17#include <linux/platform_device.h>
18#include <media/v4l2-ctrls.h>
19#include <media/v4l2-device.h>
20#include <media/v4l2-event.h>
21#include <media/v4l2-fwnode.h>
22#include <media/v4l2-mc.h>
23#include <media/v4l2-subdev.h>
24#include <media/videobuf2-dma-contig.h>
25#include <video/imx-ipu-v3.h>
26#include <media/imx.h>
27#include "imx-media.h"
28
29/*
30 * Min/Max supported width and heights.
31 *
32 * We allow planar output, so we have to align width by 16 pixels
33 * to meet IDMAC alignment requirements.
34 *
35 * TODO: move this into pad format negotiation, if capture device
36 * has not requested planar formats, we should allow 8 pixel
37 * alignment.
38 */
39#define MIN_W 176
40#define MIN_H 144
41#define MAX_W 4096
42#define MAX_H 4096
43#define W_ALIGN 4 /* multiple of 16 pixels */
44#define H_ALIGN 1 /* multiple of 2 lines */
45#define S_ALIGN 1 /* multiple of 2 */
46
fb30ee79
PZ
47/*
48 * struct csi_skip_desc - CSI frame skipping descriptor
49 * @keep - number of frames kept per max_ratio frames
50 * @max_ratio - width of skip_smfc, written to MAX_RATIO bitfield
51 * @skip_smfc - skip pattern written to the SKIP_SMFC bitfield
52 */
53struct csi_skip_desc {
54 u8 keep;
55 u8 max_ratio;
56 u8 skip_smfc;
57};
58
4a34ec8e
SL
59struct csi_priv {
60 struct device *dev;
61 struct ipu_soc *ipu;
62 struct imx_media_dev *md;
63 struct v4l2_subdev sd;
64 struct media_pad pad[CSI_NUM_PADS];
65 /* the video device at IDMAC output pad */
66 struct imx_media_video_dev *vdev;
67 struct imx_media_fim *fim;
68 int csi_id;
69 int smfc_id;
70
71 /* lock to protect all members below */
72 struct mutex lock;
73
74 int active_output_pad;
75
76 struct ipuv3_channel *idmac_ch;
77 struct ipu_smfc *smfc;
78 struct ipu_csi *csi;
79
80 struct v4l2_mbus_framefmt format_mbus[CSI_NUM_PADS];
81 const struct imx_media_pixfmt *cc[CSI_NUM_PADS];
fb30ee79 82 struct v4l2_fract frame_interval[CSI_NUM_PADS];
4a34ec8e 83 struct v4l2_rect crop;
69e78611 84 struct v4l2_rect compose;
fb30ee79 85 const struct csi_skip_desc *skip;
4a34ec8e
SL
86
87 /* active vb2 buffers to send to video dev sink */
88 struct imx_media_buffer *active_vb2_buf[2];
89 struct imx_media_dma_buf underrun_buf;
90
91 int ipu_buf_num; /* ipu double buffer index: 0-1 */
92
93 /* the sink for the captured frames */
94 struct media_entity *sink;
95 enum ipu_csi_dest dest;
96 /* the source subdev */
97 struct v4l2_subdev *src_sd;
98
99 /* the mipi virtual channel number at link validate */
100 int vc_num;
101
102 /* the attached sensor at stream on */
103 struct imx_media_subdev *sensor;
104
105 spinlock_t irqlock; /* protect eof_irq handler */
106 struct timer_list eof_timeout_timer;
107 int eof_irq;
108 int nfb4eof_irq;
109
110 struct v4l2_ctrl_handler ctrl_hdlr;
111
112 int stream_count; /* streaming counter */
113 bool last_eof; /* waiting for last EOF at stream off */
114 bool nfb4eof; /* NFB4EOF encountered during streaming */
115 struct completion last_eof_comp;
116};
117
118static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev)
119{
120 return container_of(sdev, struct csi_priv, sd);
121}
122
123static void csi_idmac_put_ipu_resources(struct csi_priv *priv)
124{
125 if (!IS_ERR_OR_NULL(priv->idmac_ch))
126 ipu_idmac_put(priv->idmac_ch);
127 priv->idmac_ch = NULL;
128
129 if (!IS_ERR_OR_NULL(priv->smfc))
130 ipu_smfc_put(priv->smfc);
131 priv->smfc = NULL;
132}
133
134static int csi_idmac_get_ipu_resources(struct csi_priv *priv)
135{
136 int ch_num, ret;
137
138 ch_num = IPUV3_CHANNEL_CSI0 + priv->smfc_id;
139
140 priv->smfc = ipu_smfc_get(priv->ipu, ch_num);
141 if (IS_ERR(priv->smfc)) {
142 v4l2_err(&priv->sd, "failed to get SMFC\n");
143 ret = PTR_ERR(priv->smfc);
144 goto out;
145 }
146
147 priv->idmac_ch = ipu_idmac_get(priv->ipu, ch_num);
148 if (IS_ERR(priv->idmac_ch)) {
149 v4l2_err(&priv->sd, "could not get IDMAC channel %u\n",
150 ch_num);
151 ret = PTR_ERR(priv->idmac_ch);
152 goto out;
153 }
154
155 return 0;
156out:
157 csi_idmac_put_ipu_resources(priv);
158 return ret;
159}
160
161static void csi_vb2_buf_done(struct csi_priv *priv)
162{
163 struct imx_media_video_dev *vdev = priv->vdev;
164 struct imx_media_buffer *done, *next;
165 struct vb2_buffer *vb;
166 dma_addr_t phys;
167
168 done = priv->active_vb2_buf[priv->ipu_buf_num];
169 if (done) {
170 vb = &done->vbuf.vb2_buf;
171 vb->timestamp = ktime_get_ns();
172 vb2_buffer_done(vb, priv->nfb4eof ?
173 VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
174 }
175
176 priv->nfb4eof = false;
177
178 /* get next queued buffer */
179 next = imx_media_capture_device_next_buf(vdev);
180 if (next) {
181 phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0);
182 priv->active_vb2_buf[priv->ipu_buf_num] = next;
183 } else {
184 phys = priv->underrun_buf.phys;
185 priv->active_vb2_buf[priv->ipu_buf_num] = NULL;
186 }
187
188 if (ipu_idmac_buffer_is_ready(priv->idmac_ch, priv->ipu_buf_num))
189 ipu_idmac_clear_buffer(priv->idmac_ch, priv->ipu_buf_num);
190
191 ipu_cpmem_set_buffer(priv->idmac_ch, priv->ipu_buf_num, phys);
192}
193
194static irqreturn_t csi_idmac_eof_interrupt(int irq, void *dev_id)
195{
196 struct csi_priv *priv = dev_id;
197
198 spin_lock(&priv->irqlock);
199
200 if (priv->last_eof) {
201 complete(&priv->last_eof_comp);
202 priv->last_eof = false;
203 goto unlock;
204 }
205
206 if (priv->fim) {
207 struct timespec cur_ts;
208
209 ktime_get_ts(&cur_ts);
210 /* call frame interval monitor */
211 imx_media_fim_eof_monitor(priv->fim, &cur_ts);
212 }
213
214 csi_vb2_buf_done(priv);
215
216 /* select new IPU buf */
217 ipu_idmac_select_buffer(priv->idmac_ch, priv->ipu_buf_num);
218 /* toggle IPU double-buffer index */
219 priv->ipu_buf_num ^= 1;
220
221 /* bump the EOF timeout timer */
222 mod_timer(&priv->eof_timeout_timer,
223 jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
224
225unlock:
226 spin_unlock(&priv->irqlock);
227 return IRQ_HANDLED;
228}
229
230static irqreturn_t csi_idmac_nfb4eof_interrupt(int irq, void *dev_id)
231{
232 struct csi_priv *priv = dev_id;
233
234 spin_lock(&priv->irqlock);
235
236 /*
237 * this is not an unrecoverable error, just mark
238 * the next captured frame with vb2 error flag.
239 */
240 priv->nfb4eof = true;
241
242 v4l2_err(&priv->sd, "NFB4EOF\n");
243
244 spin_unlock(&priv->irqlock);
245
246 return IRQ_HANDLED;
247}
248
249/*
250 * EOF timeout timer function. This is an unrecoverable condition
251 * without a stream restart.
252 */
253static void csi_idmac_eof_timeout(unsigned long data)
254{
255 struct csi_priv *priv = (struct csi_priv *)data;
256 struct imx_media_video_dev *vdev = priv->vdev;
257
258 v4l2_err(&priv->sd, "EOF timeout\n");
259
260 /* signal a fatal error to capture device */
261 imx_media_capture_device_error(vdev);
262}
263
264static void csi_idmac_setup_vb2_buf(struct csi_priv *priv, dma_addr_t *phys)
265{
266 struct imx_media_video_dev *vdev = priv->vdev;
267 struct imx_media_buffer *buf;
268 int i;
269
270 for (i = 0; i < 2; i++) {
271 buf = imx_media_capture_device_next_buf(vdev);
272 if (buf) {
273 priv->active_vb2_buf[i] = buf;
274 phys[i] = vb2_dma_contig_plane_dma_addr(
275 &buf->vbuf.vb2_buf, 0);
276 } else {
277 priv->active_vb2_buf[i] = NULL;
278 phys[i] = priv->underrun_buf.phys;
279 }
280 }
281}
282
283static void csi_idmac_unsetup_vb2_buf(struct csi_priv *priv,
284 enum vb2_buffer_state return_status)
285{
286 struct imx_media_buffer *buf;
287 int i;
288
289 /* return any remaining active frames with return_status */
290 for (i = 0; i < 2; i++) {
291 buf = priv->active_vb2_buf[i];
292 if (buf) {
293 struct vb2_buffer *vb = &buf->vbuf.vb2_buf;
294
295 vb->timestamp = ktime_get_ns();
296 vb2_buffer_done(vb, return_status);
297 }
298 }
299}
300
301/* init the SMFC IDMAC channel */
302static int csi_idmac_setup_channel(struct csi_priv *priv)
303{
304 struct imx_media_video_dev *vdev = priv->vdev;
305 struct v4l2_fwnode_endpoint *sensor_ep;
306 struct v4l2_mbus_framefmt *infmt;
4a34ec8e 307 struct ipu_image image;
c8da8c03 308 u32 passthrough_bits;
4a34ec8e
SL
309 dma_addr_t phys[2];
310 bool passthrough;
c8da8c03 311 u32 burst_size;
4a34ec8e
SL
312 int ret;
313
314 infmt = &priv->format_mbus[CSI_SINK_PAD];
315 sensor_ep = &priv->sensor->sensor_ep;
316
317 ipu_cpmem_zero(priv->idmac_ch);
318
319 memset(&image, 0, sizeof(image));
320 image.pix = vdev->fmt.fmt.pix;
321 image.rect.width = image.pix.width;
322 image.rect.height = image.pix.height;
323
324 csi_idmac_setup_vb2_buf(priv, phys);
325
326 image.phys0 = phys[0];
327 image.phys1 = phys[1];
328
4a34ec8e 329 /*
c8da8c03
RK
330 * Check for conditions that require the IPU to handle the
331 * data internally as generic data, aka passthrough mode:
332 * - raw bayer formats
333 * - the sensor bus is 16-bit parallel
4a34ec8e 334 */
c8da8c03
RK
335 switch (image.pix.pixelformat) {
336 case V4L2_PIX_FMT_SBGGR8:
337 case V4L2_PIX_FMT_SGBRG8:
338 case V4L2_PIX_FMT_SGRBG8:
339 case V4L2_PIX_FMT_SRGGB8:
340 burst_size = 8;
341 passthrough = true;
342 passthrough_bits = 8;
343 break;
344 case V4L2_PIX_FMT_SBGGR16:
345 case V4L2_PIX_FMT_SGBRG16:
346 case V4L2_PIX_FMT_SGRBG16:
347 case V4L2_PIX_FMT_SRGGB16:
348 burst_size = 4;
349 passthrough = true;
350 passthrough_bits = 16;
351 break;
6f303592
PZ
352 case V4L2_PIX_FMT_YUV420:
353 case V4L2_PIX_FMT_NV12:
354 burst_size = (image.pix.width & 0x3f) ?
355 ((image.pix.width & 0x1f) ?
356 ((image.pix.width & 0xf) ? 8 : 16) : 32) : 64;
357 passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
358 sensor_ep->bus.parallel.bus_width >= 16);
359 passthrough_bits = 16;
360 break;
361 case V4L2_PIX_FMT_YUYV:
362 case V4L2_PIX_FMT_UYVY:
363 burst_size = (image.pix.width & 0x1f) ?
364 ((image.pix.width & 0xf) ? 8 : 16) : 32;
365 passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
366 sensor_ep->bus.parallel.bus_width >= 16);
367 passthrough_bits = 16;
368 break;
c8da8c03
RK
369 default:
370 burst_size = (image.pix.width & 0xf) ? 8 : 16;
371 passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
372 sensor_ep->bus.parallel.bus_width >= 16);
373 passthrough_bits = 16;
374 break;
375 }
4a34ec8e 376
c8da8c03
RK
377 if (passthrough) {
378 ipu_cpmem_set_resolution(priv->idmac_ch, image.rect.width,
379 image.rect.height);
380 ipu_cpmem_set_stride(priv->idmac_ch, image.pix.bytesperline);
381 ipu_cpmem_set_buffer(priv->idmac_ch, 0, image.phys0);
382 ipu_cpmem_set_buffer(priv->idmac_ch, 1, image.phys1);
383 ipu_cpmem_set_format_passthrough(priv->idmac_ch,
384 passthrough_bits);
385 } else {
386 ret = ipu_cpmem_set_image(priv->idmac_ch, &image);
387 if (ret)
388 goto unsetup_vb2;
389 }
390
391 ipu_cpmem_set_burstsize(priv->idmac_ch, burst_size);
4a34ec8e
SL
392
393 /*
394 * Set the channel for the direct CSI-->memory via SMFC
395 * use-case to very high priority, by enabling the watermark
396 * signal in the SMFC, enabling WM in the channel, and setting
397 * the channel priority to high.
398 *
399 * Refer to the i.mx6 rev. D TRM Table 36-8: Calculated priority
400 * value.
401 *
402 * The WM's are set very low by intention here to ensure that
403 * the SMFC FIFOs do not overflow.
404 */
405 ipu_smfc_set_watermark(priv->smfc, 0x02, 0x01);
406 ipu_cpmem_set_high_priority(priv->idmac_ch);
407 ipu_idmac_enable_watermark(priv->idmac_ch, true);
408 ipu_cpmem_set_axi_id(priv->idmac_ch, 0);
409
410 burst_size = passthrough ?
411 (burst_size >> 3) - 1 : (burst_size >> 2) - 1;
412
413 ipu_smfc_set_burstsize(priv->smfc, burst_size);
414
415 if (image.pix.field == V4L2_FIELD_NONE &&
416 V4L2_FIELD_HAS_BOTH(infmt->field))
417 ipu_cpmem_interlaced_scan(priv->idmac_ch,
418 image.pix.bytesperline);
419
420 ipu_idmac_set_double_buffer(priv->idmac_ch, true);
421
422 return 0;
423
424unsetup_vb2:
425 csi_idmac_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED);
426 return ret;
427}
428
429static void csi_idmac_unsetup(struct csi_priv *priv,
430 enum vb2_buffer_state state)
431{
432 ipu_idmac_disable_channel(priv->idmac_ch);
433 ipu_smfc_disable(priv->smfc);
434
435 csi_idmac_unsetup_vb2_buf(priv, state);
436}
437
438static int csi_idmac_setup(struct csi_priv *priv)
439{
440 int ret;
441
442 ret = csi_idmac_setup_channel(priv);
443 if (ret)
444 return ret;
445
446 ipu_cpmem_dump(priv->idmac_ch);
447 ipu_dump(priv->ipu);
448
449 ipu_smfc_enable(priv->smfc);
450
451 /* set buffers ready */
452 ipu_idmac_select_buffer(priv->idmac_ch, 0);
453 ipu_idmac_select_buffer(priv->idmac_ch, 1);
454
455 /* enable the channels */
456 ipu_idmac_enable_channel(priv->idmac_ch);
457
458 return 0;
459}
460
461static int csi_idmac_start(struct csi_priv *priv)
462{
463 struct imx_media_video_dev *vdev = priv->vdev;
464 struct v4l2_pix_format *outfmt;
465 int ret;
466
467 ret = csi_idmac_get_ipu_resources(priv);
468 if (ret)
469 return ret;
470
471 ipu_smfc_map_channel(priv->smfc, priv->csi_id, priv->vc_num);
472
473 outfmt = &vdev->fmt.fmt.pix;
474
475 ret = imx_media_alloc_dma_buf(priv->md, &priv->underrun_buf,
476 outfmt->sizeimage);
477 if (ret)
478 goto out_put_ipu;
479
480 priv->ipu_buf_num = 0;
481
482 /* init EOF completion waitq */
483 init_completion(&priv->last_eof_comp);
484 priv->last_eof = false;
485 priv->nfb4eof = false;
486
487 ret = csi_idmac_setup(priv);
488 if (ret) {
489 v4l2_err(&priv->sd, "csi_idmac_setup failed: %d\n", ret);
490 goto out_free_dma_buf;
491 }
492
493 priv->nfb4eof_irq = ipu_idmac_channel_irq(priv->ipu,
494 priv->idmac_ch,
495 IPU_IRQ_NFB4EOF);
496 ret = devm_request_irq(priv->dev, priv->nfb4eof_irq,
497 csi_idmac_nfb4eof_interrupt, 0,
498 "imx-smfc-nfb4eof", priv);
499 if (ret) {
500 v4l2_err(&priv->sd,
501 "Error registering NFB4EOF irq: %d\n", ret);
502 goto out_unsetup;
503 }
504
505 priv->eof_irq = ipu_idmac_channel_irq(priv->ipu, priv->idmac_ch,
506 IPU_IRQ_EOF);
507
508 ret = devm_request_irq(priv->dev, priv->eof_irq,
509 csi_idmac_eof_interrupt, 0,
510 "imx-smfc-eof", priv);
511 if (ret) {
512 v4l2_err(&priv->sd,
513 "Error registering eof irq: %d\n", ret);
514 goto out_free_nfb4eof_irq;
515 }
516
517 /* start the EOF timeout timer */
518 mod_timer(&priv->eof_timeout_timer,
519 jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
520
521 return 0;
522
523out_free_nfb4eof_irq:
524 devm_free_irq(priv->dev, priv->nfb4eof_irq, priv);
525out_unsetup:
526 csi_idmac_unsetup(priv, VB2_BUF_STATE_QUEUED);
527out_free_dma_buf:
528 imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
529out_put_ipu:
530 csi_idmac_put_ipu_resources(priv);
531 return ret;
532}
533
534static void csi_idmac_stop(struct csi_priv *priv)
535{
536 unsigned long flags;
537 int ret;
538
539 /* mark next EOF interrupt as the last before stream off */
540 spin_lock_irqsave(&priv->irqlock, flags);
541 priv->last_eof = true;
542 spin_unlock_irqrestore(&priv->irqlock, flags);
543
544 /*
545 * and then wait for interrupt handler to mark completion.
546 */
547 ret = wait_for_completion_timeout(
548 &priv->last_eof_comp, msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
549 if (ret == 0)
550 v4l2_warn(&priv->sd, "wait last EOF timeout\n");
551
552 devm_free_irq(priv->dev, priv->eof_irq, priv);
553 devm_free_irq(priv->dev, priv->nfb4eof_irq, priv);
554
555 csi_idmac_unsetup(priv, VB2_BUF_STATE_ERROR);
556
557 imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
558
559 /* cancel the EOF timeout timer */
560 del_timer_sync(&priv->eof_timeout_timer);
561
562 csi_idmac_put_ipu_resources(priv);
563}
564
565/* Update the CSI whole sensor and active windows */
566static int csi_setup(struct csi_priv *priv)
567{
568 struct v4l2_mbus_framefmt *infmt, *outfmt;
569 struct v4l2_mbus_config sensor_mbus_cfg;
570 struct v4l2_fwnode_endpoint *sensor_ep;
571 struct v4l2_mbus_framefmt if_fmt;
572
573 infmt = &priv->format_mbus[CSI_SINK_PAD];
574 outfmt = &priv->format_mbus[priv->active_output_pad];
575 sensor_ep = &priv->sensor->sensor_ep;
576
577 /* compose mbus_config from sensor endpoint */
578 sensor_mbus_cfg.type = sensor_ep->bus_type;
579 sensor_mbus_cfg.flags = (sensor_ep->bus_type == V4L2_MBUS_CSI2) ?
580 sensor_ep->bus.mipi_csi2.flags :
581 sensor_ep->bus.parallel.flags;
582
583 /*
584 * we need to pass input sensor frame to CSI interface, but
585 * with translated field type from output format
586 */
587 if_fmt = *infmt;
588 if_fmt.field = outfmt->field;
589
590 ipu_csi_set_window(priv->csi, &priv->crop);
591
592 ipu_csi_set_downsize(priv->csi,
69e78611
PZ
593 priv->crop.width == 2 * priv->compose.width,
594 priv->crop.height == 2 * priv->compose.height);
4a34ec8e
SL
595
596 ipu_csi_init_interface(priv->csi, &sensor_mbus_cfg, &if_fmt);
597
598 ipu_csi_set_dest(priv->csi, priv->dest);
599
fb30ee79
PZ
600 if (priv->dest == IPU_CSI_DEST_IDMAC)
601 ipu_csi_set_skip_smfc(priv->csi, priv->skip->skip_smfc,
602 priv->skip->max_ratio - 1, 0);
603
4a34ec8e
SL
604 ipu_csi_dump(priv->csi);
605
606 return 0;
607}
608
609static int csi_start(struct csi_priv *priv)
610{
fb30ee79 611 struct v4l2_fract *output_fi, *input_fi;
4a34ec8e
SL
612 u32 bad_frames = 0;
613 int ret;
614
615 if (!priv->sensor) {
616 v4l2_err(&priv->sd, "no sensor attached\n");
617 return -EINVAL;
618 }
619
fb30ee79
PZ
620 output_fi = &priv->frame_interval[priv->active_output_pad];
621 input_fi = &priv->frame_interval[CSI_SINK_PAD];
622
4a34ec8e
SL
623 ret = v4l2_subdev_call(priv->sensor->sd, sensor,
624 g_skip_frames, &bad_frames);
625 if (!ret && bad_frames) {
4a34ec8e
SL
626 u32 delay_usec;
627
628 /*
629 * This sensor has bad frames when it is turned on,
630 * add a delay to avoid them before enabling the CSI
631 * hardware. Especially for sensors with a bt.656 interface,
632 * any shifts in the SAV/EAV sync codes will cause the CSI
633 * to lose vert/horiz sync.
634 */
635 delay_usec = DIV_ROUND_UP_ULL(
fb30ee79
PZ
636 (u64)USEC_PER_SEC * input_fi->numerator * bad_frames,
637 input_fi->denominator);
4a34ec8e
SL
638 usleep_range(delay_usec, delay_usec + 1000);
639 }
640
641 if (priv->dest == IPU_CSI_DEST_IDMAC) {
642 ret = csi_idmac_start(priv);
643 if (ret)
644 return ret;
645 }
646
647 ret = csi_setup(priv);
648 if (ret)
649 goto idmac_stop;
650
651 /* start the frame interval monitor */
652 if (priv->fim && priv->dest == IPU_CSI_DEST_IDMAC) {
fb30ee79 653 ret = imx_media_fim_set_stream(priv->fim, output_fi, true);
4a34ec8e
SL
654 if (ret)
655 goto idmac_stop;
656 }
657
658 ret = ipu_csi_enable(priv->csi);
659 if (ret) {
660 v4l2_err(&priv->sd, "CSI enable error: %d\n", ret);
661 goto fim_off;
662 }
663
664 return 0;
665
666fim_off:
667 if (priv->fim && priv->dest == IPU_CSI_DEST_IDMAC)
fb30ee79 668 imx_media_fim_set_stream(priv->fim, NULL, false);
4a34ec8e
SL
669idmac_stop:
670 if (priv->dest == IPU_CSI_DEST_IDMAC)
671 csi_idmac_stop(priv);
672 return ret;
673}
674
675static void csi_stop(struct csi_priv *priv)
676{
677 if (priv->dest == IPU_CSI_DEST_IDMAC) {
678 csi_idmac_stop(priv);
679
680 /* stop the frame interval monitor */
681 if (priv->fim)
fb30ee79 682 imx_media_fim_set_stream(priv->fim, NULL, false);
4a34ec8e
SL
683 }
684
685 ipu_csi_disable(priv->csi);
686}
687
fb30ee79
PZ
688static const struct csi_skip_desc csi_skip[12] = {
689 { 1, 1, 0x00 }, /* Keep all frames */
690 { 5, 6, 0x10 }, /* Skip every sixth frame */
691 { 4, 5, 0x08 }, /* Skip every fifth frame */
692 { 3, 4, 0x04 }, /* Skip every fourth frame */
693 { 2, 3, 0x02 }, /* Skip every third frame */
694 { 3, 5, 0x0a }, /* Skip frames 1 and 3 of every 5 */
695 { 1, 2, 0x01 }, /* Skip every second frame */
696 { 2, 5, 0x0b }, /* Keep frames 1 and 4 of every 5 */
697 { 1, 3, 0x03 }, /* Keep one in three frames */
698 { 1, 4, 0x07 }, /* Keep one in four frames */
699 { 1, 5, 0x0f }, /* Keep one in five frames */
700 { 1, 6, 0x1f }, /* Keep one in six frames */
701};
702
703static void csi_apply_skip_interval(const struct csi_skip_desc *skip,
704 struct v4l2_fract *interval)
705{
706 unsigned int div;
707
708 interval->numerator *= skip->max_ratio;
709 interval->denominator *= skip->keep;
710
711 /* Reduce fraction to lowest terms */
712 div = gcd(interval->numerator, interval->denominator);
713 if (div > 1) {
714 interval->numerator /= div;
715 interval->denominator /= div;
716 }
717}
718
719/*
720 * Find the skip pattern to produce the output frame interval closest to the
721 * requested one, for the given input frame interval. Updates the output frame
722 * interval to the exact value.
723 */
724static const struct csi_skip_desc *csi_find_best_skip(struct v4l2_fract *in,
725 struct v4l2_fract *out)
726{
727 const struct csi_skip_desc *skip = &csi_skip[0], *best_skip = skip;
728 u32 min_err = UINT_MAX;
729 u64 want_us;
730 int i;
731
732 /* Default to 1:1 ratio */
733 if (out->numerator == 0 || out->denominator == 0 ||
734 in->numerator == 0 || in->denominator == 0) {
735 *out = *in;
736 return best_skip;
737 }
738
739 want_us = div_u64((u64)USEC_PER_SEC * out->numerator, out->denominator);
740
741 /* Find the reduction closest to the requested time per frame */
742 for (i = 0; i < ARRAY_SIZE(csi_skip); i++, skip++) {
743 u64 tmp, err;
744
745 tmp = div_u64((u64)USEC_PER_SEC * in->numerator *
746 skip->max_ratio, in->denominator * skip->keep);
747
748 err = abs((s64)tmp - want_us);
749 if (err < min_err) {
750 min_err = err;
751 best_skip = skip;
752 }
753 }
754
755 *out = *in;
756 csi_apply_skip_interval(best_skip, out);
757
758 return best_skip;
759}
760
4a34ec8e
SL
761/*
762 * V4L2 subdev operations.
763 */
764
765static int csi_g_frame_interval(struct v4l2_subdev *sd,
766 struct v4l2_subdev_frame_interval *fi)
767{
768 struct csi_priv *priv = v4l2_get_subdevdata(sd);
769
fb30ee79
PZ
770 if (fi->pad >= CSI_NUM_PADS)
771 return -EINVAL;
772
4a34ec8e 773 mutex_lock(&priv->lock);
fb30ee79
PZ
774
775 fi->interval = priv->frame_interval[fi->pad];
776
4a34ec8e
SL
777 mutex_unlock(&priv->lock);
778
779 return 0;
780}
781
782static int csi_s_frame_interval(struct v4l2_subdev *sd,
783 struct v4l2_subdev_frame_interval *fi)
784{
785 struct csi_priv *priv = v4l2_get_subdevdata(sd);
fb30ee79
PZ
786 struct v4l2_fract *input_fi;
787 int ret = 0;
4a34ec8e
SL
788
789 mutex_lock(&priv->lock);
790
fb30ee79 791 input_fi = &priv->frame_interval[CSI_SINK_PAD];
4a34ec8e 792
fb30ee79
PZ
793 switch (fi->pad) {
794 case CSI_SINK_PAD:
795 /* No limits on input frame interval */
796 /* Reset output intervals and frame skipping ratio to 1:1 */
797 priv->frame_interval[CSI_SRC_PAD_IDMAC] = fi->interval;
798 priv->frame_interval[CSI_SRC_PAD_DIRECT] = fi->interval;
799 priv->skip = &csi_skip[0];
800 break;
801 case CSI_SRC_PAD_IDMAC:
802 /*
803 * frame interval at IDMAC output pad depends on input
804 * interval, modified by frame skipping.
805 */
806 priv->skip = csi_find_best_skip(input_fi, &fi->interval);
807 break;
808 case CSI_SRC_PAD_DIRECT:
809 /*
810 * frame interval at DIRECT output pad is same as input
811 * interval.
812 */
813 fi->interval = *input_fi;
814 break;
815 default:
816 ret = -EINVAL;
817 goto out;
818 }
4a34ec8e 819
fb30ee79
PZ
820 priv->frame_interval[fi->pad] = fi->interval;
821out:
4a34ec8e 822 mutex_unlock(&priv->lock);
fb30ee79 823 return ret;
4a34ec8e
SL
824}
825
826static int csi_s_stream(struct v4l2_subdev *sd, int enable)
827{
828 struct csi_priv *priv = v4l2_get_subdevdata(sd);
829 int ret = 0;
830
831 mutex_lock(&priv->lock);
832
833 if (!priv->src_sd || !priv->sink) {
834 ret = -EPIPE;
835 goto out;
836 }
837
838 /*
839 * enable/disable streaming only if stream_count is
840 * going from 0 to 1 / 1 to 0.
841 */
842 if (priv->stream_count != !enable)
843 goto update_count;
844
845 if (enable) {
846 /* upstream must be started first, before starting CSI */
847 ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1);
848 ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
849 if (ret)
850 goto out;
851
852 dev_dbg(priv->dev, "stream ON\n");
853 ret = csi_start(priv);
854 if (ret) {
855 v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
856 goto out;
857 }
858 } else {
859 dev_dbg(priv->dev, "stream OFF\n");
860 /* CSI must be stopped first, then stop upstream */
861 csi_stop(priv);
862 v4l2_subdev_call(priv->src_sd, video, s_stream, 0);
863 }
864
865update_count:
866 priv->stream_count += enable ? 1 : -1;
867 WARN_ON(priv->stream_count < 0);
868out:
869 mutex_unlock(&priv->lock);
870 return ret;
871}
872
873static int csi_link_setup(struct media_entity *entity,
874 const struct media_pad *local,
875 const struct media_pad *remote, u32 flags)
876{
877 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
878 struct csi_priv *priv = v4l2_get_subdevdata(sd);
879 struct v4l2_subdev *remote_sd;
880 int ret = 0;
881
882 dev_dbg(priv->dev, "link setup %s -> %s\n", remote->entity->name,
883 local->entity->name);
884
885 mutex_lock(&priv->lock);
886
887 if (local->flags & MEDIA_PAD_FL_SINK) {
888 if (!is_media_entity_v4l2_subdev(remote->entity)) {
889 ret = -EINVAL;
890 goto out;
891 }
892
893 remote_sd = media_entity_to_v4l2_subdev(remote->entity);
894
895 if (flags & MEDIA_LNK_FL_ENABLED) {
896 if (priv->src_sd) {
897 ret = -EBUSY;
898 goto out;
899 }
900 priv->src_sd = remote_sd;
901 } else {
902 priv->src_sd = NULL;
903 }
904
905 goto out;
906 }
907
908 /* this is a source pad */
909
910 if (flags & MEDIA_LNK_FL_ENABLED) {
911 if (priv->sink) {
912 ret = -EBUSY;
913 goto out;
914 }
915 } else {
916 v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
917 v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
918 priv->sink = NULL;
919 goto out;
920 }
921
922 /* record which output pad is now active */
923 priv->active_output_pad = local->index;
924
925 /* set CSI destination */
926 if (local->index == CSI_SRC_PAD_IDMAC) {
927 if (!is_media_entity_v4l2_video_device(remote->entity)) {
928 ret = -EINVAL;
929 goto out;
930 }
931
932 if (priv->fim) {
933 ret = imx_media_fim_add_controls(priv->fim);
934 if (ret)
935 goto out;
936 }
937
938 priv->dest = IPU_CSI_DEST_IDMAC;
939 } else {
940 if (!is_media_entity_v4l2_subdev(remote->entity)) {
941 ret = -EINVAL;
942 goto out;
943 }
944
945 remote_sd = media_entity_to_v4l2_subdev(remote->entity);
946 switch (remote_sd->grp_id) {
947 case IMX_MEDIA_GRP_ID_VDIC:
948 priv->dest = IPU_CSI_DEST_VDIC;
949 break;
950 case IMX_MEDIA_GRP_ID_IC_PRP:
951 priv->dest = IPU_CSI_DEST_IC;
952 break;
953 default:
954 ret = -EINVAL;
955 goto out;
956 }
957 }
958
959 priv->sink = remote->entity;
960out:
961 mutex_unlock(&priv->lock);
962 return ret;
963}
964
965static int csi_link_validate(struct v4l2_subdev *sd,
966 struct media_link *link,
967 struct v4l2_subdev_format *source_fmt,
968 struct v4l2_subdev_format *sink_fmt)
969{
970 struct csi_priv *priv = v4l2_get_subdevdata(sd);
971 struct v4l2_fwnode_endpoint *sensor_ep;
c8da8c03 972 const struct imx_media_pixfmt *incc;
4a34ec8e
SL
973 struct imx_media_subdev *sensor;
974 bool is_csi2;
975 int ret;
976
977 ret = v4l2_subdev_link_validate_default(sd, link,
978 source_fmt, sink_fmt);
979 if (ret)
980 return ret;
981
982 sensor = __imx_media_find_sensor(priv->md, &priv->sd.entity);
983 if (IS_ERR(sensor)) {
984 v4l2_err(&priv->sd, "no sensor attached\n");
985 return PTR_ERR(priv->sensor);
986 }
987
988 mutex_lock(&priv->lock);
989
990 priv->sensor = sensor;
991 sensor_ep = &priv->sensor->sensor_ep;
992 is_csi2 = (sensor_ep->bus_type == V4L2_MBUS_CSI2);
c8da8c03
RK
993 incc = priv->cc[CSI_SINK_PAD];
994
995 if (priv->dest != IPU_CSI_DEST_IDMAC &&
996 (incc->bayer || (!is_csi2 &&
997 sensor_ep->bus.parallel.bus_width >= 16))) {
998 v4l2_err(&priv->sd,
999 "bayer/16-bit parallel buses must go to IDMAC pad\n");
1000 ret = -EINVAL;
1001 goto out;
1002 }
4a34ec8e
SL
1003
1004 if (is_csi2) {
1005 int vc_num = 0;
1006 /*
1007 * NOTE! It seems the virtual channels from the mipi csi-2
1008 * receiver are used only for routing by the video mux's,
1009 * or for hard-wired routing to the CSI's. Once the stream
1010 * enters the CSI's however, they are treated internally
1011 * in the IPU as virtual channel 0.
1012 */
1013#if 0
1014 mutex_unlock(&priv->lock);
1015 vc_num = imx_media_find_mipi_csi2_channel(priv->md,
1016 &priv->sd.entity);
1017 if (vc_num < 0)
1018 return vc_num;
1019 mutex_lock(&priv->lock);
1020#endif
1021 ipu_csi_set_mipi_datatype(priv->csi, vc_num,
1022 &priv->format_mbus[CSI_SINK_PAD]);
1023 }
1024
1025 /* select either parallel or MIPI-CSI2 as input to CSI */
1026 ipu_set_csi_src_mux(priv->ipu, priv->csi_id, is_csi2);
c8da8c03 1027out:
4a34ec8e
SL
1028 mutex_unlock(&priv->lock);
1029 return ret;
1030}
1031
1032static struct v4l2_mbus_framefmt *
1033__csi_get_fmt(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg,
1034 unsigned int pad, enum v4l2_subdev_format_whence which)
1035{
1036 if (which == V4L2_SUBDEV_FORMAT_TRY)
1037 return v4l2_subdev_get_try_format(&priv->sd, cfg, pad);
1038 else
1039 return &priv->format_mbus[pad];
1040}
1041
1042static struct v4l2_rect *
1043__csi_get_crop(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg,
1044 enum v4l2_subdev_format_whence which)
1045{
1046 if (which == V4L2_SUBDEV_FORMAT_TRY)
1047 return v4l2_subdev_get_try_crop(&priv->sd, cfg, CSI_SINK_PAD);
1048 else
1049 return &priv->crop;
1050}
1051
69e78611
PZ
1052static struct v4l2_rect *
1053__csi_get_compose(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg,
1054 enum v4l2_subdev_format_whence which)
1055{
1056 if (which == V4L2_SUBDEV_FORMAT_TRY)
1057 return v4l2_subdev_get_try_compose(&priv->sd, cfg,
1058 CSI_SINK_PAD);
1059 else
1060 return &priv->compose;
1061}
1062
4a34ec8e
SL
1063static void csi_try_crop(struct csi_priv *priv,
1064 struct v4l2_rect *crop,
1065 struct v4l2_subdev_pad_config *cfg,
1066 struct v4l2_mbus_framefmt *infmt,
1067 struct imx_media_subdev *sensor)
1068{
1069 struct v4l2_fwnode_endpoint *sensor_ep;
1070
1071 sensor_ep = &sensor->sensor_ep;
1072
1073 crop->width = min_t(__u32, infmt->width, crop->width);
1074 if (crop->left + crop->width > infmt->width)
1075 crop->left = infmt->width - crop->width;
1076 /* adjust crop left/width to h/w alignment restrictions */
1077 crop->left &= ~0x3;
1078 crop->width &= ~0x7;
1079
1080 /*
1081 * FIXME: not sure why yet, but on interlaced bt.656,
1082 * changing the vertical cropping causes loss of vertical
1083 * sync, so fix it to NTSC/PAL active lines. NTSC contains
1084 * 2 extra lines of active video that need to be cropped.
1085 */
1086 if (sensor_ep->bus_type == V4L2_MBUS_BT656 &&
1087 (V4L2_FIELD_HAS_BOTH(infmt->field) ||
1088 infmt->field == V4L2_FIELD_ALTERNATE)) {
1089 crop->height = infmt->height;
1090 crop->top = (infmt->height == 480) ? 2 : 0;
1091 } else {
1092 crop->height = min_t(__u32, infmt->height, crop->height);
1093 if (crop->top + crop->height > infmt->height)
1094 crop->top = infmt->height - crop->height;
1095 }
1096}
1097
1098static int csi_enum_mbus_code(struct v4l2_subdev *sd,
1099 struct v4l2_subdev_pad_config *cfg,
1100 struct v4l2_subdev_mbus_code_enum *code)
1101{
1102 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1103 const struct imx_media_pixfmt *incc;
1104 struct v4l2_mbus_framefmt *infmt;
1105 int ret = 0;
1106
1107 mutex_lock(&priv->lock);
1108
1109 infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, code->which);
1110 incc = imx_media_find_mbus_format(infmt->code, CS_SEL_ANY, true);
1111
1112 switch (code->pad) {
1113 case CSI_SINK_PAD:
1114 ret = imx_media_enum_mbus_format(&code->code, code->index,
1115 CS_SEL_ANY, true);
1116 break;
1117 case CSI_SRC_PAD_DIRECT:
1118 case CSI_SRC_PAD_IDMAC:
1119 if (incc->bayer) {
1120 if (code->index != 0) {
1121 ret = -EINVAL;
1122 goto out;
1123 }
1124 code->code = infmt->code;
1125 } else {
1126 u32 cs_sel = (incc->cs == IPUV3_COLORSPACE_YUV) ?
1127 CS_SEL_YUV : CS_SEL_RGB;
1128 ret = imx_media_enum_ipu_format(&code->code,
1129 code->index,
1130 cs_sel);
1131 }
1132 break;
1133 default:
1134 ret = -EINVAL;
1135 }
1136
1137out:
1138 mutex_unlock(&priv->lock);
1139 return ret;
1140}
1141
949ffdbf
RK
1142static int csi_enum_frame_size(struct v4l2_subdev *sd,
1143 struct v4l2_subdev_pad_config *cfg,
1144 struct v4l2_subdev_frame_size_enum *fse)
1145{
1146 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1147 struct v4l2_rect *crop;
1148 int ret = 0;
1149
1150 if (fse->pad >= CSI_NUM_PADS ||
1151 fse->index > (fse->pad == CSI_SINK_PAD ? 0 : 3))
1152 return -EINVAL;
1153
1154 mutex_lock(&priv->lock);
1155
1156 if (fse->pad == CSI_SINK_PAD) {
1157 fse->min_width = MIN_W;
1158 fse->max_width = MAX_W;
1159 fse->min_height = MIN_H;
1160 fse->max_height = MAX_H;
1161 } else {
1162 crop = __csi_get_crop(priv, cfg, fse->which);
1163
1164 fse->min_width = fse->max_width = fse->index & 1 ?
1165 crop->width / 2 : crop->width;
1166 fse->min_height = fse->max_height = fse->index & 2 ?
1167 crop->height / 2 : crop->height;
1168 }
1169
1170 mutex_unlock(&priv->lock);
1171 return ret;
1172}
1173
1174static int csi_enum_frame_interval(struct v4l2_subdev *sd,
1175 struct v4l2_subdev_pad_config *cfg,
1176 struct v4l2_subdev_frame_interval_enum *fie)
1177{
1178 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1179 struct v4l2_fract *input_fi;
1180 struct v4l2_rect *crop;
1181 int ret = 0;
1182
1183 if (fie->pad >= CSI_NUM_PADS ||
1184 fie->index >= (fie->pad != CSI_SRC_PAD_IDMAC ?
1185 1 : ARRAY_SIZE(csi_skip)))
1186 return -EINVAL;
1187
1188 mutex_lock(&priv->lock);
1189
1190 input_fi = &priv->frame_interval[CSI_SINK_PAD];
1191 crop = __csi_get_crop(priv, cfg, fie->which);
1192
1193 if ((fie->width != crop->width && fie->width != crop->width / 2) ||
1194 (fie->height != crop->height && fie->height != crop->height / 2)) {
1195 ret = -EINVAL;
1196 goto out;
1197 }
1198
1199 fie->interval = *input_fi;
1200
1201 if (fie->pad == CSI_SRC_PAD_IDMAC)
1202 csi_apply_skip_interval(&csi_skip[fie->index],
1203 &fie->interval);
1204
1205out:
1206 mutex_unlock(&priv->lock);
1207 return ret;
1208}
1209
4a34ec8e
SL
1210static int csi_get_fmt(struct v4l2_subdev *sd,
1211 struct v4l2_subdev_pad_config *cfg,
1212 struct v4l2_subdev_format *sdformat)
1213{
1214 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1215 struct v4l2_mbus_framefmt *fmt;
1216 int ret = 0;
1217
1218 if (sdformat->pad >= CSI_NUM_PADS)
1219 return -EINVAL;
1220
1221 mutex_lock(&priv->lock);
1222
1223 fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
1224 if (!fmt) {
1225 ret = -EINVAL;
1226 goto out;
1227 }
1228
1229 sdformat->format = *fmt;
1230out:
1231 mutex_unlock(&priv->lock);
1232 return ret;
1233}
1234
1235static void csi_try_fmt(struct csi_priv *priv,
1236 struct imx_media_subdev *sensor,
1237 struct v4l2_subdev_pad_config *cfg,
1238 struct v4l2_subdev_format *sdformat,
1239 struct v4l2_rect *crop,
69e78611 1240 struct v4l2_rect *compose,
4a34ec8e
SL
1241 const struct imx_media_pixfmt **cc)
1242{
1243 const struct imx_media_pixfmt *incc;
1244 struct v4l2_mbus_framefmt *infmt;
1245 u32 code;
1246
1247 switch (sdformat->pad) {
1248 case CSI_SRC_PAD_DIRECT:
1249 case CSI_SRC_PAD_IDMAC:
1250 infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD,
1251 sdformat->which);
1252 incc = imx_media_find_mbus_format(infmt->code,
1253 CS_SEL_ANY, true);
1254
69e78611
PZ
1255 sdformat->format.width = compose->width;
1256 sdformat->format.height = compose->height;
4a34ec8e
SL
1257
1258 if (incc->bayer) {
1259 sdformat->format.code = infmt->code;
1260 *cc = incc;
1261 } else {
1262 u32 cs_sel = (incc->cs == IPUV3_COLORSPACE_YUV) ?
1263 CS_SEL_YUV : CS_SEL_RGB;
1264
1265 *cc = imx_media_find_ipu_format(sdformat->format.code,
1266 cs_sel);
1267 if (!*cc) {
1268 imx_media_enum_ipu_format(&code, 0, cs_sel);
1269 *cc = imx_media_find_ipu_format(code, cs_sel);
1270 sdformat->format.code = (*cc)->codes[0];
1271 }
1272 }
1273
1274 if (sdformat->pad == CSI_SRC_PAD_DIRECT ||
1275 sdformat->format.field != V4L2_FIELD_NONE)
1276 sdformat->format.field = infmt->field;
1277
1278 /*
1279 * translate V4L2_FIELD_ALTERNATE to SEQ_TB or SEQ_BT
1280 * depending on input height (assume NTSC top-bottom
1281 * order if 480 lines, otherwise PAL bottom-top order).
1282 */
1283 if (sdformat->format.field == V4L2_FIELD_ALTERNATE) {
1284 sdformat->format.field = (infmt->height == 480) ?
1285 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
1286 }
1287 break;
1288 case CSI_SINK_PAD:
1289 v4l_bound_align_image(&sdformat->format.width, MIN_W, MAX_W,
1290 W_ALIGN, &sdformat->format.height,
1291 MIN_H, MAX_H, H_ALIGN, S_ALIGN);
69e78611
PZ
1292
1293 /* Reset crop and compose rectangles */
4a34ec8e
SL
1294 crop->left = 0;
1295 crop->top = 0;
1296 crop->width = sdformat->format.width;
1297 crop->height = sdformat->format.height;
1298 csi_try_crop(priv, crop, cfg, &sdformat->format, sensor);
69e78611
PZ
1299 compose->left = 0;
1300 compose->top = 0;
1301 compose->width = crop->width;
1302 compose->height = crop->height;
4a34ec8e
SL
1303
1304 *cc = imx_media_find_mbus_format(sdformat->format.code,
1305 CS_SEL_ANY, true);
1306 if (!*cc) {
1307 imx_media_enum_mbus_format(&code, 0,
1308 CS_SEL_ANY, false);
1309 *cc = imx_media_find_mbus_format(code,
1310 CS_SEL_ANY, false);
1311 sdformat->format.code = (*cc)->codes[0];
1312 }
1313 break;
1314 }
1315}
1316
1317static int csi_set_fmt(struct v4l2_subdev *sd,
1318 struct v4l2_subdev_pad_config *cfg,
1319 struct v4l2_subdev_format *sdformat)
1320{
1321 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1322 struct imx_media_video_dev *vdev = priv->vdev;
1323 const struct imx_media_pixfmt *cc;
1324 struct imx_media_subdev *sensor;
1325 struct v4l2_pix_format vdev_fmt;
1326 struct v4l2_mbus_framefmt *fmt;
69e78611 1327 struct v4l2_rect *crop, *compose;
4a34ec8e
SL
1328 int ret = 0;
1329
1330 if (sdformat->pad >= CSI_NUM_PADS)
1331 return -EINVAL;
1332
1333 sensor = imx_media_find_sensor(priv->md, &priv->sd.entity);
1334 if (IS_ERR(sensor)) {
1335 v4l2_err(&priv->sd, "no sensor attached\n");
1336 return PTR_ERR(sensor);
1337 }
1338
1339 mutex_lock(&priv->lock);
1340
1341 if (priv->stream_count > 0) {
1342 ret = -EBUSY;
1343 goto out;
1344 }
1345
1346 crop = __csi_get_crop(priv, cfg, sdformat->which);
69e78611 1347 compose = __csi_get_compose(priv, cfg, sdformat->which);
4a34ec8e 1348
69e78611 1349 csi_try_fmt(priv, sensor, cfg, sdformat, crop, compose, &cc);
4a34ec8e
SL
1350
1351 fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
1352 *fmt = sdformat->format;
1353
1354 if (sdformat->pad == CSI_SINK_PAD) {
1355 int pad;
1356
1357 /* propagate format to source pads */
1358 for (pad = CSI_SINK_PAD + 1; pad < CSI_NUM_PADS; pad++) {
1359 const struct imx_media_pixfmt *outcc;
1360 struct v4l2_mbus_framefmt *outfmt;
1361 struct v4l2_subdev_format format;
1362
1363 format.pad = pad;
1364 format.which = sdformat->which;
1365 format.format = sdformat->format;
69e78611
PZ
1366 csi_try_fmt(priv, sensor, cfg, &format, NULL, compose,
1367 &outcc);
4a34ec8e
SL
1368
1369 outfmt = __csi_get_fmt(priv, cfg, pad, sdformat->which);
1370 *outfmt = format.format;
1371
1372 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1373 priv->cc[pad] = outcc;
1374 }
1375 }
1376
1377 if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
1378 goto out;
1379
1380 priv->cc[sdformat->pad] = cc;
1381
1382 /* propagate IDMAC output pad format to capture device */
1383 imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
1384 &priv->format_mbus[CSI_SRC_PAD_IDMAC],
1385 priv->cc[CSI_SRC_PAD_IDMAC]);
1386 mutex_unlock(&priv->lock);
1387 imx_media_capture_device_set_format(vdev, &vdev_fmt);
1388
1389 return 0;
1390out:
1391 mutex_unlock(&priv->lock);
1392 return ret;
1393}
1394
1395static int csi_get_selection(struct v4l2_subdev *sd,
1396 struct v4l2_subdev_pad_config *cfg,
1397 struct v4l2_subdev_selection *sel)
1398{
1399 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1400 struct v4l2_mbus_framefmt *infmt;
69e78611 1401 struct v4l2_rect *crop, *compose;
4a34ec8e
SL
1402 int ret = 0;
1403
69e78611 1404 if (sel->pad != CSI_SINK_PAD)
4a34ec8e
SL
1405 return -EINVAL;
1406
1407 mutex_lock(&priv->lock);
1408
1409 infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sel->which);
1410 crop = __csi_get_crop(priv, cfg, sel->which);
69e78611 1411 compose = __csi_get_compose(priv, cfg, sel->which);
4a34ec8e
SL
1412
1413 switch (sel->target) {
1414 case V4L2_SEL_TGT_CROP_BOUNDS:
1415 sel->r.left = 0;
1416 sel->r.top = 0;
1417 sel->r.width = infmt->width;
1418 sel->r.height = infmt->height;
1419 break;
1420 case V4L2_SEL_TGT_CROP:
1421 sel->r = *crop;
1422 break;
69e78611
PZ
1423 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1424 sel->r.left = 0;
1425 sel->r.top = 0;
1426 sel->r.width = crop->width;
1427 sel->r.height = crop->height;
1428 break;
1429 case V4L2_SEL_TGT_COMPOSE:
1430 sel->r = *compose;
1431 break;
4a34ec8e
SL
1432 default:
1433 ret = -EINVAL;
1434 }
1435
1436 mutex_unlock(&priv->lock);
1437 return ret;
1438}
1439
69e78611
PZ
1440static int csi_set_scale(u32 *compose, u32 crop, u32 flags)
1441{
1442 if ((flags & (V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE)) ==
1443 (V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE) &&
1444 *compose != crop && *compose != crop / 2)
1445 return -ERANGE;
1446
1447 if (*compose <= crop / 2 ||
1448 (*compose < crop * 3 / 4 && !(flags & V4L2_SEL_FLAG_GE)) ||
1449 (*compose < crop && (flags & V4L2_SEL_FLAG_LE)))
1450 *compose = crop / 2;
1451 else
1452 *compose = crop;
1453
1454 return 0;
1455}
1456
4a34ec8e
SL
1457static int csi_set_selection(struct v4l2_subdev *sd,
1458 struct v4l2_subdev_pad_config *cfg,
1459 struct v4l2_subdev_selection *sel)
1460{
1461 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1462 struct v4l2_mbus_framefmt *infmt;
69e78611 1463 struct v4l2_rect *crop, *compose;
4a34ec8e 1464 struct imx_media_subdev *sensor;
4a34ec8e
SL
1465 int pad, ret = 0;
1466
69e78611 1467 if (sel->pad != CSI_SINK_PAD)
4a34ec8e
SL
1468 return -EINVAL;
1469
1470 sensor = imx_media_find_sensor(priv->md, &priv->sd.entity);
1471 if (IS_ERR(sensor)) {
1472 v4l2_err(&priv->sd, "no sensor attached\n");
1473 return PTR_ERR(sensor);
1474 }
1475
1476 mutex_lock(&priv->lock);
1477
1478 if (priv->stream_count > 0) {
1479 ret = -EBUSY;
1480 goto out;
1481 }
1482
1483 infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sel->which);
1484 crop = __csi_get_crop(priv, cfg, sel->which);
69e78611 1485 compose = __csi_get_compose(priv, cfg, sel->which);
4a34ec8e 1486
69e78611
PZ
1487 switch (sel->target) {
1488 case V4L2_SEL_TGT_CROP:
1489 /*
1490 * Modifying the crop rectangle always changes the format on
1491 * the source pads. If the KEEP_CONFIG flag is set, just return
1492 * the current crop rectangle.
1493 */
1494 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
1495 sel->r = priv->crop;
1496 if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
1497 *crop = sel->r;
1498 goto out;
1499 }
1500
1501 csi_try_crop(priv, &sel->r, cfg, infmt, sensor);
1502
1503 *crop = sel->r;
1504
1505 /* Reset scaling to 1:1 */
1506 compose->width = crop->width;
1507 compose->height = crop->height;
1508 break;
1509 case V4L2_SEL_TGT_COMPOSE:
1510 /*
1511 * Modifying the compose rectangle always changes the format on
1512 * the source pads. If the KEEP_CONFIG flag is set, just return
1513 * the current compose rectangle.
1514 */
1515 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
1516 sel->r = priv->compose;
1517 if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
1518 *compose = sel->r;
1519 goto out;
1520 }
4a34ec8e 1521
69e78611
PZ
1522 sel->r.left = 0;
1523 sel->r.top = 0;
1524 ret = csi_set_scale(&sel->r.width, crop->width, sel->flags);
1525 if (ret)
1526 goto out;
1527 ret = csi_set_scale(&sel->r.height, crop->height, sel->flags);
1528 if (ret)
1529 goto out;
4a34ec8e 1530
69e78611
PZ
1531 *compose = sel->r;
1532 break;
1533 default:
1534 ret = -EINVAL;
1535 goto out;
1536 }
4a34ec8e 1537
69e78611 1538 /* Reset source pads to sink compose rectangle */
4a34ec8e
SL
1539 for (pad = CSI_SINK_PAD + 1; pad < CSI_NUM_PADS; pad++) {
1540 struct v4l2_mbus_framefmt *outfmt;
1541
1542 outfmt = __csi_get_fmt(priv, cfg, pad, sel->which);
69e78611
PZ
1543 outfmt->width = compose->width;
1544 outfmt->height = compose->height;
4a34ec8e
SL
1545 }
1546
1547out:
1548 mutex_unlock(&priv->lock);
1549 return ret;
1550}
1551
1552static int csi_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1553 struct v4l2_event_subscription *sub)
1554{
1555 if (sub->type != V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR)
1556 return -EINVAL;
1557 if (sub->id != 0)
1558 return -EINVAL;
1559
1560 return v4l2_event_subscribe(fh, sub, 0, NULL);
1561}
1562
1563static int csi_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1564 struct v4l2_event_subscription *sub)
1565{
1566 return v4l2_event_unsubscribe(fh, sub);
1567}
1568
1569/*
1570 * retrieve our pads parsed from the OF graph by the media device
1571 */
1572static int csi_registered(struct v4l2_subdev *sd)
1573{
1574 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1575 int i, ret;
1576 u32 code;
1577
1578 /* get media device */
1579 priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
1580
1581 /* get handle to IPU CSI */
1582 priv->csi = ipu_csi_get(priv->ipu, priv->csi_id);
1583 if (IS_ERR(priv->csi)) {
1584 v4l2_err(&priv->sd, "failed to get CSI%d\n", priv->csi_id);
1585 return PTR_ERR(priv->csi);
1586 }
1587
1588 for (i = 0; i < CSI_NUM_PADS; i++) {
1589 priv->pad[i].flags = (i == CSI_SINK_PAD) ?
1590 MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
1591
1592 code = 0;
1593 if (i != CSI_SINK_PAD)
1594 imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
1595
1596 /* set a default mbus format */
1597 ret = imx_media_init_mbus_fmt(&priv->format_mbus[i],
1598 640, 480, code, V4L2_FIELD_NONE,
1599 &priv->cc[i]);
1600 if (ret)
1601 goto put_csi;
fb30ee79
PZ
1602
1603 /* init default frame interval */
1604 priv->frame_interval[i].numerator = 1;
1605 priv->frame_interval[i].denominator = 30;
4a34ec8e
SL
1606 }
1607
fb30ee79
PZ
1608 /* disable frame skipping */
1609 priv->skip = &csi_skip[0];
4a34ec8e 1610
69e78611
PZ
1611 /* init default crop and compose rectangle sizes */
1612 priv->crop.width = 640;
1613 priv->crop.height = 480;
1614 priv->compose.width = 640;
1615 priv->compose.height = 480;
1616
4a34ec8e
SL
1617 priv->fim = imx_media_fim_init(&priv->sd);
1618 if (IS_ERR(priv->fim)) {
1619 ret = PTR_ERR(priv->fim);
1620 goto put_csi;
1621 }
1622
1623 ret = media_entity_pads_init(&sd->entity, CSI_NUM_PADS, priv->pad);
1624 if (ret)
1625 goto free_fim;
1626
1627 ret = imx_media_capture_device_register(priv->vdev);
1628 if (ret)
1629 goto free_fim;
1630
1631 ret = imx_media_add_video_device(priv->md, priv->vdev);
1632 if (ret)
1633 goto unreg;
1634
1635 return 0;
1636unreg:
1637 imx_media_capture_device_unregister(priv->vdev);
1638free_fim:
1639 if (priv->fim)
1640 imx_media_fim_free(priv->fim);
1641put_csi:
1642 ipu_csi_put(priv->csi);
1643 return ret;
1644}
1645
1646static void csi_unregistered(struct v4l2_subdev *sd)
1647{
1648 struct csi_priv *priv = v4l2_get_subdevdata(sd);
1649
1650 imx_media_capture_device_unregister(priv->vdev);
1651
1652 if (priv->fim)
1653 imx_media_fim_free(priv->fim);
1654
1655 if (!IS_ERR_OR_NULL(priv->csi))
1656 ipu_csi_put(priv->csi);
1657}
1658
1659static const struct media_entity_operations csi_entity_ops = {
1660 .link_setup = csi_link_setup,
1661 .link_validate = v4l2_subdev_link_validate,
1662};
1663
1664static const struct v4l2_subdev_core_ops csi_core_ops = {
1665 .subscribe_event = csi_subscribe_event,
1666 .unsubscribe_event = csi_unsubscribe_event,
1667};
1668
1669static const struct v4l2_subdev_video_ops csi_video_ops = {
1670 .g_frame_interval = csi_g_frame_interval,
1671 .s_frame_interval = csi_s_frame_interval,
1672 .s_stream = csi_s_stream,
1673};
1674
1675static const struct v4l2_subdev_pad_ops csi_pad_ops = {
1676 .enum_mbus_code = csi_enum_mbus_code,
949ffdbf
RK
1677 .enum_frame_size = csi_enum_frame_size,
1678 .enum_frame_interval = csi_enum_frame_interval,
4a34ec8e
SL
1679 .get_fmt = csi_get_fmt,
1680 .set_fmt = csi_set_fmt,
1681 .get_selection = csi_get_selection,
1682 .set_selection = csi_set_selection,
1683 .link_validate = csi_link_validate,
1684};
1685
1686static const struct v4l2_subdev_ops csi_subdev_ops = {
1687 .core = &csi_core_ops,
1688 .video = &csi_video_ops,
1689 .pad = &csi_pad_ops,
1690};
1691
1692static const struct v4l2_subdev_internal_ops csi_internal_ops = {
1693 .registered = csi_registered,
1694 .unregistered = csi_unregistered,
1695};
1696
1697static int imx_csi_probe(struct platform_device *pdev)
1698{
1699 struct ipu_client_platformdata *pdata;
1700 struct pinctrl *pinctrl;
1701 struct csi_priv *priv;
1702 int ret;
1703
1704 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1705 if (!priv)
1706 return -ENOMEM;
1707
1708 platform_set_drvdata(pdev, &priv->sd);
1709 priv->dev = &pdev->dev;
1710
1711 ret = dma_set_coherent_mask(priv->dev, DMA_BIT_MASK(32));
1712 if (ret)
1713 return ret;
1714
1715 /* get parent IPU */
1716 priv->ipu = dev_get_drvdata(priv->dev->parent);
1717
1718 /* get our CSI id */
1719 pdata = priv->dev->platform_data;
1720 priv->csi_id = pdata->csi;
1721 priv->smfc_id = (priv->csi_id == 0) ? 0 : 2;
1722
1723 init_timer(&priv->eof_timeout_timer);
1724 priv->eof_timeout_timer.data = (unsigned long)priv;
1725 priv->eof_timeout_timer.function = csi_idmac_eof_timeout;
1726 spin_lock_init(&priv->irqlock);
1727
1728 v4l2_subdev_init(&priv->sd, &csi_subdev_ops);
1729 v4l2_set_subdevdata(&priv->sd, priv);
1730 priv->sd.internal_ops = &csi_internal_ops;
1731 priv->sd.entity.ops = &csi_entity_ops;
1732 priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1733 priv->sd.dev = &pdev->dev;
1734 priv->sd.fwnode = of_fwnode_handle(pdata->of_node);
1735 priv->sd.owner = THIS_MODULE;
1736 priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
1737 priv->sd.grp_id = priv->csi_id ?
1738 IMX_MEDIA_GRP_ID_CSI1 : IMX_MEDIA_GRP_ID_CSI0;
1739 imx_media_grp_id_to_sd_name(priv->sd.name, sizeof(priv->sd.name),
1740 priv->sd.grp_id, ipu_get_num(priv->ipu));
1741
1742 priv->vdev = imx_media_capture_device_init(&priv->sd,
1743 CSI_SRC_PAD_IDMAC);
1744 if (IS_ERR(priv->vdev))
1745 return PTR_ERR(priv->vdev);
1746
1747 mutex_init(&priv->lock);
1748
1749 v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
1750 priv->sd.ctrl_handler = &priv->ctrl_hdlr;
1751
1752 /*
1753 * The IPUv3 driver did not assign an of_node to this
1754 * device. As a result, pinctrl does not automatically
1755 * configure our pin groups, so we need to do that manually
1756 * here, after setting this device's of_node.
1757 */
1758 priv->dev->of_node = pdata->of_node;
1759 pinctrl = devm_pinctrl_get_select_default(priv->dev);
1760
1761 ret = v4l2_async_register_subdev(&priv->sd);
1762 if (ret)
1763 goto free;
1764
1765 return 0;
1766free:
1767 v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
1768 mutex_destroy(&priv->lock);
1769 imx_media_capture_device_remove(priv->vdev);
1770 return ret;
1771}
1772
1773static int imx_csi_remove(struct platform_device *pdev)
1774{
1775 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
1776 struct csi_priv *priv = sd_to_dev(sd);
1777
1778 v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
1779 mutex_destroy(&priv->lock);
1780 imx_media_capture_device_remove(priv->vdev);
1781 v4l2_async_unregister_subdev(sd);
1782 media_entity_cleanup(&sd->entity);
1783
1784 return 0;
1785}
1786
1787static const struct platform_device_id imx_csi_ids[] = {
1788 { .name = "imx-ipuv3-csi" },
1789 { },
1790};
1791MODULE_DEVICE_TABLE(platform, imx_csi_ids);
1792
1793static struct platform_driver imx_csi_driver = {
1794 .probe = imx_csi_probe,
1795 .remove = imx_csi_remove,
1796 .id_table = imx_csi_ids,
1797 .driver = {
1798 .name = "imx-ipuv3-csi",
1799 },
1800};
1801module_platform_driver(imx_csi_driver);
1802
1803MODULE_DESCRIPTION("i.MX CSI subdev driver");
1804MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
1805MODULE_LICENSE("GPL");
1806MODULE_ALIAS("platform:imx-ipuv3-csi");