1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2021-2023 Digiteq Automotive
4 * author: Martin Tuma <martin.tuma@digiteqautomotive.com>
6 * This is the v4l2 input device module. It initializes the signal deserializers
7 * and creates the v4l2 video devices. The input signal can change at any time
8 * which is handled by the "timings" callbacks and an IRQ based watcher, that
9 * emits the V4L2_EVENT_SOURCE_CHANGE event in case of a signal source change.
11 * When the device is in loopback mode (a direct, in HW, in->out frame passing
12 * mode) the card's frame queue must be running regardless of whether a v4l2
13 * stream is running and the output parameters like frame buffers padding must
14 * be in sync with the input parameters.
17 #include <linux/pci.h>
18 #include <linux/workqueue.h>
19 #include <linux/align.h>
20 #include <linux/dma/amd_xdma.h>
21 #include <linux/v4l2-dv-timings.h>
22 #include <media/v4l2-ioctl.h>
23 #include <media/videobuf2-v4l2.h>
24 #include <media/videobuf2-dma-sg.h>
25 #include <media/v4l2-dv-timings.h>
26 #include <media/v4l2-event.h>
27 #include "mgb4_core.h"
29 #include "mgb4_sysfs.h"
31 #include "mgb4_vout.h"
34 ATTRIBUTE_GROUPS(mgb4_fpdl3_in
);
35 ATTRIBUTE_GROUPS(mgb4_gmsl_in
);
37 static const struct mgb4_vin_config vin_cfg
[] = {
38 {0, 0, 0, 6, {0x10, 0x00, 0x04, 0x08, 0x1C, 0x14, 0x18, 0x20, 0x24, 0x28, 0xE8}},
39 {1, 1, 1, 7, {0x40, 0x30, 0x34, 0x38, 0x4C, 0x44, 0x48, 0x50, 0x54, 0x58, 0xEC}}
42 static const struct i2c_board_info fpdl3_deser_info
[] = {
43 {I2C_BOARD_INFO("deserializer1", 0x38)},
44 {I2C_BOARD_INFO("deserializer2", 0x36)},
47 static const struct i2c_board_info gmsl_deser_info
[] = {
48 {I2C_BOARD_INFO("deserializer1", 0x4C)},
49 {I2C_BOARD_INFO("deserializer2", 0x2A)},
52 static const struct mgb4_i2c_kv fpdl3_i2c
[] = {
53 {0x06, 0xFF, 0x04}, {0x07, 0xFF, 0x01}, {0x45, 0xFF, 0xE8},
54 {0x49, 0xFF, 0x00}, {0x34, 0xFF, 0x00}, {0x23, 0xFF, 0x00}
57 static const struct mgb4_i2c_kv gmsl_i2c
[] = {
58 {0x01, 0x03, 0x03}, {0x300, 0x0C, 0x0C}, {0x03, 0xC0, 0xC0},
59 {0x1CE, 0x0E, 0x0E}, {0x11, 0x05, 0x00}, {0x05, 0xC0, 0x40},
60 {0x307, 0x0F, 0x00}, {0xA0, 0x03, 0x00}, {0x3E0, 0x07, 0x07},
61 {0x308, 0x01, 0x01}, {0x10, 0x20, 0x20}, {0x300, 0x40, 0x40}
64 static const struct v4l2_dv_timings_cap video_timings_cap
= {
65 .type
= V4L2_DV_BT_656_1120
,
71 .min_pixelclock
= 1843200, /* 320 x 240 x 24Hz */
72 .max_pixelclock
= 530841600, /* 4096 x 2160 x 60Hz */
73 .standards
= V4L2_DV_BT_STD_CEA861
| V4L2_DV_BT_STD_DMT
|
74 V4L2_DV_BT_STD_CVT
| V4L2_DV_BT_STD_GTF
,
75 .capabilities
= V4L2_DV_BT_CAP_PROGRESSIVE
|
76 V4L2_DV_BT_CAP_CUSTOM
,
80 /* Dummy timings when no signal present */
81 static const struct v4l2_dv_timings cea1080p60
= V4L2_DV_BT_CEA_1920X1080P60
;
84 * Returns the video output connected with the given video input if the input
85 * is in loopback mode.
87 static struct mgb4_vout_dev
*loopback_dev(struct mgb4_vin_dev
*vindev
, int i
)
89 struct mgb4_vout_dev
*voutdev
;
92 voutdev
= vindev
->mgbdev
->vout
[i
];
96 config
= mgb4_read_reg(&voutdev
->mgbdev
->video
,
97 voutdev
->config
->regs
.config
);
98 if ((config
& 0xc) >> 2 == vindev
->config
->id
)
105 * Check, whether the loopback mode - a HW INPUT->OUTPUT transmission - is
106 * enabled on the given input.
108 static int loopback_active(struct mgb4_vin_dev
*vindev
)
112 for (i
= 0; i
< MGB4_VOUT_DEVICES
; i
++)
113 if (loopback_dev(vindev
, i
))
120 * Set the output frame buffer padding of all outputs connected with the given
121 * input when the video input is set to loopback mode. The paddings must be
122 * the same for the loopback to work properly.
124 static void set_loopback_padding(struct mgb4_vin_dev
*vindev
, u32 padding
)
126 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
127 struct mgb4_vout_dev
*voutdev
;
130 for (i
= 0; i
< MGB4_VOUT_DEVICES
; i
++) {
131 voutdev
= loopback_dev(vindev
, i
);
133 mgb4_write_reg(video
, voutdev
->config
->regs
.padding
,
138 static int get_timings(struct mgb4_vin_dev
*vindev
,
139 struct v4l2_dv_timings
*timings
)
141 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
142 const struct mgb4_vin_regs
*regs
= &vindev
->config
->regs
;
144 u32 status
= mgb4_read_reg(video
, regs
->status
);
145 u32 pclk
= mgb4_read_reg(video
, regs
->pclk
);
146 u32 signal
= mgb4_read_reg(video
, regs
->signal
);
147 u32 signal2
= mgb4_read_reg(video
, regs
->signal2
);
148 u32 resolution
= mgb4_read_reg(video
, regs
->resolution
);
150 if (!(status
& (1U << 2)))
152 if (!(status
& (3 << 9)))
155 memset(timings
, 0, sizeof(*timings
));
156 timings
->type
= V4L2_DV_BT_656_1120
;
157 timings
->bt
.width
= resolution
>> 16;
158 timings
->bt
.height
= resolution
& 0xFFFF;
159 if (status
& (1U << 12))
160 timings
->bt
.polarities
|= V4L2_DV_HSYNC_POS_POL
;
161 if (status
& (1U << 13))
162 timings
->bt
.polarities
|= V4L2_DV_VSYNC_POS_POL
;
163 timings
->bt
.pixelclock
= pclk
* 1000;
164 timings
->bt
.hsync
= (signal
& 0x00FF0000) >> 16;
165 timings
->bt
.vsync
= (signal2
& 0x00FF0000) >> 16;
166 timings
->bt
.hbackporch
= (signal
& 0x0000FF00) >> 8;
167 timings
->bt
.hfrontporch
= signal
& 0x000000FF;
168 timings
->bt
.vbackporch
= (signal2
& 0x0000FF00) >> 8;
169 timings
->bt
.vfrontporch
= signal2
& 0x000000FF;
174 static void return_all_buffers(struct mgb4_vin_dev
*vindev
,
175 enum vb2_buffer_state state
)
177 struct mgb4_frame_buffer
*buf
, *node
;
180 spin_lock_irqsave(&vindev
->qlock
, flags
);
181 list_for_each_entry_safe(buf
, node
, &vindev
->buf_list
, list
) {
182 vb2_buffer_done(&buf
->vb
.vb2_buf
, state
);
183 list_del(&buf
->list
);
185 spin_unlock_irqrestore(&vindev
->qlock
, flags
);
188 static int queue_setup(struct vb2_queue
*q
, unsigned int *nbuffers
,
189 unsigned int *nplanes
, unsigned int sizes
[],
190 struct device
*alloc_devs
[])
192 struct mgb4_vin_dev
*vindev
= vb2_get_drv_priv(q
);
193 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
194 u32 config
= mgb4_read_reg(video
, vindev
->config
->regs
.config
);
195 u32 pixelsize
= (config
& (1U << 16)) ? 2 : 4;
196 unsigned int size
= (vindev
->timings
.bt
.width
+ vindev
->padding
)
197 * vindev
->timings
.bt
.height
* pixelsize
;
200 * If I/O reconfiguration is in process, do not allow to start
201 * the queue. See video_source_store() in mgb4_sysfs_out.c for
204 if (test_bit(0, &vindev
->mgbdev
->io_reconfig
))
210 return sizes
[0] < size
? -EINVAL
: 0;
217 static int buffer_init(struct vb2_buffer
*vb
)
219 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
220 struct mgb4_frame_buffer
*buf
= to_frame_buffer(vbuf
);
222 INIT_LIST_HEAD(&buf
->list
);
227 static int buffer_prepare(struct vb2_buffer
*vb
)
229 struct mgb4_vin_dev
*vindev
= vb2_get_drv_priv(vb
->vb2_queue
);
230 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
231 struct device
*dev
= &vindev
->mgbdev
->pdev
->dev
;
232 u32 config
= mgb4_read_reg(video
, vindev
->config
->regs
.config
);
233 u32 pixelsize
= (config
& (1U << 16)) ? 2 : 4;
234 unsigned int size
= (vindev
->timings
.bt
.width
+ vindev
->padding
)
235 * vindev
->timings
.bt
.height
* pixelsize
;
237 if (vb2_plane_size(vb
, 0) < size
) {
238 dev_err(dev
, "buffer too small (%lu < %u)\n",
239 vb2_plane_size(vb
, 0), size
);
243 vb2_set_plane_payload(vb
, 0, size
);
248 static void buffer_queue(struct vb2_buffer
*vb
)
250 struct mgb4_vin_dev
*vindev
= vb2_get_drv_priv(vb
->vb2_queue
);
251 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
252 struct mgb4_frame_buffer
*buf
= to_frame_buffer(vbuf
);
255 spin_lock_irqsave(&vindev
->qlock
, flags
);
256 list_add_tail(&buf
->list
, &vindev
->buf_list
);
257 spin_unlock_irqrestore(&vindev
->qlock
, flags
);
260 static void stop_streaming(struct vb2_queue
*vq
)
262 struct mgb4_vin_dev
*vindev
= vb2_get_drv_priv(vq
);
263 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
264 const struct mgb4_vin_config
*config
= vindev
->config
;
265 int irq
= xdma_get_user_irq(vindev
->mgbdev
->xdev
, config
->vin_irq
);
267 xdma_disable_user_irq(vindev
->mgbdev
->xdev
, irq
);
270 * In loopback mode, the HW frame queue must be left running for
271 * the IN->OUT transmission to work!
273 if (!loopback_active(vindev
))
274 mgb4_mask_reg(&vindev
->mgbdev
->video
, config
->regs
.config
, 0x2,
277 mgb4_write_reg(video
, vindev
->config
->regs
.padding
, 0);
278 set_loopback_padding(vindev
, 0);
280 cancel_work_sync(&vindev
->dma_work
);
281 return_all_buffers(vindev
, VB2_BUF_STATE_ERROR
);
284 static int start_streaming(struct vb2_queue
*vq
, unsigned int count
)
286 struct mgb4_vin_dev
*vindev
= vb2_get_drv_priv(vq
);
287 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
288 const struct mgb4_vin_config
*config
= vindev
->config
;
289 int irq
= xdma_get_user_irq(vindev
->mgbdev
->xdev
, config
->vin_irq
);
291 vindev
->sequence
= 0;
294 * In loopback mode, the HW frame queue is already running.
296 if (!loopback_active(vindev
))
297 mgb4_mask_reg(&vindev
->mgbdev
->video
, config
->regs
.config
, 0x2,
300 mgb4_write_reg(video
, vindev
->config
->regs
.padding
, vindev
->padding
);
301 set_loopback_padding(vindev
, vindev
->padding
);
303 xdma_enable_user_irq(vindev
->mgbdev
->xdev
, irq
);
308 static const struct vb2_ops queue_ops
= {
309 .queue_setup
= queue_setup
,
310 .buf_init
= buffer_init
,
311 .buf_prepare
= buffer_prepare
,
312 .buf_queue
= buffer_queue
,
313 .start_streaming
= start_streaming
,
314 .stop_streaming
= stop_streaming
,
317 static int fh_open(struct file
*file
)
319 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
322 mutex_lock(&vindev
->lock
);
324 rv
= v4l2_fh_open(file
);
328 if (!v4l2_fh_is_singular_file(file
))
331 if (get_timings(vindev
, &vindev
->timings
) < 0)
332 vindev
->timings
= cea1080p60
;
335 mutex_unlock(&vindev
->lock
);
339 static const struct v4l2_file_operations video_fops
= {
340 .owner
= THIS_MODULE
,
342 .release
= vb2_fop_release
,
343 .unlocked_ioctl
= video_ioctl2
,
344 .read
= vb2_fop_read
,
345 .mmap
= vb2_fop_mmap
,
346 .poll
= vb2_fop_poll
,
349 static int vidioc_querycap(struct file
*file
, void *priv
,
350 struct v4l2_capability
*cap
)
352 strscpy(cap
->driver
, KBUILD_MODNAME
, sizeof(cap
->driver
));
353 strscpy(cap
->card
, "MGB4 PCIe Card", sizeof(cap
->card
));
358 static int vidioc_enum_fmt(struct file
*file
, void *priv
,
359 struct v4l2_fmtdesc
*f
)
361 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
362 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
365 f
->pixelformat
= V4L2_PIX_FMT_ABGR32
;
367 } else if (f
->index
== 1 && has_yuv(video
)) {
368 f
->pixelformat
= V4L2_PIX_FMT_YUYV
;
375 static int vidioc_enum_frameintervals(struct file
*file
, void *priv
,
376 struct v4l2_frmivalenum
*ival
)
378 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
379 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
381 if (ival
->index
!= 0)
383 if (!(ival
->pixel_format
== V4L2_PIX_FMT_ABGR32
||
384 ((has_yuv(video
) && ival
->pixel_format
== V4L2_PIX_FMT_YUYV
))))
386 if (ival
->width
!= vindev
->timings
.bt
.width
||
387 ival
->height
!= vindev
->timings
.bt
.height
)
390 ival
->type
= V4L2_FRMIVAL_TYPE_STEPWISE
;
391 ival
->stepwise
.max
.denominator
= MGB4_HW_FREQ
;
392 ival
->stepwise
.max
.numerator
= 0xFFFFFFFF;
393 ival
->stepwise
.min
.denominator
= vindev
->timings
.bt
.pixelclock
;
394 ival
->stepwise
.min
.numerator
= pixel_size(&vindev
->timings
);
395 ival
->stepwise
.step
.denominator
= MGB4_HW_FREQ
;
396 ival
->stepwise
.step
.numerator
= 1;
401 static int vidioc_g_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
403 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
404 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
405 u32 config
= mgb4_read_reg(video
, vindev
->config
->regs
.config
);
407 f
->fmt
.pix
.width
= vindev
->timings
.bt
.width
;
408 f
->fmt
.pix
.height
= vindev
->timings
.bt
.height
;
409 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
411 if (config
& (1U << 16)) {
412 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_YUYV
;
413 if (config
& (1U << 20)) {
414 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_REC709
;
416 if (config
& (1U << 19))
417 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
419 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
421 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
+ vindev
->padding
) * 2;
423 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_ABGR32
;
424 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_RAW
;
425 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
+ vindev
->padding
) * 4;
427 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.bytesperline
* f
->fmt
.pix
.height
;
432 static int vidioc_try_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
434 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
435 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
438 f
->fmt
.pix
.width
= vindev
->timings
.bt
.width
;
439 f
->fmt
.pix
.height
= vindev
->timings
.bt
.height
;
440 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
442 if (has_yuv(video
) && f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_YUYV
) {
444 if (!(f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_REC709
||
445 f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_SMPTE170M
))
446 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
449 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_ABGR32
;
450 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_RAW
;
453 if (f
->fmt
.pix
.bytesperline
> f
->fmt
.pix
.width
* pixelsize
&&
454 f
->fmt
.pix
.bytesperline
< f
->fmt
.pix
.width
* pixelsize
* 2)
455 f
->fmt
.pix
.bytesperline
= ALIGN(f
->fmt
.pix
.bytesperline
,
458 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
* pixelsize
;
459 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.bytesperline
* f
->fmt
.pix
.height
;
464 static int vidioc_s_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
466 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
467 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
468 u32 config
, pixelsize
;
470 if (vb2_is_busy(&vindev
->queue
))
473 vidioc_try_fmt(file
, priv
, f
);
475 config
= mgb4_read_reg(video
, vindev
->config
->regs
.config
);
476 if (f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_YUYV
) {
480 if (f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_REC709
) {
483 } else if (f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_SMPTE170M
) {
484 config
&= ~(1U << 20);
487 config
&= ~(1U << 20);
488 config
&= ~(1U << 19);
492 config
&= ~(1U << 16);
494 mgb4_write_reg(video
, vindev
->config
->regs
.config
, config
);
496 vindev
->padding
= (f
->fmt
.pix
.bytesperline
- (f
->fmt
.pix
.width
497 * pixelsize
)) / pixelsize
;
502 static int vidioc_enum_input(struct file
*file
, void *priv
,
503 struct v4l2_input
*i
)
505 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
506 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
512 strscpy(i
->name
, "MGB4", sizeof(i
->name
));
513 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
514 i
->capabilities
= V4L2_IN_CAP_DV_TIMINGS
;
517 status
= mgb4_read_reg(video
, vindev
->config
->regs
.status
);
518 if (!(status
& (1U << 2)))
519 i
->status
|= V4L2_IN_ST_NO_SYNC
;
520 if (!(status
& (3 << 9)))
521 i
->status
|= V4L2_IN_ST_NO_SIGNAL
;
526 static int vidioc_enum_framesizes(struct file
*file
, void *fh
,
527 struct v4l2_frmsizeenum
*fsize
)
529 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
531 if (fsize
->index
!= 0 || !(fsize
->pixel_format
== V4L2_PIX_FMT_ABGR32
||
532 fsize
->pixel_format
== V4L2_PIX_FMT_YUYV
))
535 fsize
->discrete
.width
= vindev
->timings
.bt
.width
;
536 fsize
->discrete
.height
= vindev
->timings
.bt
.height
;
537 fsize
->type
= V4L2_FRMSIZE_TYPE_DISCRETE
;
542 static int vidioc_s_input(struct file
*file
, void *priv
, unsigned int i
)
544 return (i
== 0) ? 0 : -EINVAL
;
547 static int vidioc_g_input(struct file
*file
, void *priv
, unsigned int *i
)
553 static int vidioc_g_parm(struct file
*file
, void *priv
,
554 struct v4l2_streamparm
*parm
)
556 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
557 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
558 struct v4l2_fract
*tpf
= &parm
->parm
.output
.timeperframe
;
561 parm
->parm
.capture
.readbuffers
= 2;
563 if (has_timeperframe(video
)) {
564 timer
= mgb4_read_reg(video
, vindev
->config
->regs
.timer
);
565 if (timer
< 0xFFFF) {
566 tpf
->numerator
= pixel_size(&vindev
->timings
);
567 tpf
->denominator
= vindev
->timings
.bt
.pixelclock
;
569 tpf
->numerator
= timer
;
570 tpf
->denominator
= MGB4_HW_FREQ
;
573 parm
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
579 static int vidioc_s_parm(struct file
*file
, void *priv
,
580 struct v4l2_streamparm
*parm
)
582 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
583 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
584 struct v4l2_fract
*tpf
= &parm
->parm
.output
.timeperframe
;
587 if (has_timeperframe(video
)) {
588 timer
= tpf
->denominator
?
589 MGB4_PERIOD(tpf
->numerator
, tpf
->denominator
) : 0;
591 period
= MGB4_PERIOD(pixel_size(&vindev
->timings
),
592 vindev
->timings
.bt
.pixelclock
);
597 mgb4_write_reg(video
, vindev
->config
->regs
.timer
, timer
);
600 return vidioc_g_parm(file
, priv
, parm
);
603 static int vidioc_s_dv_timings(struct file
*file
, void *fh
,
604 struct v4l2_dv_timings
*timings
)
606 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
608 if (timings
->bt
.width
< video_timings_cap
.bt
.min_width
||
609 timings
->bt
.width
> video_timings_cap
.bt
.max_width
||
610 timings
->bt
.height
< video_timings_cap
.bt
.min_height
||
611 timings
->bt
.height
> video_timings_cap
.bt
.max_height
)
613 if (timings
->bt
.width
== vindev
->timings
.bt
.width
&&
614 timings
->bt
.height
== vindev
->timings
.bt
.height
)
616 if (vb2_is_busy(&vindev
->queue
))
619 vindev
->timings
= *timings
;
624 static int vidioc_g_dv_timings(struct file
*file
, void *fh
,
625 struct v4l2_dv_timings
*timings
)
627 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
628 *timings
= vindev
->timings
;
633 static int vidioc_query_dv_timings(struct file
*file
, void *fh
,
634 struct v4l2_dv_timings
*timings
)
636 struct mgb4_vin_dev
*vindev
= video_drvdata(file
);
638 return get_timings(vindev
, timings
);
641 static int vidioc_enum_dv_timings(struct file
*file
, void *fh
,
642 struct v4l2_enum_dv_timings
*timings
)
644 return v4l2_enum_dv_timings_cap(timings
, &video_timings_cap
, NULL
, NULL
);
647 static int vidioc_dv_timings_cap(struct file
*file
, void *fh
,
648 struct v4l2_dv_timings_cap
*cap
)
650 *cap
= video_timings_cap
;
655 static int vidioc_subscribe_event(struct v4l2_fh
*fh
,
656 const struct v4l2_event_subscription
*sub
)
659 case V4L2_EVENT_SOURCE_CHANGE
:
660 return v4l2_src_change_event_subscribe(fh
, sub
);
663 return v4l2_ctrl_subscribe_event(fh
, sub
);
666 static const struct v4l2_ioctl_ops video_ioctl_ops
= {
667 .vidioc_querycap
= vidioc_querycap
,
668 .vidioc_enum_fmt_vid_cap
= vidioc_enum_fmt
,
669 .vidioc_try_fmt_vid_cap
= vidioc_try_fmt
,
670 .vidioc_s_fmt_vid_cap
= vidioc_s_fmt
,
671 .vidioc_g_fmt_vid_cap
= vidioc_g_fmt
,
672 .vidioc_enum_framesizes
= vidioc_enum_framesizes
,
673 .vidioc_enum_frameintervals
= vidioc_enum_frameintervals
,
674 .vidioc_enum_input
= vidioc_enum_input
,
675 .vidioc_g_input
= vidioc_g_input
,
676 .vidioc_s_input
= vidioc_s_input
,
677 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
678 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
679 .vidioc_prepare_buf
= vb2_ioctl_prepare_buf
,
680 .vidioc_querybuf
= vb2_ioctl_querybuf
,
681 .vidioc_qbuf
= vb2_ioctl_qbuf
,
682 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
683 .vidioc_expbuf
= vb2_ioctl_expbuf
,
684 .vidioc_streamon
= vb2_ioctl_streamon
,
685 .vidioc_streamoff
= vb2_ioctl_streamoff
,
686 .vidioc_g_parm
= vidioc_g_parm
,
687 .vidioc_s_parm
= vidioc_s_parm
,
688 .vidioc_dv_timings_cap
= vidioc_dv_timings_cap
,
689 .vidioc_enum_dv_timings
= vidioc_enum_dv_timings
,
690 .vidioc_g_dv_timings
= vidioc_g_dv_timings
,
691 .vidioc_s_dv_timings
= vidioc_s_dv_timings
,
692 .vidioc_query_dv_timings
= vidioc_query_dv_timings
,
693 .vidioc_subscribe_event
= vidioc_subscribe_event
,
694 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
697 static void dma_transfer(struct work_struct
*work
)
699 struct mgb4_vin_dev
*vindev
= container_of(work
, struct mgb4_vin_dev
,
701 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
702 struct device
*dev
= &vindev
->mgbdev
->pdev
->dev
;
703 struct mgb4_frame_buffer
*buf
= NULL
;
708 spin_lock_irqsave(&vindev
->qlock
, flags
);
709 if (!list_empty(&vindev
->buf_list
)) {
710 buf
= list_first_entry(&vindev
->buf_list
,
711 struct mgb4_frame_buffer
, list
);
712 list_del_init(vindev
->buf_list
.next
);
714 spin_unlock_irqrestore(&vindev
->qlock
, flags
);
719 addr
= mgb4_read_reg(video
, vindev
->config
->regs
.address
);
720 if (addr
>= MGB4_ERR_QUEUE_FULL
) {
721 dev_dbg(dev
, "frame queue error (%d)\n", (int)addr
);
722 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
726 rv
= mgb4_dma_transfer(vindev
->mgbdev
, vindev
->config
->dma_channel
,
728 vb2_dma_sg_plane_desc(&buf
->vb
.vb2_buf
, 0));
730 dev_warn(dev
, "DMA transfer error\n");
731 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
733 buf
->vb
.vb2_buf
.timestamp
= ktime_get_ns();
734 buf
->vb
.sequence
= vindev
->sequence
++;
735 buf
->vb
.field
= V4L2_FIELD_NONE
;
736 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_DONE
);
740 static void signal_change(struct work_struct
*work
)
742 struct mgb4_vin_dev
*vindev
= container_of(work
, struct mgb4_vin_dev
,
744 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
745 struct v4l2_bt_timings
*timings
= &vindev
->timings
.bt
;
746 struct device
*dev
= &vindev
->mgbdev
->pdev
->dev
;
748 u32 resolution
= mgb4_read_reg(video
, vindev
->config
->regs
.resolution
);
749 u32 width
= resolution
>> 16;
750 u32 height
= resolution
& 0xFFFF;
752 if (timings
->width
!= width
|| timings
->height
!= height
) {
753 static const struct v4l2_event ev
= {
754 .type
= V4L2_EVENT_SOURCE_CHANGE
,
755 .u
.src_change
.changes
= V4L2_EVENT_SRC_CH_RESOLUTION
,
758 v4l2_event_queue(&vindev
->vdev
, &ev
);
760 if (vb2_is_streaming(&vindev
->queue
))
761 vb2_queue_error(&vindev
->queue
);
764 dev_dbg(dev
, "stream changed to %ux%u\n", width
, height
);
767 static irqreturn_t
vin_handler(int irq
, void *ctx
)
769 struct mgb4_vin_dev
*vindev
= (struct mgb4_vin_dev
*)ctx
;
770 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
772 schedule_work(&vindev
->dma_work
);
774 mgb4_write_reg(video
, 0xB4, 1U << vindev
->config
->vin_irq
);
779 static irqreturn_t
err_handler(int irq
, void *ctx
)
781 struct mgb4_vin_dev
*vindev
= (struct mgb4_vin_dev
*)ctx
;
782 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
784 schedule_work(&vindev
->err_work
);
786 mgb4_write_reg(video
, 0xB4, 1U << vindev
->config
->err_irq
);
791 static int deser_init(struct mgb4_vin_dev
*vindev
, int id
)
795 const struct mgb4_i2c_kv
*values
;
796 const struct i2c_board_info
*info
;
797 struct device
*dev
= &vindev
->mgbdev
->pdev
->dev
;
799 if (MGB4_IS_GMSL(vindev
->mgbdev
)) {
800 info
= &gmsl_deser_info
[id
];
803 values_count
= ARRAY_SIZE(gmsl_i2c
);
805 info
= &fpdl3_deser_info
[id
];
808 values_count
= ARRAY_SIZE(fpdl3_i2c
);
811 rv
= mgb4_i2c_init(&vindev
->deser
, vindev
->mgbdev
->i2c_adap
, info
,
814 dev_err(dev
, "failed to create deserializer\n");
817 rv
= mgb4_i2c_configure(&vindev
->deser
, values
, values_count
);
819 dev_err(dev
, "failed to configure deserializer\n");
826 mgb4_i2c_free(&vindev
->deser
);
831 static void fpga_init(struct mgb4_vin_dev
*vindev
)
833 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
834 const struct mgb4_vin_regs
*regs
= &vindev
->config
->regs
;
836 mgb4_write_reg(video
, regs
->config
, 0x00000001);
837 mgb4_write_reg(video
, regs
->sync
, 0x03E80002);
838 mgb4_write_reg(video
, regs
->padding
, 0x00000000);
839 mgb4_write_reg(video
, regs
->config
, 1U << 9);
842 static void create_debugfs(struct mgb4_vin_dev
*vindev
)
844 #ifdef CONFIG_DEBUG_FS
845 struct mgb4_regs
*video
= &vindev
->mgbdev
->video
;
846 struct dentry
*entry
;
848 if (IS_ERR_OR_NULL(vindev
->mgbdev
->debugfs
))
850 entry
= debugfs_create_dir(vindev
->vdev
.name
, vindev
->mgbdev
->debugfs
);
854 vindev
->regs
[0].name
= "CONFIG";
855 vindev
->regs
[0].offset
= vindev
->config
->regs
.config
;
856 vindev
->regs
[1].name
= "STATUS";
857 vindev
->regs
[1].offset
= vindev
->config
->regs
.status
;
858 vindev
->regs
[2].name
= "RESOLUTION";
859 vindev
->regs
[2].offset
= vindev
->config
->regs
.resolution
;
860 vindev
->regs
[3].name
= "FRAME_PERIOD";
861 vindev
->regs
[3].offset
= vindev
->config
->regs
.frame_period
;
862 vindev
->regs
[4].name
= "HS_VS_GENER_SETTINGS";
863 vindev
->regs
[4].offset
= vindev
->config
->regs
.sync
;
864 vindev
->regs
[5].name
= "PCLK_FREQUENCY";
865 vindev
->regs
[5].offset
= vindev
->config
->regs
.pclk
;
866 vindev
->regs
[6].name
= "VIDEO_PARAMS_1";
867 vindev
->regs
[6].offset
= vindev
->config
->regs
.signal
;
868 vindev
->regs
[7].name
= "VIDEO_PARAMS_2";
869 vindev
->regs
[7].offset
= vindev
->config
->regs
.signal2
;
870 vindev
->regs
[8].name
= "PADDING_PIXELS";
871 vindev
->regs
[8].offset
= vindev
->config
->regs
.padding
;
872 if (has_timeperframe(video
)) {
873 vindev
->regs
[9].name
= "TIMER";
874 vindev
->regs
[9].offset
= vindev
->config
->regs
.timer
;
875 vindev
->regset
.nregs
= 10;
877 vindev
->regset
.nregs
= 9;
880 vindev
->regset
.base
= video
->membase
;
881 vindev
->regset
.regs
= vindev
->regs
;
883 debugfs_create_regset32("registers", 0444, entry
, &vindev
->regset
);
887 struct mgb4_vin_dev
*mgb4_vin_create(struct mgb4_dev
*mgbdev
, int id
)
890 const struct attribute_group
**groups
;
891 struct mgb4_vin_dev
*vindev
;
892 struct pci_dev
*pdev
= mgbdev
->pdev
;
893 struct device
*dev
= &pdev
->dev
;
894 int vin_irq
, err_irq
;
896 vindev
= kzalloc(sizeof(*vindev
), GFP_KERNEL
);
900 vindev
->mgbdev
= mgbdev
;
901 vindev
->config
= &vin_cfg
[id
];
904 INIT_LIST_HEAD(&vindev
->buf_list
);
905 spin_lock_init(&vindev
->qlock
);
908 INIT_WORK(&vindev
->dma_work
, dma_transfer
);
909 INIT_WORK(&vindev
->err_work
, signal_change
);
912 vin_irq
= xdma_get_user_irq(mgbdev
->xdev
, vindev
->config
->vin_irq
);
913 rv
= request_irq(vin_irq
, vin_handler
, 0, "mgb4-vin", vindev
);
915 dev_err(dev
, "failed to register vin irq handler\n");
918 /* Error IRQ callback */
919 err_irq
= xdma_get_user_irq(mgbdev
->xdev
, vindev
->config
->err_irq
);
920 rv
= request_irq(err_irq
, err_handler
, 0, "mgb4-err", vindev
);
922 dev_err(dev
, "failed to register err irq handler\n");
926 /* Set the FPGA registers default values */
929 /* Set the deserializer default values */
930 rv
= deser_init(vindev
, id
);
934 /* V4L2 stuff init */
935 rv
= v4l2_device_register(dev
, &vindev
->v4l2dev
);
937 dev_err(dev
, "failed to register v4l2 device\n");
941 mutex_init(&vindev
->lock
);
943 vindev
->queue
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
944 vindev
->queue
.io_modes
= VB2_MMAP
| VB2_DMABUF
| VB2_READ
;
945 vindev
->queue
.buf_struct_size
= sizeof(struct mgb4_frame_buffer
);
946 vindev
->queue
.ops
= &queue_ops
;
947 vindev
->queue
.mem_ops
= &vb2_dma_sg_memops
;
948 vindev
->queue
.gfp_flags
= GFP_DMA32
;
949 vindev
->queue
.timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
950 vindev
->queue
.min_queued_buffers
= 2;
951 vindev
->queue
.drv_priv
= vindev
;
952 vindev
->queue
.lock
= &vindev
->lock
;
953 vindev
->queue
.dev
= dev
;
954 rv
= vb2_queue_init(&vindev
->queue
);
956 dev_err(dev
, "failed to initialize vb2 queue\n");
960 snprintf(vindev
->vdev
.name
, sizeof(vindev
->vdev
.name
), "mgb4-in%d",
962 vindev
->vdev
.device_caps
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_READWRITE
963 | V4L2_CAP_STREAMING
;
964 vindev
->vdev
.fops
= &video_fops
;
965 vindev
->vdev
.ioctl_ops
= &video_ioctl_ops
;
966 vindev
->vdev
.release
= video_device_release_empty
;
967 vindev
->vdev
.v4l2_dev
= &vindev
->v4l2dev
;
968 vindev
->vdev
.lock
= &vindev
->lock
;
969 vindev
->vdev
.queue
= &vindev
->queue
;
970 video_set_drvdata(&vindev
->vdev
, vindev
);
972 /* Enable the video signal change watcher */
973 xdma_enable_user_irq(vindev
->mgbdev
->xdev
, err_irq
);
975 /* Register the video device */
976 rv
= video_register_device(&vindev
->vdev
, VFL_TYPE_VIDEO
, -1);
978 dev_err(dev
, "failed to register video device\n");
982 /* Module sysfs attributes */
983 groups
= MGB4_IS_GMSL(mgbdev
)
984 ? mgb4_gmsl_in_groups
: mgb4_fpdl3_in_groups
;
985 rv
= device_add_groups(&vindev
->vdev
.dev
, groups
);
987 dev_err(dev
, "failed to create sysfs attributes\n");
991 create_debugfs(vindev
);
996 video_unregister_device(&vindev
->vdev
);
998 v4l2_device_unregister(&vindev
->v4l2dev
);
1000 free_irq(err_irq
, vindev
);
1002 free_irq(vin_irq
, vindev
);
1009 void mgb4_vin_free(struct mgb4_vin_dev
*vindev
)
1011 const struct attribute_group
**groups
;
1012 int vin_irq
= xdma_get_user_irq(vindev
->mgbdev
->xdev
,
1013 vindev
->config
->vin_irq
);
1014 int err_irq
= xdma_get_user_irq(vindev
->mgbdev
->xdev
,
1015 vindev
->config
->err_irq
);
1017 xdma_disable_user_irq(vindev
->mgbdev
->xdev
, err_irq
);
1019 free_irq(vin_irq
, vindev
);
1020 free_irq(err_irq
, vindev
);
1022 groups
= MGB4_IS_GMSL(vindev
->mgbdev
)
1023 ? mgb4_gmsl_in_groups
: mgb4_fpdl3_in_groups
;
1024 device_remove_groups(&vindev
->vdev
.dev
, groups
);
1026 mgb4_i2c_free(&vindev
->deser
);
1027 video_unregister_device(&vindev
->vdev
);
1028 v4l2_device_unregister(&vindev
->v4l2dev
);