2 * V4L2 Capture CSI Subdev for Freescale i.MX5/6 SOC
4 * Copyright (c) 2014-2017 Mentor Graphics Inc.
5 * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
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.
12 #include <linux/delay.h>
13 #include <linux/gcd.h>
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"
30 * Min/Max supported width and heights.
32 * We allow planar output, so we have to align width by 16 pixels
33 * to meet IDMAC alignment requirements.
35 * TODO: move this into pad format negotiation, if capture device
36 * has not requested planar formats, we should allow 8 pixel
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 */
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
53 struct csi_skip_desc
{
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
;
71 /* lock to protect all members below */
74 int active_output_pad
;
76 struct ipuv3_channel
*idmac_ch
;
77 struct ipu_smfc
*smfc
;
80 struct v4l2_mbus_framefmt format_mbus
[CSI_NUM_PADS
];
81 const struct imx_media_pixfmt
*cc
[CSI_NUM_PADS
];
82 struct v4l2_fract frame_interval
[CSI_NUM_PADS
];
83 struct v4l2_rect crop
;
84 struct v4l2_rect compose
;
85 const struct csi_skip_desc
*skip
;
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
;
91 int ipu_buf_num
; /* ipu double buffer index: 0-1 */
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
;
99 /* the mipi virtual channel number at link validate */
102 /* the attached sensor at stream on */
103 struct imx_media_subdev
*sensor
;
105 spinlock_t irqlock
; /* protect eof_irq handler */
106 struct timer_list eof_timeout_timer
;
110 struct v4l2_ctrl_handler ctrl_hdlr
;
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
;
118 static inline struct csi_priv
*sd_to_dev(struct v4l2_subdev
*sdev
)
120 return container_of(sdev
, struct csi_priv
, sd
);
123 static void csi_idmac_put_ipu_resources(struct csi_priv
*priv
)
126 ipu_idmac_put(priv
->idmac_ch
);
127 priv
->idmac_ch
= NULL
;
130 ipu_smfc_put(priv
->smfc
);
134 static int csi_idmac_get_ipu_resources(struct csi_priv
*priv
)
137 struct ipu_smfc
*smfc
;
138 struct ipuv3_channel
*idmac_ch
;
140 ch_num
= IPUV3_CHANNEL_CSI0
+ priv
->smfc_id
;
142 smfc
= ipu_smfc_get(priv
->ipu
, ch_num
);
144 v4l2_err(&priv
->sd
, "failed to get SMFC\n");
150 idmac_ch
= ipu_idmac_get(priv
->ipu
, ch_num
);
151 if (IS_ERR(idmac_ch
)) {
152 v4l2_err(&priv
->sd
, "could not get IDMAC channel %u\n",
154 ret
= PTR_ERR(idmac_ch
);
157 priv
->idmac_ch
= idmac_ch
;
161 csi_idmac_put_ipu_resources(priv
);
165 static void csi_vb2_buf_done(struct csi_priv
*priv
)
167 struct imx_media_video_dev
*vdev
= priv
->vdev
;
168 struct imx_media_buffer
*done
, *next
;
169 struct vb2_buffer
*vb
;
172 done
= priv
->active_vb2_buf
[priv
->ipu_buf_num
];
174 vb
= &done
->vbuf
.vb2_buf
;
175 vb
->timestamp
= ktime_get_ns();
176 vb2_buffer_done(vb
, priv
->nfb4eof
?
177 VB2_BUF_STATE_ERROR
: VB2_BUF_STATE_DONE
);
180 priv
->nfb4eof
= false;
182 /* get next queued buffer */
183 next
= imx_media_capture_device_next_buf(vdev
);
185 phys
= vb2_dma_contig_plane_dma_addr(&next
->vbuf
.vb2_buf
, 0);
186 priv
->active_vb2_buf
[priv
->ipu_buf_num
] = next
;
188 phys
= priv
->underrun_buf
.phys
;
189 priv
->active_vb2_buf
[priv
->ipu_buf_num
] = NULL
;
192 if (ipu_idmac_buffer_is_ready(priv
->idmac_ch
, priv
->ipu_buf_num
))
193 ipu_idmac_clear_buffer(priv
->idmac_ch
, priv
->ipu_buf_num
);
195 ipu_cpmem_set_buffer(priv
->idmac_ch
, priv
->ipu_buf_num
, phys
);
198 static irqreturn_t
csi_idmac_eof_interrupt(int irq
, void *dev_id
)
200 struct csi_priv
*priv
= dev_id
;
202 spin_lock(&priv
->irqlock
);
204 if (priv
->last_eof
) {
205 complete(&priv
->last_eof_comp
);
206 priv
->last_eof
= false;
211 struct timespec cur_ts
;
213 ktime_get_ts(&cur_ts
);
214 /* call frame interval monitor */
215 imx_media_fim_eof_monitor(priv
->fim
, &cur_ts
);
218 csi_vb2_buf_done(priv
);
220 /* select new IPU buf */
221 ipu_idmac_select_buffer(priv
->idmac_ch
, priv
->ipu_buf_num
);
222 /* toggle IPU double-buffer index */
223 priv
->ipu_buf_num
^= 1;
225 /* bump the EOF timeout timer */
226 mod_timer(&priv
->eof_timeout_timer
,
227 jiffies
+ msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT
));
230 spin_unlock(&priv
->irqlock
);
234 static irqreturn_t
csi_idmac_nfb4eof_interrupt(int irq
, void *dev_id
)
236 struct csi_priv
*priv
= dev_id
;
238 spin_lock(&priv
->irqlock
);
241 * this is not an unrecoverable error, just mark
242 * the next captured frame with vb2 error flag.
244 priv
->nfb4eof
= true;
246 v4l2_err(&priv
->sd
, "NFB4EOF\n");
248 spin_unlock(&priv
->irqlock
);
254 * EOF timeout timer function. This is an unrecoverable condition
255 * without a stream restart.
257 static void csi_idmac_eof_timeout(unsigned long data
)
259 struct csi_priv
*priv
= (struct csi_priv
*)data
;
260 struct imx_media_video_dev
*vdev
= priv
->vdev
;
262 v4l2_err(&priv
->sd
, "EOF timeout\n");
264 /* signal a fatal error to capture device */
265 imx_media_capture_device_error(vdev
);
268 static void csi_idmac_setup_vb2_buf(struct csi_priv
*priv
, dma_addr_t
*phys
)
270 struct imx_media_video_dev
*vdev
= priv
->vdev
;
271 struct imx_media_buffer
*buf
;
274 for (i
= 0; i
< 2; i
++) {
275 buf
= imx_media_capture_device_next_buf(vdev
);
277 priv
->active_vb2_buf
[i
] = buf
;
278 phys
[i
] = vb2_dma_contig_plane_dma_addr(
279 &buf
->vbuf
.vb2_buf
, 0);
281 priv
->active_vb2_buf
[i
] = NULL
;
282 phys
[i
] = priv
->underrun_buf
.phys
;
287 static void csi_idmac_unsetup_vb2_buf(struct csi_priv
*priv
,
288 enum vb2_buffer_state return_status
)
290 struct imx_media_buffer
*buf
;
293 /* return any remaining active frames with return_status */
294 for (i
= 0; i
< 2; i
++) {
295 buf
= priv
->active_vb2_buf
[i
];
297 struct vb2_buffer
*vb
= &buf
->vbuf
.vb2_buf
;
299 vb
->timestamp
= ktime_get_ns();
300 vb2_buffer_done(vb
, return_status
);
305 /* init the SMFC IDMAC channel */
306 static int csi_idmac_setup_channel(struct csi_priv
*priv
)
308 struct imx_media_video_dev
*vdev
= priv
->vdev
;
309 struct v4l2_fwnode_endpoint
*sensor_ep
;
310 struct v4l2_mbus_framefmt
*infmt
;
311 struct ipu_image image
;
312 u32 passthrough_bits
;
318 infmt
= &priv
->format_mbus
[CSI_SINK_PAD
];
319 sensor_ep
= &priv
->sensor
->sensor_ep
;
321 ipu_cpmem_zero(priv
->idmac_ch
);
323 memset(&image
, 0, sizeof(image
));
324 image
.pix
= vdev
->fmt
.fmt
.pix
;
325 image
.rect
.width
= image
.pix
.width
;
326 image
.rect
.height
= image
.pix
.height
;
328 csi_idmac_setup_vb2_buf(priv
, phys
);
330 image
.phys0
= phys
[0];
331 image
.phys1
= phys
[1];
334 * Check for conditions that require the IPU to handle the
335 * data internally as generic data, aka passthrough mode:
336 * - raw bayer formats
337 * - the sensor bus is 16-bit parallel
339 switch (image
.pix
.pixelformat
) {
340 case V4L2_PIX_FMT_SBGGR8
:
341 case V4L2_PIX_FMT_SGBRG8
:
342 case V4L2_PIX_FMT_SGRBG8
:
343 case V4L2_PIX_FMT_SRGGB8
:
346 passthrough_bits
= 8;
348 case V4L2_PIX_FMT_SBGGR16
:
349 case V4L2_PIX_FMT_SGBRG16
:
350 case V4L2_PIX_FMT_SGRBG16
:
351 case V4L2_PIX_FMT_SRGGB16
:
354 passthrough_bits
= 16;
356 case V4L2_PIX_FMT_YUV420
:
357 case V4L2_PIX_FMT_NV12
:
358 burst_size
= (image
.pix
.width
& 0x3f) ?
359 ((image
.pix
.width
& 0x1f) ?
360 ((image
.pix
.width
& 0xf) ? 8 : 16) : 32) : 64;
361 passthrough
= (sensor_ep
->bus_type
!= V4L2_MBUS_CSI2
&&
362 sensor_ep
->bus
.parallel
.bus_width
>= 16);
363 passthrough_bits
= 16;
364 /* Skip writing U and V components to odd rows */
365 ipu_cpmem_skip_odd_chroma_rows(priv
->idmac_ch
);
367 case V4L2_PIX_FMT_YUYV
:
368 case V4L2_PIX_FMT_UYVY
:
369 burst_size
= (image
.pix
.width
& 0x1f) ?
370 ((image
.pix
.width
& 0xf) ? 8 : 16) : 32;
371 passthrough
= (sensor_ep
->bus_type
!= V4L2_MBUS_CSI2
&&
372 sensor_ep
->bus
.parallel
.bus_width
>= 16);
373 passthrough_bits
= 16;
376 burst_size
= (image
.pix
.width
& 0xf) ? 8 : 16;
377 passthrough
= (sensor_ep
->bus_type
!= V4L2_MBUS_CSI2
&&
378 sensor_ep
->bus
.parallel
.bus_width
>= 16);
379 passthrough_bits
= 16;
384 ipu_cpmem_set_resolution(priv
->idmac_ch
, image
.rect
.width
,
386 ipu_cpmem_set_stride(priv
->idmac_ch
, image
.pix
.bytesperline
);
387 ipu_cpmem_set_buffer(priv
->idmac_ch
, 0, image
.phys0
);
388 ipu_cpmem_set_buffer(priv
->idmac_ch
, 1, image
.phys1
);
389 ipu_cpmem_set_format_passthrough(priv
->idmac_ch
,
392 ret
= ipu_cpmem_set_image(priv
->idmac_ch
, &image
);
397 ipu_cpmem_set_burstsize(priv
->idmac_ch
, burst_size
);
400 * Set the channel for the direct CSI-->memory via SMFC
401 * use-case to very high priority, by enabling the watermark
402 * signal in the SMFC, enabling WM in the channel, and setting
403 * the channel priority to high.
405 * Refer to the i.mx6 rev. D TRM Table 36-8: Calculated priority
408 * The WM's are set very low by intention here to ensure that
409 * the SMFC FIFOs do not overflow.
411 ipu_smfc_set_watermark(priv
->smfc
, 0x02, 0x01);
412 ipu_cpmem_set_high_priority(priv
->idmac_ch
);
413 ipu_idmac_enable_watermark(priv
->idmac_ch
, true);
414 ipu_cpmem_set_axi_id(priv
->idmac_ch
, 0);
416 burst_size
= passthrough
?
417 (burst_size
>> 3) - 1 : (burst_size
>> 2) - 1;
419 ipu_smfc_set_burstsize(priv
->smfc
, burst_size
);
421 if (image
.pix
.field
== V4L2_FIELD_NONE
&&
422 V4L2_FIELD_HAS_BOTH(infmt
->field
))
423 ipu_cpmem_interlaced_scan(priv
->idmac_ch
,
424 image
.pix
.bytesperline
);
426 ipu_idmac_set_double_buffer(priv
->idmac_ch
, true);
431 csi_idmac_unsetup_vb2_buf(priv
, VB2_BUF_STATE_QUEUED
);
435 static void csi_idmac_unsetup(struct csi_priv
*priv
,
436 enum vb2_buffer_state state
)
438 ipu_idmac_disable_channel(priv
->idmac_ch
);
439 ipu_smfc_disable(priv
->smfc
);
441 csi_idmac_unsetup_vb2_buf(priv
, state
);
444 static int csi_idmac_setup(struct csi_priv
*priv
)
448 ret
= csi_idmac_setup_channel(priv
);
452 ipu_cpmem_dump(priv
->idmac_ch
);
455 ipu_smfc_enable(priv
->smfc
);
457 /* set buffers ready */
458 ipu_idmac_select_buffer(priv
->idmac_ch
, 0);
459 ipu_idmac_select_buffer(priv
->idmac_ch
, 1);
461 /* enable the channels */
462 ipu_idmac_enable_channel(priv
->idmac_ch
);
467 static int csi_idmac_start(struct csi_priv
*priv
)
469 struct imx_media_video_dev
*vdev
= priv
->vdev
;
470 struct v4l2_pix_format
*outfmt
;
473 ret
= csi_idmac_get_ipu_resources(priv
);
477 ipu_smfc_map_channel(priv
->smfc
, priv
->csi_id
, priv
->vc_num
);
479 outfmt
= &vdev
->fmt
.fmt
.pix
;
481 ret
= imx_media_alloc_dma_buf(priv
->md
, &priv
->underrun_buf
,
486 priv
->ipu_buf_num
= 0;
488 /* init EOF completion waitq */
489 init_completion(&priv
->last_eof_comp
);
490 priv
->last_eof
= false;
491 priv
->nfb4eof
= false;
493 ret
= csi_idmac_setup(priv
);
495 v4l2_err(&priv
->sd
, "csi_idmac_setup failed: %d\n", ret
);
496 goto out_free_dma_buf
;
499 priv
->nfb4eof_irq
= ipu_idmac_channel_irq(priv
->ipu
,
502 ret
= devm_request_irq(priv
->dev
, priv
->nfb4eof_irq
,
503 csi_idmac_nfb4eof_interrupt
, 0,
504 "imx-smfc-nfb4eof", priv
);
507 "Error registering NFB4EOF irq: %d\n", ret
);
511 priv
->eof_irq
= ipu_idmac_channel_irq(priv
->ipu
, priv
->idmac_ch
,
514 ret
= devm_request_irq(priv
->dev
, priv
->eof_irq
,
515 csi_idmac_eof_interrupt
, 0,
516 "imx-smfc-eof", priv
);
519 "Error registering eof irq: %d\n", ret
);
520 goto out_free_nfb4eof_irq
;
523 /* start the EOF timeout timer */
524 mod_timer(&priv
->eof_timeout_timer
,
525 jiffies
+ msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT
));
529 out_free_nfb4eof_irq
:
530 devm_free_irq(priv
->dev
, priv
->nfb4eof_irq
, priv
);
532 csi_idmac_unsetup(priv
, VB2_BUF_STATE_QUEUED
);
534 imx_media_free_dma_buf(priv
->md
, &priv
->underrun_buf
);
536 csi_idmac_put_ipu_resources(priv
);
540 static void csi_idmac_stop(struct csi_priv
*priv
)
545 /* mark next EOF interrupt as the last before stream off */
546 spin_lock_irqsave(&priv
->irqlock
, flags
);
547 priv
->last_eof
= true;
548 spin_unlock_irqrestore(&priv
->irqlock
, flags
);
551 * and then wait for interrupt handler to mark completion.
553 ret
= wait_for_completion_timeout(
554 &priv
->last_eof_comp
, msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT
));
556 v4l2_warn(&priv
->sd
, "wait last EOF timeout\n");
558 devm_free_irq(priv
->dev
, priv
->eof_irq
, priv
);
559 devm_free_irq(priv
->dev
, priv
->nfb4eof_irq
, priv
);
561 csi_idmac_unsetup(priv
, VB2_BUF_STATE_ERROR
);
563 imx_media_free_dma_buf(priv
->md
, &priv
->underrun_buf
);
565 /* cancel the EOF timeout timer */
566 del_timer_sync(&priv
->eof_timeout_timer
);
568 csi_idmac_put_ipu_resources(priv
);
571 /* Update the CSI whole sensor and active windows */
572 static int csi_setup(struct csi_priv
*priv
)
574 struct v4l2_mbus_framefmt
*infmt
, *outfmt
;
575 struct v4l2_mbus_config sensor_mbus_cfg
;
576 struct v4l2_fwnode_endpoint
*sensor_ep
;
577 struct v4l2_mbus_framefmt if_fmt
;
579 infmt
= &priv
->format_mbus
[CSI_SINK_PAD
];
580 outfmt
= &priv
->format_mbus
[priv
->active_output_pad
];
581 sensor_ep
= &priv
->sensor
->sensor_ep
;
583 /* compose mbus_config from sensor endpoint */
584 sensor_mbus_cfg
.type
= sensor_ep
->bus_type
;
585 sensor_mbus_cfg
.flags
= (sensor_ep
->bus_type
== V4L2_MBUS_CSI2
) ?
586 sensor_ep
->bus
.mipi_csi2
.flags
:
587 sensor_ep
->bus
.parallel
.flags
;
590 * we need to pass input sensor frame to CSI interface, but
591 * with translated field type from output format
594 if_fmt
.field
= outfmt
->field
;
596 ipu_csi_set_window(priv
->csi
, &priv
->crop
);
598 ipu_csi_set_downsize(priv
->csi
,
599 priv
->crop
.width
== 2 * priv
->compose
.width
,
600 priv
->crop
.height
== 2 * priv
->compose
.height
);
602 ipu_csi_init_interface(priv
->csi
, &sensor_mbus_cfg
, &if_fmt
);
604 ipu_csi_set_dest(priv
->csi
, priv
->dest
);
606 if (priv
->dest
== IPU_CSI_DEST_IDMAC
)
607 ipu_csi_set_skip_smfc(priv
->csi
, priv
->skip
->skip_smfc
,
608 priv
->skip
->max_ratio
- 1, 0);
610 ipu_csi_dump(priv
->csi
);
615 static int csi_start(struct csi_priv
*priv
)
617 struct v4l2_fract
*output_fi
, *input_fi
;
622 v4l2_err(&priv
->sd
, "no sensor attached\n");
626 output_fi
= &priv
->frame_interval
[priv
->active_output_pad
];
627 input_fi
= &priv
->frame_interval
[CSI_SINK_PAD
];
629 ret
= v4l2_subdev_call(priv
->sensor
->sd
, sensor
,
630 g_skip_frames
, &bad_frames
);
631 if (!ret
&& bad_frames
) {
635 * This sensor has bad frames when it is turned on,
636 * add a delay to avoid them before enabling the CSI
637 * hardware. Especially for sensors with a bt.656 interface,
638 * any shifts in the SAV/EAV sync codes will cause the CSI
639 * to lose vert/horiz sync.
641 delay_usec
= DIV_ROUND_UP_ULL(
642 (u64
)USEC_PER_SEC
* input_fi
->numerator
* bad_frames
,
643 input_fi
->denominator
);
644 usleep_range(delay_usec
, delay_usec
+ 1000);
647 if (priv
->dest
== IPU_CSI_DEST_IDMAC
) {
648 ret
= csi_idmac_start(priv
);
653 ret
= csi_setup(priv
);
657 /* start the frame interval monitor */
658 if (priv
->fim
&& priv
->dest
== IPU_CSI_DEST_IDMAC
) {
659 ret
= imx_media_fim_set_stream(priv
->fim
, output_fi
, true);
664 ret
= ipu_csi_enable(priv
->csi
);
666 v4l2_err(&priv
->sd
, "CSI enable error: %d\n", ret
);
673 if (priv
->fim
&& priv
->dest
== IPU_CSI_DEST_IDMAC
)
674 imx_media_fim_set_stream(priv
->fim
, NULL
, false);
676 if (priv
->dest
== IPU_CSI_DEST_IDMAC
)
677 csi_idmac_stop(priv
);
681 static void csi_stop(struct csi_priv
*priv
)
683 if (priv
->dest
== IPU_CSI_DEST_IDMAC
) {
684 csi_idmac_stop(priv
);
686 /* stop the frame interval monitor */
688 imx_media_fim_set_stream(priv
->fim
, NULL
, false);
691 ipu_csi_disable(priv
->csi
);
694 static const struct csi_skip_desc csi_skip
[12] = {
695 { 1, 1, 0x00 }, /* Keep all frames */
696 { 5, 6, 0x10 }, /* Skip every sixth frame */
697 { 4, 5, 0x08 }, /* Skip every fifth frame */
698 { 3, 4, 0x04 }, /* Skip every fourth frame */
699 { 2, 3, 0x02 }, /* Skip every third frame */
700 { 3, 5, 0x0a }, /* Skip frames 1 and 3 of every 5 */
701 { 1, 2, 0x01 }, /* Skip every second frame */
702 { 2, 5, 0x0b }, /* Keep frames 1 and 4 of every 5 */
703 { 1, 3, 0x03 }, /* Keep one in three frames */
704 { 1, 4, 0x07 }, /* Keep one in four frames */
705 { 1, 5, 0x0f }, /* Keep one in five frames */
706 { 1, 6, 0x1f }, /* Keep one in six frames */
709 static void csi_apply_skip_interval(const struct csi_skip_desc
*skip
,
710 struct v4l2_fract
*interval
)
714 interval
->numerator
*= skip
->max_ratio
;
715 interval
->denominator
*= skip
->keep
;
717 /* Reduce fraction to lowest terms */
718 div
= gcd(interval
->numerator
, interval
->denominator
);
720 interval
->numerator
/= div
;
721 interval
->denominator
/= div
;
726 * Find the skip pattern to produce the output frame interval closest to the
727 * requested one, for the given input frame interval. Updates the output frame
728 * interval to the exact value.
730 static const struct csi_skip_desc
*csi_find_best_skip(struct v4l2_fract
*in
,
731 struct v4l2_fract
*out
)
733 const struct csi_skip_desc
*skip
= &csi_skip
[0], *best_skip
= skip
;
734 u32 min_err
= UINT_MAX
;
738 /* Default to 1:1 ratio */
739 if (out
->numerator
== 0 || out
->denominator
== 0 ||
740 in
->numerator
== 0 || in
->denominator
== 0) {
745 want_us
= div_u64((u64
)USEC_PER_SEC
* out
->numerator
, out
->denominator
);
747 /* Find the reduction closest to the requested time per frame */
748 for (i
= 0; i
< ARRAY_SIZE(csi_skip
); i
++, skip
++) {
751 tmp
= div_u64((u64
)USEC_PER_SEC
* in
->numerator
*
752 skip
->max_ratio
, in
->denominator
* skip
->keep
);
754 err
= abs((s64
)tmp
- want_us
);
762 csi_apply_skip_interval(best_skip
, out
);
768 * V4L2 subdev operations.
771 static int csi_g_frame_interval(struct v4l2_subdev
*sd
,
772 struct v4l2_subdev_frame_interval
*fi
)
774 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
776 if (fi
->pad
>= CSI_NUM_PADS
)
779 mutex_lock(&priv
->lock
);
781 fi
->interval
= priv
->frame_interval
[fi
->pad
];
783 mutex_unlock(&priv
->lock
);
788 static int csi_s_frame_interval(struct v4l2_subdev
*sd
,
789 struct v4l2_subdev_frame_interval
*fi
)
791 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
792 struct v4l2_fract
*input_fi
;
795 mutex_lock(&priv
->lock
);
797 input_fi
= &priv
->frame_interval
[CSI_SINK_PAD
];
801 /* No limits on input frame interval */
802 /* Reset output intervals and frame skipping ratio to 1:1 */
803 priv
->frame_interval
[CSI_SRC_PAD_IDMAC
] = fi
->interval
;
804 priv
->frame_interval
[CSI_SRC_PAD_DIRECT
] = fi
->interval
;
805 priv
->skip
= &csi_skip
[0];
807 case CSI_SRC_PAD_IDMAC
:
809 * frame interval at IDMAC output pad depends on input
810 * interval, modified by frame skipping.
812 priv
->skip
= csi_find_best_skip(input_fi
, &fi
->interval
);
814 case CSI_SRC_PAD_DIRECT
:
816 * frame interval at DIRECT output pad is same as input
819 fi
->interval
= *input_fi
;
826 priv
->frame_interval
[fi
->pad
] = fi
->interval
;
828 mutex_unlock(&priv
->lock
);
832 static int csi_s_stream(struct v4l2_subdev
*sd
, int enable
)
834 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
837 mutex_lock(&priv
->lock
);
839 if (!priv
->src_sd
|| !priv
->sink
) {
845 * enable/disable streaming only if stream_count is
846 * going from 0 to 1 / 1 to 0.
848 if (priv
->stream_count
!= !enable
)
852 /* upstream must be started first, before starting CSI */
853 ret
= v4l2_subdev_call(priv
->src_sd
, video
, s_stream
, 1);
854 ret
= (ret
&& ret
!= -ENOIOCTLCMD
) ? ret
: 0;
858 dev_dbg(priv
->dev
, "stream ON\n");
859 ret
= csi_start(priv
);
861 v4l2_subdev_call(priv
->src_sd
, video
, s_stream
, 0);
865 dev_dbg(priv
->dev
, "stream OFF\n");
866 /* CSI must be stopped first, then stop upstream */
868 v4l2_subdev_call(priv
->src_sd
, video
, s_stream
, 0);
872 priv
->stream_count
+= enable
? 1 : -1;
873 if (priv
->stream_count
< 0)
874 priv
->stream_count
= 0;
876 mutex_unlock(&priv
->lock
);
880 static int csi_link_setup(struct media_entity
*entity
,
881 const struct media_pad
*local
,
882 const struct media_pad
*remote
, u32 flags
)
884 struct v4l2_subdev
*sd
= media_entity_to_v4l2_subdev(entity
);
885 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
886 struct v4l2_subdev
*remote_sd
;
889 dev_dbg(priv
->dev
, "link setup %s -> %s\n", remote
->entity
->name
,
890 local
->entity
->name
);
892 mutex_lock(&priv
->lock
);
894 if (local
->flags
& MEDIA_PAD_FL_SINK
) {
895 if (!is_media_entity_v4l2_subdev(remote
->entity
)) {
900 remote_sd
= media_entity_to_v4l2_subdev(remote
->entity
);
902 if (flags
& MEDIA_LNK_FL_ENABLED
) {
907 priv
->src_sd
= remote_sd
;
915 /* this is a source pad */
917 if (flags
& MEDIA_LNK_FL_ENABLED
) {
923 v4l2_ctrl_handler_free(&priv
->ctrl_hdlr
);
924 v4l2_ctrl_handler_init(&priv
->ctrl_hdlr
, 0);
929 /* record which output pad is now active */
930 priv
->active_output_pad
= local
->index
;
932 /* set CSI destination */
933 if (local
->index
== CSI_SRC_PAD_IDMAC
) {
934 if (!is_media_entity_v4l2_video_device(remote
->entity
)) {
940 ret
= imx_media_fim_add_controls(priv
->fim
);
945 priv
->dest
= IPU_CSI_DEST_IDMAC
;
947 if (!is_media_entity_v4l2_subdev(remote
->entity
)) {
952 remote_sd
= media_entity_to_v4l2_subdev(remote
->entity
);
953 switch (remote_sd
->grp_id
) {
954 case IMX_MEDIA_GRP_ID_VDIC
:
955 priv
->dest
= IPU_CSI_DEST_VDIC
;
957 case IMX_MEDIA_GRP_ID_IC_PRP
:
958 priv
->dest
= IPU_CSI_DEST_IC
;
966 priv
->sink
= remote
->entity
;
968 mutex_unlock(&priv
->lock
);
972 static int csi_link_validate(struct v4l2_subdev
*sd
,
973 struct media_link
*link
,
974 struct v4l2_subdev_format
*source_fmt
,
975 struct v4l2_subdev_format
*sink_fmt
)
977 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
978 struct v4l2_fwnode_endpoint
*sensor_ep
;
979 const struct imx_media_pixfmt
*incc
;
980 struct imx_media_subdev
*sensor
;
984 ret
= v4l2_subdev_link_validate_default(sd
, link
,
985 source_fmt
, sink_fmt
);
989 sensor
= __imx_media_find_sensor(priv
->md
, &priv
->sd
.entity
);
990 if (IS_ERR(sensor
)) {
991 v4l2_err(&priv
->sd
, "no sensor attached\n");
992 return PTR_ERR(priv
->sensor
);
995 mutex_lock(&priv
->lock
);
997 priv
->sensor
= sensor
;
998 sensor_ep
= &priv
->sensor
->sensor_ep
;
999 is_csi2
= (sensor_ep
->bus_type
== V4L2_MBUS_CSI2
);
1000 incc
= priv
->cc
[CSI_SINK_PAD
];
1002 if (priv
->dest
!= IPU_CSI_DEST_IDMAC
&&
1003 (incc
->bayer
|| (!is_csi2
&&
1004 sensor_ep
->bus
.parallel
.bus_width
>= 16))) {
1006 "bayer/16-bit parallel buses must go to IDMAC pad\n");
1014 * NOTE! It seems the virtual channels from the mipi csi-2
1015 * receiver are used only for routing by the video mux's,
1016 * or for hard-wired routing to the CSI's. Once the stream
1017 * enters the CSI's however, they are treated internally
1018 * in the IPU as virtual channel 0.
1021 mutex_unlock(&priv
->lock
);
1022 vc_num
= imx_media_find_mipi_csi2_channel(priv
->md
,
1026 mutex_lock(&priv
->lock
);
1028 ipu_csi_set_mipi_datatype(priv
->csi
, vc_num
,
1029 &priv
->format_mbus
[CSI_SINK_PAD
]);
1032 /* select either parallel or MIPI-CSI2 as input to CSI */
1033 ipu_set_csi_src_mux(priv
->ipu
, priv
->csi_id
, is_csi2
);
1035 mutex_unlock(&priv
->lock
);
1039 static struct v4l2_mbus_framefmt
*
1040 __csi_get_fmt(struct csi_priv
*priv
, struct v4l2_subdev_pad_config
*cfg
,
1041 unsigned int pad
, enum v4l2_subdev_format_whence which
)
1043 if (which
== V4L2_SUBDEV_FORMAT_TRY
)
1044 return v4l2_subdev_get_try_format(&priv
->sd
, cfg
, pad
);
1046 return &priv
->format_mbus
[pad
];
1049 static struct v4l2_rect
*
1050 __csi_get_crop(struct csi_priv
*priv
, struct v4l2_subdev_pad_config
*cfg
,
1051 enum v4l2_subdev_format_whence which
)
1053 if (which
== V4L2_SUBDEV_FORMAT_TRY
)
1054 return v4l2_subdev_get_try_crop(&priv
->sd
, cfg
, CSI_SINK_PAD
);
1059 static struct v4l2_rect
*
1060 __csi_get_compose(struct csi_priv
*priv
, struct v4l2_subdev_pad_config
*cfg
,
1061 enum v4l2_subdev_format_whence which
)
1063 if (which
== V4L2_SUBDEV_FORMAT_TRY
)
1064 return v4l2_subdev_get_try_compose(&priv
->sd
, cfg
,
1067 return &priv
->compose
;
1070 static void csi_try_crop(struct csi_priv
*priv
,
1071 struct v4l2_rect
*crop
,
1072 struct v4l2_subdev_pad_config
*cfg
,
1073 struct v4l2_mbus_framefmt
*infmt
,
1074 struct imx_media_subdev
*sensor
)
1076 struct v4l2_fwnode_endpoint
*sensor_ep
;
1078 sensor_ep
= &sensor
->sensor_ep
;
1080 crop
->width
= min_t(__u32
, infmt
->width
, crop
->width
);
1081 if (crop
->left
+ crop
->width
> infmt
->width
)
1082 crop
->left
= infmt
->width
- crop
->width
;
1083 /* adjust crop left/width to h/w alignment restrictions */
1085 crop
->width
&= ~0x7;
1088 * FIXME: not sure why yet, but on interlaced bt.656,
1089 * changing the vertical cropping causes loss of vertical
1090 * sync, so fix it to NTSC/PAL active lines. NTSC contains
1091 * 2 extra lines of active video that need to be cropped.
1093 if (sensor_ep
->bus_type
== V4L2_MBUS_BT656
&&
1094 (V4L2_FIELD_HAS_BOTH(infmt
->field
) ||
1095 infmt
->field
== V4L2_FIELD_ALTERNATE
)) {
1096 crop
->height
= infmt
->height
;
1097 crop
->top
= (infmt
->height
== 480) ? 2 : 0;
1099 crop
->height
= min_t(__u32
, infmt
->height
, crop
->height
);
1100 if (crop
->top
+ crop
->height
> infmt
->height
)
1101 crop
->top
= infmt
->height
- crop
->height
;
1105 static int csi_enum_mbus_code(struct v4l2_subdev
*sd
,
1106 struct v4l2_subdev_pad_config
*cfg
,
1107 struct v4l2_subdev_mbus_code_enum
*code
)
1109 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1110 const struct imx_media_pixfmt
*incc
;
1111 struct v4l2_mbus_framefmt
*infmt
;
1114 mutex_lock(&priv
->lock
);
1116 infmt
= __csi_get_fmt(priv
, cfg
, CSI_SINK_PAD
, code
->which
);
1117 incc
= imx_media_find_mbus_format(infmt
->code
, CS_SEL_ANY
, true);
1119 switch (code
->pad
) {
1121 ret
= imx_media_enum_mbus_format(&code
->code
, code
->index
,
1124 case CSI_SRC_PAD_DIRECT
:
1125 case CSI_SRC_PAD_IDMAC
:
1127 if (code
->index
!= 0) {
1131 code
->code
= infmt
->code
;
1133 u32 cs_sel
= (incc
->cs
== IPUV3_COLORSPACE_YUV
) ?
1134 CS_SEL_YUV
: CS_SEL_RGB
;
1135 ret
= imx_media_enum_ipu_format(&code
->code
,
1145 mutex_unlock(&priv
->lock
);
1149 static int csi_enum_frame_size(struct v4l2_subdev
*sd
,
1150 struct v4l2_subdev_pad_config
*cfg
,
1151 struct v4l2_subdev_frame_size_enum
*fse
)
1153 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1154 struct v4l2_rect
*crop
;
1157 if (fse
->pad
>= CSI_NUM_PADS
||
1158 fse
->index
> (fse
->pad
== CSI_SINK_PAD
? 0 : 3))
1161 mutex_lock(&priv
->lock
);
1163 if (fse
->pad
== CSI_SINK_PAD
) {
1164 fse
->min_width
= MIN_W
;
1165 fse
->max_width
= MAX_W
;
1166 fse
->min_height
= MIN_H
;
1167 fse
->max_height
= MAX_H
;
1169 crop
= __csi_get_crop(priv
, cfg
, fse
->which
);
1171 fse
->min_width
= fse
->max_width
= fse
->index
& 1 ?
1172 crop
->width
/ 2 : crop
->width
;
1173 fse
->min_height
= fse
->max_height
= fse
->index
& 2 ?
1174 crop
->height
/ 2 : crop
->height
;
1177 mutex_unlock(&priv
->lock
);
1181 static int csi_enum_frame_interval(struct v4l2_subdev
*sd
,
1182 struct v4l2_subdev_pad_config
*cfg
,
1183 struct v4l2_subdev_frame_interval_enum
*fie
)
1185 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1186 struct v4l2_fract
*input_fi
;
1187 struct v4l2_rect
*crop
;
1190 if (fie
->pad
>= CSI_NUM_PADS
||
1191 fie
->index
>= (fie
->pad
!= CSI_SRC_PAD_IDMAC
?
1192 1 : ARRAY_SIZE(csi_skip
)))
1195 mutex_lock(&priv
->lock
);
1197 input_fi
= &priv
->frame_interval
[CSI_SINK_PAD
];
1198 crop
= __csi_get_crop(priv
, cfg
, fie
->which
);
1200 if ((fie
->width
!= crop
->width
&& fie
->width
!= crop
->width
/ 2) ||
1201 (fie
->height
!= crop
->height
&& fie
->height
!= crop
->height
/ 2)) {
1206 fie
->interval
= *input_fi
;
1208 if (fie
->pad
== CSI_SRC_PAD_IDMAC
)
1209 csi_apply_skip_interval(&csi_skip
[fie
->index
],
1213 mutex_unlock(&priv
->lock
);
1217 static int csi_get_fmt(struct v4l2_subdev
*sd
,
1218 struct v4l2_subdev_pad_config
*cfg
,
1219 struct v4l2_subdev_format
*sdformat
)
1221 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1222 struct v4l2_mbus_framefmt
*fmt
;
1225 if (sdformat
->pad
>= CSI_NUM_PADS
)
1228 mutex_lock(&priv
->lock
);
1230 fmt
= __csi_get_fmt(priv
, cfg
, sdformat
->pad
, sdformat
->which
);
1236 sdformat
->format
= *fmt
;
1238 mutex_unlock(&priv
->lock
);
1242 static void csi_try_fmt(struct csi_priv
*priv
,
1243 struct imx_media_subdev
*sensor
,
1244 struct v4l2_subdev_pad_config
*cfg
,
1245 struct v4l2_subdev_format
*sdformat
,
1246 struct v4l2_rect
*crop
,
1247 struct v4l2_rect
*compose
,
1248 const struct imx_media_pixfmt
**cc
)
1250 const struct imx_media_pixfmt
*incc
;
1251 struct v4l2_mbus_framefmt
*infmt
;
1254 infmt
= __csi_get_fmt(priv
, cfg
, CSI_SINK_PAD
, sdformat
->which
);
1256 switch (sdformat
->pad
) {
1257 case CSI_SRC_PAD_DIRECT
:
1258 case CSI_SRC_PAD_IDMAC
:
1259 incc
= imx_media_find_mbus_format(infmt
->code
,
1262 sdformat
->format
.width
= compose
->width
;
1263 sdformat
->format
.height
= compose
->height
;
1266 sdformat
->format
.code
= infmt
->code
;
1269 u32 cs_sel
= (incc
->cs
== IPUV3_COLORSPACE_YUV
) ?
1270 CS_SEL_YUV
: CS_SEL_RGB
;
1272 *cc
= imx_media_find_ipu_format(sdformat
->format
.code
,
1275 imx_media_enum_ipu_format(&code
, 0, cs_sel
);
1276 *cc
= imx_media_find_ipu_format(code
, cs_sel
);
1277 sdformat
->format
.code
= (*cc
)->codes
[0];
1281 if (sdformat
->pad
== CSI_SRC_PAD_DIRECT
||
1282 sdformat
->format
.field
!= V4L2_FIELD_NONE
)
1283 sdformat
->format
.field
= infmt
->field
;
1286 * translate V4L2_FIELD_ALTERNATE to SEQ_TB or SEQ_BT
1287 * depending on input height (assume NTSC top-bottom
1288 * order if 480 lines, otherwise PAL bottom-top order).
1290 if (sdformat
->format
.field
== V4L2_FIELD_ALTERNATE
) {
1291 sdformat
->format
.field
= (infmt
->height
== 480) ?
1292 V4L2_FIELD_SEQ_TB
: V4L2_FIELD_SEQ_BT
;
1295 /* propagate colorimetry from sink */
1296 sdformat
->format
.colorspace
= infmt
->colorspace
;
1297 sdformat
->format
.xfer_func
= infmt
->xfer_func
;
1298 sdformat
->format
.quantization
= infmt
->quantization
;
1299 sdformat
->format
.ycbcr_enc
= infmt
->ycbcr_enc
;
1302 v4l_bound_align_image(&sdformat
->format
.width
, MIN_W
, MAX_W
,
1303 W_ALIGN
, &sdformat
->format
.height
,
1304 MIN_H
, MAX_H
, H_ALIGN
, S_ALIGN
);
1306 /* Reset crop and compose rectangles */
1309 crop
->width
= sdformat
->format
.width
;
1310 crop
->height
= sdformat
->format
.height
;
1311 csi_try_crop(priv
, crop
, cfg
, &sdformat
->format
, sensor
);
1314 compose
->width
= crop
->width
;
1315 compose
->height
= crop
->height
;
1317 *cc
= imx_media_find_mbus_format(sdformat
->format
.code
,
1320 imx_media_enum_mbus_format(&code
, 0,
1322 *cc
= imx_media_find_mbus_format(code
,
1324 sdformat
->format
.code
= (*cc
)->codes
[0];
1327 imx_media_fill_default_mbus_fields(
1328 &sdformat
->format
, infmt
,
1329 priv
->active_output_pad
== CSI_SRC_PAD_DIRECT
);
1334 static int csi_set_fmt(struct v4l2_subdev
*sd
,
1335 struct v4l2_subdev_pad_config
*cfg
,
1336 struct v4l2_subdev_format
*sdformat
)
1338 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1339 struct imx_media_video_dev
*vdev
= priv
->vdev
;
1340 const struct imx_media_pixfmt
*cc
;
1341 struct imx_media_subdev
*sensor
;
1342 struct v4l2_pix_format vdev_fmt
;
1343 struct v4l2_mbus_framefmt
*fmt
;
1344 struct v4l2_rect
*crop
, *compose
;
1347 if (sdformat
->pad
>= CSI_NUM_PADS
)
1350 sensor
= imx_media_find_sensor(priv
->md
, &priv
->sd
.entity
);
1351 if (IS_ERR(sensor
)) {
1352 v4l2_err(&priv
->sd
, "no sensor attached\n");
1353 return PTR_ERR(sensor
);
1356 mutex_lock(&priv
->lock
);
1358 if (priv
->stream_count
> 0) {
1363 crop
= __csi_get_crop(priv
, cfg
, sdformat
->which
);
1364 compose
= __csi_get_compose(priv
, cfg
, sdformat
->which
);
1366 csi_try_fmt(priv
, sensor
, cfg
, sdformat
, crop
, compose
, &cc
);
1368 fmt
= __csi_get_fmt(priv
, cfg
, sdformat
->pad
, sdformat
->which
);
1369 *fmt
= sdformat
->format
;
1371 if (sdformat
->pad
== CSI_SINK_PAD
) {
1374 /* propagate format to source pads */
1375 for (pad
= CSI_SINK_PAD
+ 1; pad
< CSI_NUM_PADS
; pad
++) {
1376 const struct imx_media_pixfmt
*outcc
;
1377 struct v4l2_mbus_framefmt
*outfmt
;
1378 struct v4l2_subdev_format format
;
1381 format
.which
= sdformat
->which
;
1382 format
.format
= sdformat
->format
;
1383 csi_try_fmt(priv
, sensor
, cfg
, &format
, NULL
, compose
,
1386 outfmt
= __csi_get_fmt(priv
, cfg
, pad
, sdformat
->which
);
1387 *outfmt
= format
.format
;
1389 if (sdformat
->which
== V4L2_SUBDEV_FORMAT_ACTIVE
)
1390 priv
->cc
[pad
] = outcc
;
1394 if (sdformat
->which
== V4L2_SUBDEV_FORMAT_TRY
)
1397 priv
->cc
[sdformat
->pad
] = cc
;
1399 /* propagate IDMAC output pad format to capture device */
1400 imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt
,
1401 &priv
->format_mbus
[CSI_SRC_PAD_IDMAC
],
1402 priv
->cc
[CSI_SRC_PAD_IDMAC
]);
1403 mutex_unlock(&priv
->lock
);
1404 imx_media_capture_device_set_format(vdev
, &vdev_fmt
);
1408 mutex_unlock(&priv
->lock
);
1412 static int csi_get_selection(struct v4l2_subdev
*sd
,
1413 struct v4l2_subdev_pad_config
*cfg
,
1414 struct v4l2_subdev_selection
*sel
)
1416 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1417 struct v4l2_mbus_framefmt
*infmt
;
1418 struct v4l2_rect
*crop
, *compose
;
1421 if (sel
->pad
!= CSI_SINK_PAD
)
1424 mutex_lock(&priv
->lock
);
1426 infmt
= __csi_get_fmt(priv
, cfg
, CSI_SINK_PAD
, sel
->which
);
1427 crop
= __csi_get_crop(priv
, cfg
, sel
->which
);
1428 compose
= __csi_get_compose(priv
, cfg
, sel
->which
);
1430 switch (sel
->target
) {
1431 case V4L2_SEL_TGT_CROP_BOUNDS
:
1434 sel
->r
.width
= infmt
->width
;
1435 sel
->r
.height
= infmt
->height
;
1437 case V4L2_SEL_TGT_CROP
:
1440 case V4L2_SEL_TGT_COMPOSE_BOUNDS
:
1443 sel
->r
.width
= crop
->width
;
1444 sel
->r
.height
= crop
->height
;
1446 case V4L2_SEL_TGT_COMPOSE
:
1453 mutex_unlock(&priv
->lock
);
1457 static int csi_set_scale(u32
*compose
, u32 crop
, u32 flags
)
1459 if ((flags
& (V4L2_SEL_FLAG_LE
| V4L2_SEL_FLAG_GE
)) ==
1460 (V4L2_SEL_FLAG_LE
| V4L2_SEL_FLAG_GE
) &&
1461 *compose
!= crop
&& *compose
!= crop
/ 2)
1464 if (*compose
<= crop
/ 2 ||
1465 (*compose
< crop
* 3 / 4 && !(flags
& V4L2_SEL_FLAG_GE
)) ||
1466 (*compose
< crop
&& (flags
& V4L2_SEL_FLAG_LE
)))
1467 *compose
= crop
/ 2;
1474 static int csi_set_selection(struct v4l2_subdev
*sd
,
1475 struct v4l2_subdev_pad_config
*cfg
,
1476 struct v4l2_subdev_selection
*sel
)
1478 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1479 struct v4l2_mbus_framefmt
*infmt
;
1480 struct v4l2_rect
*crop
, *compose
;
1481 struct imx_media_subdev
*sensor
;
1484 if (sel
->pad
!= CSI_SINK_PAD
)
1487 sensor
= imx_media_find_sensor(priv
->md
, &priv
->sd
.entity
);
1488 if (IS_ERR(sensor
)) {
1489 v4l2_err(&priv
->sd
, "no sensor attached\n");
1490 return PTR_ERR(sensor
);
1493 mutex_lock(&priv
->lock
);
1495 if (priv
->stream_count
> 0) {
1500 infmt
= __csi_get_fmt(priv
, cfg
, CSI_SINK_PAD
, sel
->which
);
1501 crop
= __csi_get_crop(priv
, cfg
, sel
->which
);
1502 compose
= __csi_get_compose(priv
, cfg
, sel
->which
);
1504 switch (sel
->target
) {
1505 case V4L2_SEL_TGT_CROP
:
1507 * Modifying the crop rectangle always changes the format on
1508 * the source pads. If the KEEP_CONFIG flag is set, just return
1509 * the current crop rectangle.
1511 if (sel
->flags
& V4L2_SEL_FLAG_KEEP_CONFIG
) {
1512 sel
->r
= priv
->crop
;
1513 if (sel
->which
== V4L2_SUBDEV_FORMAT_TRY
)
1518 csi_try_crop(priv
, &sel
->r
, cfg
, infmt
, sensor
);
1522 /* Reset scaling to 1:1 */
1523 compose
->width
= crop
->width
;
1524 compose
->height
= crop
->height
;
1526 case V4L2_SEL_TGT_COMPOSE
:
1528 * Modifying the compose rectangle always changes the format on
1529 * the source pads. If the KEEP_CONFIG flag is set, just return
1530 * the current compose rectangle.
1532 if (sel
->flags
& V4L2_SEL_FLAG_KEEP_CONFIG
) {
1533 sel
->r
= priv
->compose
;
1534 if (sel
->which
== V4L2_SUBDEV_FORMAT_TRY
)
1541 ret
= csi_set_scale(&sel
->r
.width
, crop
->width
, sel
->flags
);
1544 ret
= csi_set_scale(&sel
->r
.height
, crop
->height
, sel
->flags
);
1555 /* Reset source pads to sink compose rectangle */
1556 for (pad
= CSI_SINK_PAD
+ 1; pad
< CSI_NUM_PADS
; pad
++) {
1557 struct v4l2_mbus_framefmt
*outfmt
;
1559 outfmt
= __csi_get_fmt(priv
, cfg
, pad
, sel
->which
);
1560 outfmt
->width
= compose
->width
;
1561 outfmt
->height
= compose
->height
;
1565 mutex_unlock(&priv
->lock
);
1569 static int csi_subscribe_event(struct v4l2_subdev
*sd
, struct v4l2_fh
*fh
,
1570 struct v4l2_event_subscription
*sub
)
1572 if (sub
->type
!= V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR
)
1577 return v4l2_event_subscribe(fh
, sub
, 0, NULL
);
1580 static int csi_unsubscribe_event(struct v4l2_subdev
*sd
, struct v4l2_fh
*fh
,
1581 struct v4l2_event_subscription
*sub
)
1583 return v4l2_event_unsubscribe(fh
, sub
);
1587 * retrieve our pads parsed from the OF graph by the media device
1589 static int csi_registered(struct v4l2_subdev
*sd
)
1591 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1592 struct ipu_csi
*csi
;
1596 /* get media device */
1597 priv
->md
= dev_get_drvdata(sd
->v4l2_dev
->dev
);
1599 /* get handle to IPU CSI */
1600 csi
= ipu_csi_get(priv
->ipu
, priv
->csi_id
);
1602 v4l2_err(&priv
->sd
, "failed to get CSI%d\n", priv
->csi_id
);
1603 return PTR_ERR(csi
);
1607 for (i
= 0; i
< CSI_NUM_PADS
; i
++) {
1608 priv
->pad
[i
].flags
= (i
== CSI_SINK_PAD
) ?
1609 MEDIA_PAD_FL_SINK
: MEDIA_PAD_FL_SOURCE
;
1612 if (i
!= CSI_SINK_PAD
)
1613 imx_media_enum_ipu_format(&code
, 0, CS_SEL_YUV
);
1615 /* set a default mbus format */
1616 ret
= imx_media_init_mbus_fmt(&priv
->format_mbus
[i
],
1617 640, 480, code
, V4L2_FIELD_NONE
,
1622 /* init default frame interval */
1623 priv
->frame_interval
[i
].numerator
= 1;
1624 priv
->frame_interval
[i
].denominator
= 30;
1627 /* disable frame skipping */
1628 priv
->skip
= &csi_skip
[0];
1630 /* init default crop and compose rectangle sizes */
1631 priv
->crop
.width
= 640;
1632 priv
->crop
.height
= 480;
1633 priv
->compose
.width
= 640;
1634 priv
->compose
.height
= 480;
1636 priv
->fim
= imx_media_fim_init(&priv
->sd
);
1637 if (IS_ERR(priv
->fim
)) {
1638 ret
= PTR_ERR(priv
->fim
);
1642 ret
= media_entity_pads_init(&sd
->entity
, CSI_NUM_PADS
, priv
->pad
);
1646 ret
= imx_media_capture_device_register(priv
->vdev
);
1650 ret
= imx_media_add_video_device(priv
->md
, priv
->vdev
);
1656 imx_media_capture_device_unregister(priv
->vdev
);
1659 imx_media_fim_free(priv
->fim
);
1661 ipu_csi_put(priv
->csi
);
1665 static void csi_unregistered(struct v4l2_subdev
*sd
)
1667 struct csi_priv
*priv
= v4l2_get_subdevdata(sd
);
1669 imx_media_capture_device_unregister(priv
->vdev
);
1672 imx_media_fim_free(priv
->fim
);
1675 ipu_csi_put(priv
->csi
);
1678 static const struct media_entity_operations csi_entity_ops
= {
1679 .link_setup
= csi_link_setup
,
1680 .link_validate
= v4l2_subdev_link_validate
,
1683 static const struct v4l2_subdev_core_ops csi_core_ops
= {
1684 .subscribe_event
= csi_subscribe_event
,
1685 .unsubscribe_event
= csi_unsubscribe_event
,
1688 static const struct v4l2_subdev_video_ops csi_video_ops
= {
1689 .g_frame_interval
= csi_g_frame_interval
,
1690 .s_frame_interval
= csi_s_frame_interval
,
1691 .s_stream
= csi_s_stream
,
1694 static const struct v4l2_subdev_pad_ops csi_pad_ops
= {
1695 .enum_mbus_code
= csi_enum_mbus_code
,
1696 .enum_frame_size
= csi_enum_frame_size
,
1697 .enum_frame_interval
= csi_enum_frame_interval
,
1698 .get_fmt
= csi_get_fmt
,
1699 .set_fmt
= csi_set_fmt
,
1700 .get_selection
= csi_get_selection
,
1701 .set_selection
= csi_set_selection
,
1702 .link_validate
= csi_link_validate
,
1705 static const struct v4l2_subdev_ops csi_subdev_ops
= {
1706 .core
= &csi_core_ops
,
1707 .video
= &csi_video_ops
,
1708 .pad
= &csi_pad_ops
,
1711 static const struct v4l2_subdev_internal_ops csi_internal_ops
= {
1712 .registered
= csi_registered
,
1713 .unregistered
= csi_unregistered
,
1716 static int imx_csi_probe(struct platform_device
*pdev
)
1718 struct ipu_client_platformdata
*pdata
;
1719 struct pinctrl
*pinctrl
;
1720 struct csi_priv
*priv
;
1723 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
1727 platform_set_drvdata(pdev
, &priv
->sd
);
1728 priv
->dev
= &pdev
->dev
;
1730 ret
= dma_set_coherent_mask(priv
->dev
, DMA_BIT_MASK(32));
1734 /* get parent IPU */
1735 priv
->ipu
= dev_get_drvdata(priv
->dev
->parent
);
1737 /* get our CSI id */
1738 pdata
= priv
->dev
->platform_data
;
1739 priv
->csi_id
= pdata
->csi
;
1740 priv
->smfc_id
= (priv
->csi_id
== 0) ? 0 : 2;
1742 setup_timer(&priv
->eof_timeout_timer
, csi_idmac_eof_timeout
,
1743 (unsigned long)priv
);
1744 spin_lock_init(&priv
->irqlock
);
1746 v4l2_subdev_init(&priv
->sd
, &csi_subdev_ops
);
1747 v4l2_set_subdevdata(&priv
->sd
, priv
);
1748 priv
->sd
.internal_ops
= &csi_internal_ops
;
1749 priv
->sd
.entity
.ops
= &csi_entity_ops
;
1750 priv
->sd
.entity
.function
= MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER
;
1751 priv
->sd
.dev
= &pdev
->dev
;
1752 priv
->sd
.fwnode
= of_fwnode_handle(pdata
->of_node
);
1753 priv
->sd
.owner
= THIS_MODULE
;
1754 priv
->sd
.flags
= V4L2_SUBDEV_FL_HAS_DEVNODE
| V4L2_SUBDEV_FL_HAS_EVENTS
;
1755 priv
->sd
.grp_id
= priv
->csi_id
?
1756 IMX_MEDIA_GRP_ID_CSI1
: IMX_MEDIA_GRP_ID_CSI0
;
1757 imx_media_grp_id_to_sd_name(priv
->sd
.name
, sizeof(priv
->sd
.name
),
1758 priv
->sd
.grp_id
, ipu_get_num(priv
->ipu
));
1760 priv
->vdev
= imx_media_capture_device_init(&priv
->sd
,
1762 if (IS_ERR(priv
->vdev
))
1763 return PTR_ERR(priv
->vdev
);
1765 mutex_init(&priv
->lock
);
1767 v4l2_ctrl_handler_init(&priv
->ctrl_hdlr
, 0);
1768 priv
->sd
.ctrl_handler
= &priv
->ctrl_hdlr
;
1771 * The IPUv3 driver did not assign an of_node to this
1772 * device. As a result, pinctrl does not automatically
1773 * configure our pin groups, so we need to do that manually
1774 * here, after setting this device's of_node.
1776 priv
->dev
->of_node
= pdata
->of_node
;
1777 pinctrl
= devm_pinctrl_get_select_default(priv
->dev
);
1779 ret
= v4l2_async_register_subdev(&priv
->sd
);
1785 v4l2_ctrl_handler_free(&priv
->ctrl_hdlr
);
1786 mutex_destroy(&priv
->lock
);
1787 imx_media_capture_device_remove(priv
->vdev
);
1791 static int imx_csi_remove(struct platform_device
*pdev
)
1793 struct v4l2_subdev
*sd
= platform_get_drvdata(pdev
);
1794 struct csi_priv
*priv
= sd_to_dev(sd
);
1796 v4l2_ctrl_handler_free(&priv
->ctrl_hdlr
);
1797 mutex_destroy(&priv
->lock
);
1798 imx_media_capture_device_remove(priv
->vdev
);
1799 v4l2_async_unregister_subdev(sd
);
1800 media_entity_cleanup(&sd
->entity
);
1805 static const struct platform_device_id imx_csi_ids
[] = {
1806 { .name
= "imx-ipuv3-csi" },
1809 MODULE_DEVICE_TABLE(platform
, imx_csi_ids
);
1811 static struct platform_driver imx_csi_driver
= {
1812 .probe
= imx_csi_probe
,
1813 .remove
= imx_csi_remove
,
1814 .id_table
= imx_csi_ids
,
1816 .name
= "imx-ipuv3-csi",
1819 module_platform_driver(imx_csi_driver
);
1821 MODULE_DESCRIPTION("i.MX CSI subdev driver");
1822 MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
1823 MODULE_LICENSE("GPL");
1824 MODULE_ALIAS("platform:imx-ipuv3-csi");