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 output device module. It initializes the signal serializers
7 * and creates the v4l2 video devices.
9 * When the device is in loopback mode (a direct, in HW, in->out frame passing
10 * mode) we disable the v4l2 output by returning EBUSY in the open() syscall.
13 #include <linux/pci.h>
14 #include <linux/align.h>
15 #include <linux/dma/amd_xdma.h>
16 #include <media/v4l2-ioctl.h>
17 #include <media/videobuf2-v4l2.h>
18 #include <media/videobuf2-dma-sg.h>
19 #include <media/v4l2-dv-timings.h>
20 #include "mgb4_core.h"
22 #include "mgb4_sysfs.h"
25 #include "mgb4_vout.h"
27 #define DEFAULT_WIDTH 1280
28 #define DEFAULT_HEIGHT 640
29 #define DEFAULT_PERIOD (MGB4_HW_FREQ / 60)
31 ATTRIBUTE_GROUPS(mgb4_fpdl3_out
);
32 ATTRIBUTE_GROUPS(mgb4_gmsl_out
);
34 static const struct mgb4_vout_config vout_cfg
[] = {
35 {0, 0, 8, {0x78, 0x60, 0x64, 0x68, 0x74, 0x6C, 0x70, 0x7C, 0xE0}},
36 {1, 1, 9, {0x98, 0x80, 0x84, 0x88, 0x94, 0x8C, 0x90, 0x9C, 0xE4}}
39 static const struct i2c_board_info fpdl3_ser_info
[] = {
40 {I2C_BOARD_INFO("serializer1", 0x14)},
41 {I2C_BOARD_INFO("serializer2", 0x16)},
44 static const struct mgb4_i2c_kv fpdl3_i2c
[] = {
45 {0x05, 0xFF, 0x04}, {0x06, 0xFF, 0x01}, {0xC2, 0xFF, 0x80}
48 static const struct v4l2_dv_timings_cap video_timings_cap
= {
49 .type
= V4L2_DV_BT_656_1120
,
55 .min_pixelclock
= 1843200, /* 320 x 240 x 24Hz */
56 .max_pixelclock
= 530841600, /* 4096 x 2160 x 60Hz */
57 .standards
= V4L2_DV_BT_STD_CEA861
| V4L2_DV_BT_STD_DMT
|
58 V4L2_DV_BT_STD_CVT
| V4L2_DV_BT_STD_GTF
,
59 .capabilities
= V4L2_DV_BT_CAP_PROGRESSIVE
|
60 V4L2_DV_BT_CAP_CUSTOM
,
64 static void get_timings(struct mgb4_vout_dev
*voutdev
,
65 struct v4l2_dv_timings
*timings
)
67 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
68 const struct mgb4_vout_regs
*regs
= &voutdev
->config
->regs
;
70 u32 hsync
= mgb4_read_reg(video
, regs
->hsync
);
71 u32 vsync
= mgb4_read_reg(video
, regs
->vsync
);
72 u32 resolution
= mgb4_read_reg(video
, regs
->resolution
);
74 memset(timings
, 0, sizeof(*timings
));
75 timings
->type
= V4L2_DV_BT_656_1120
;
76 timings
->bt
.width
= resolution
>> 16;
77 timings
->bt
.height
= resolution
& 0xFFFF;
78 if (hsync
& (1U << 31))
79 timings
->bt
.polarities
|= V4L2_DV_HSYNC_POS_POL
;
80 if (vsync
& (1U << 31))
81 timings
->bt
.polarities
|= V4L2_DV_VSYNC_POS_POL
;
82 timings
->bt
.pixelclock
= voutdev
->freq
* 1000;
83 timings
->bt
.hsync
= (hsync
& 0x00FF0000) >> 16;
84 timings
->bt
.vsync
= (vsync
& 0x00FF0000) >> 16;
85 timings
->bt
.hbackporch
= (hsync
& 0x0000FF00) >> 8;
86 timings
->bt
.hfrontporch
= hsync
& 0x000000FF;
87 timings
->bt
.vbackporch
= (vsync
& 0x0000FF00) >> 8;
88 timings
->bt
.vfrontporch
= vsync
& 0x000000FF;
91 static void return_all_buffers(struct mgb4_vout_dev
*voutdev
,
92 enum vb2_buffer_state state
)
94 struct mgb4_frame_buffer
*buf
, *node
;
97 spin_lock_irqsave(&voutdev
->qlock
, flags
);
98 list_for_each_entry_safe(buf
, node
, &voutdev
->buf_list
, list
) {
99 vb2_buffer_done(&buf
->vb
.vb2_buf
, state
);
100 list_del(&buf
->list
);
102 spin_unlock_irqrestore(&voutdev
->qlock
, flags
);
105 static int queue_setup(struct vb2_queue
*q
, unsigned int *nbuffers
,
106 unsigned int *nplanes
, unsigned int sizes
[],
107 struct device
*alloc_devs
[])
109 struct mgb4_vout_dev
*voutdev
= vb2_get_drv_priv(q
);
110 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
111 u32 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
112 u32 pixelsize
= (config
& (1U << 16)) ? 2 : 4;
113 unsigned int size
= (voutdev
->width
+ voutdev
->padding
) * voutdev
->height
117 * If I/O reconfiguration is in process, do not allow to start
118 * the queue. See video_source_store() in mgb4_sysfs_out.c for
121 if (test_bit(0, &voutdev
->mgbdev
->io_reconfig
))
125 return sizes
[0] < size
? -EINVAL
: 0;
132 static int buffer_init(struct vb2_buffer
*vb
)
134 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
135 struct mgb4_frame_buffer
*buf
= to_frame_buffer(vbuf
);
137 INIT_LIST_HEAD(&buf
->list
);
142 static int buffer_prepare(struct vb2_buffer
*vb
)
144 struct mgb4_vout_dev
*voutdev
= vb2_get_drv_priv(vb
->vb2_queue
);
145 struct device
*dev
= &voutdev
->mgbdev
->pdev
->dev
;
146 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
147 u32 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
148 u32 pixelsize
= (config
& (1U << 16)) ? 2 : 4;
149 unsigned int size
= (voutdev
->width
+ voutdev
->padding
) * voutdev
->height
152 if (vb2_plane_size(vb
, 0) < size
) {
153 dev_err(dev
, "buffer too small (%lu < %u)\n",
154 vb2_plane_size(vb
, 0), size
);
158 vb2_set_plane_payload(vb
, 0, size
);
163 static void buffer_queue(struct vb2_buffer
*vb
)
165 struct mgb4_vout_dev
*vindev
= vb2_get_drv_priv(vb
->vb2_queue
);
166 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
167 struct mgb4_frame_buffer
*buf
= to_frame_buffer(vbuf
);
170 spin_lock_irqsave(&vindev
->qlock
, flags
);
171 list_add_tail(&buf
->list
, &vindev
->buf_list
);
172 spin_unlock_irqrestore(&vindev
->qlock
, flags
);
175 static void stop_streaming(struct vb2_queue
*vq
)
177 struct mgb4_vout_dev
*voutdev
= vb2_get_drv_priv(vq
);
178 struct mgb4_dev
*mgbdev
= voutdev
->mgbdev
;
179 int irq
= xdma_get_user_irq(mgbdev
->xdev
, voutdev
->config
->irq
);
181 xdma_disable_user_irq(mgbdev
->xdev
, irq
);
182 cancel_work_sync(&voutdev
->dma_work
);
183 mgb4_mask_reg(&mgbdev
->video
, voutdev
->config
->regs
.config
, 0x2, 0x0);
184 return_all_buffers(voutdev
, VB2_BUF_STATE_ERROR
);
187 static int start_streaming(struct vb2_queue
*vq
, unsigned int count
)
189 struct mgb4_vout_dev
*voutdev
= vb2_get_drv_priv(vq
);
190 struct mgb4_dev
*mgbdev
= voutdev
->mgbdev
;
191 struct device
*dev
= &mgbdev
->pdev
->dev
;
192 struct mgb4_frame_buffer
*buf
;
193 struct mgb4_regs
*video
= &mgbdev
->video
;
194 const struct mgb4_vout_config
*config
= voutdev
->config
;
195 int irq
= xdma_get_user_irq(mgbdev
->xdev
, config
->irq
);
199 mgb4_mask_reg(video
, config
->regs
.config
, 0x2, 0x2);
201 addr
= mgb4_read_reg(video
, config
->regs
.address
);
202 if (addr
>= MGB4_ERR_QUEUE_FULL
) {
203 dev_dbg(dev
, "frame queue error (%d)\n", (int)addr
);
204 return_all_buffers(voutdev
, VB2_BUF_STATE_QUEUED
);
208 buf
= list_first_entry(&voutdev
->buf_list
, struct mgb4_frame_buffer
,
210 list_del_init(voutdev
->buf_list
.next
);
212 rv
= mgb4_dma_transfer(mgbdev
, config
->dma_channel
, true, addr
,
213 vb2_dma_sg_plane_desc(&buf
->vb
.vb2_buf
, 0));
215 dev_warn(dev
, "DMA transfer error\n");
216 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
218 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_DONE
);
221 xdma_enable_user_irq(mgbdev
->xdev
, irq
);
226 static const struct vb2_ops queue_ops
= {
227 .queue_setup
= queue_setup
,
228 .buf_init
= buffer_init
,
229 .buf_prepare
= buffer_prepare
,
230 .buf_queue
= buffer_queue
,
231 .start_streaming
= start_streaming
,
232 .stop_streaming
= stop_streaming
,
233 .wait_prepare
= vb2_ops_wait_prepare
,
234 .wait_finish
= vb2_ops_wait_finish
237 static int vidioc_querycap(struct file
*file
, void *priv
,
238 struct v4l2_capability
*cap
)
240 strscpy(cap
->driver
, KBUILD_MODNAME
, sizeof(cap
->driver
));
241 strscpy(cap
->card
, "MGB4 PCIe Card", sizeof(cap
->card
));
246 static int vidioc_enum_fmt(struct file
*file
, void *priv
,
247 struct v4l2_fmtdesc
*f
)
249 struct mgb4_vin_dev
*voutdev
= video_drvdata(file
);
250 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
253 f
->pixelformat
= V4L2_PIX_FMT_ABGR32
;
255 } else if (f
->index
== 1 && has_yuv(video
)) {
256 f
->pixelformat
= V4L2_PIX_FMT_YUYV
;
263 static int vidioc_g_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
265 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
266 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
267 u32 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
269 f
->fmt
.pix
.width
= voutdev
->width
;
270 f
->fmt
.pix
.height
= voutdev
->height
;
271 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
273 if (config
& (1U << 16)) {
274 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_YUYV
;
275 if (config
& (1U << 20)) {
276 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_REC709
;
278 if (config
& (1U << 19))
279 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
281 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
283 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
+ voutdev
->padding
) * 2;
285 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_ABGR32
;
286 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_RAW
;
287 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
+ voutdev
->padding
) * 4;
290 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.bytesperline
* f
->fmt
.pix
.height
;
295 static int vidioc_try_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
297 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
298 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
301 f
->fmt
.pix
.width
= voutdev
->width
;
302 f
->fmt
.pix
.height
= voutdev
->height
;
303 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
305 if (has_yuv(video
) && f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_YUYV
) {
307 if (!(f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_REC709
||
308 f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_SMPTE170M
))
309 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
312 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_ABGR32
;
313 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_RAW
;
316 if (f
->fmt
.pix
.bytesperline
> f
->fmt
.pix
.width
* pixelsize
&&
317 f
->fmt
.pix
.bytesperline
< f
->fmt
.pix
.width
* pixelsize
* 2)
318 f
->fmt
.pix
.bytesperline
= ALIGN(f
->fmt
.pix
.bytesperline
,
321 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
* pixelsize
;
322 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.bytesperline
* f
->fmt
.pix
.height
;
327 static int vidioc_s_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
329 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
330 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
331 u32 config
, pixelsize
;
334 if (vb2_is_busy(&voutdev
->queue
))
337 ret
= vidioc_try_fmt(file
, priv
, f
);
341 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
342 if (f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_YUYV
) {
346 if (f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_REC709
) {
349 } else if (f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_SMPTE170M
) {
350 config
&= ~(1U << 20);
353 config
&= ~(1U << 20);
354 config
&= ~(1U << 19);
358 config
&= ~(1U << 16);
360 mgb4_write_reg(video
, voutdev
->config
->regs
.config
, config
);
362 voutdev
->padding
= (f
->fmt
.pix
.bytesperline
- (f
->fmt
.pix
.width
363 * pixelsize
)) / pixelsize
;
364 mgb4_write_reg(video
, voutdev
->config
->regs
.padding
, voutdev
->padding
);
369 static int vidioc_g_output(struct file
*file
, void *priv
, unsigned int *i
)
375 static int vidioc_s_output(struct file
*file
, void *priv
, unsigned int i
)
377 return i
? -EINVAL
: 0;
380 static int vidioc_enum_output(struct file
*file
, void *priv
,
381 struct v4l2_output
*out
)
386 out
->type
= V4L2_OUTPUT_TYPE_ANALOG
;
387 out
->capabilities
= V4L2_OUT_CAP_DV_TIMINGS
;
388 strscpy(out
->name
, "MGB4", sizeof(out
->name
));
393 static int vidioc_enum_frameintervals(struct file
*file
, void *priv
,
394 struct v4l2_frmivalenum
*ival
)
396 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
397 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
398 struct v4l2_dv_timings timings
;
400 if (ival
->index
!= 0)
402 if (!(ival
->pixel_format
== V4L2_PIX_FMT_ABGR32
||
403 ((has_yuv(video
) && ival
->pixel_format
== V4L2_PIX_FMT_YUYV
))))
405 if (ival
->width
!= voutdev
->width
|| ival
->height
!= voutdev
->height
)
408 get_timings(voutdev
, &timings
);
410 ival
->type
= V4L2_FRMIVAL_TYPE_STEPWISE
;
411 ival
->stepwise
.max
.denominator
= MGB4_HW_FREQ
;
412 ival
->stepwise
.max
.numerator
= 0xFFFFFFFF;
413 ival
->stepwise
.min
.denominator
= timings
.bt
.pixelclock
;
414 ival
->stepwise
.min
.numerator
= pixel_size(&timings
);
415 ival
->stepwise
.step
.denominator
= MGB4_HW_FREQ
;
416 ival
->stepwise
.step
.numerator
= 1;
421 static int vidioc_g_parm(struct file
*file
, void *priv
,
422 struct v4l2_streamparm
*parm
)
424 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
425 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
426 struct v4l2_fract
*tpf
= &parm
->parm
.output
.timeperframe
;
427 struct v4l2_dv_timings timings
;
430 parm
->parm
.output
.writebuffers
= 2;
432 if (has_timeperframe(video
)) {
433 timer
= mgb4_read_reg(video
, voutdev
->config
->regs
.timer
);
434 if (timer
< 0xFFFF) {
435 get_timings(voutdev
, &timings
);
436 tpf
->numerator
= pixel_size(&timings
);
437 tpf
->denominator
= timings
.bt
.pixelclock
;
439 tpf
->numerator
= timer
;
440 tpf
->denominator
= MGB4_HW_FREQ
;
443 parm
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
449 static int vidioc_s_parm(struct file
*file
, void *priv
,
450 struct v4l2_streamparm
*parm
)
452 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
453 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
454 struct v4l2_fract
*tpf
= &parm
->parm
.output
.timeperframe
;
455 struct v4l2_dv_timings timings
;
458 if (has_timeperframe(video
)) {
459 timer
= tpf
->denominator
?
460 MGB4_PERIOD(tpf
->numerator
, tpf
->denominator
) : 0;
462 get_timings(voutdev
, &timings
);
463 period
= MGB4_PERIOD(pixel_size(&timings
),
464 timings
.bt
.pixelclock
);
469 mgb4_write_reg(video
, voutdev
->config
->regs
.timer
, timer
);
472 return vidioc_g_parm(file
, priv
, parm
);
475 static int vidioc_g_dv_timings(struct file
*file
, void *fh
,
476 struct v4l2_dv_timings
*timings
)
478 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
480 get_timings(voutdev
, timings
);
485 static int vidioc_s_dv_timings(struct file
*file
, void *fh
,
486 struct v4l2_dv_timings
*timings
)
488 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
490 get_timings(voutdev
, timings
);
495 static int vidioc_enum_dv_timings(struct file
*file
, void *fh
,
496 struct v4l2_enum_dv_timings
*timings
)
498 return v4l2_enum_dv_timings_cap(timings
, &video_timings_cap
, NULL
, NULL
);
501 static int vidioc_dv_timings_cap(struct file
*file
, void *fh
,
502 struct v4l2_dv_timings_cap
*cap
)
504 *cap
= video_timings_cap
;
509 static const struct v4l2_ioctl_ops video_ioctl_ops
= {
510 .vidioc_querycap
= vidioc_querycap
,
511 .vidioc_enum_fmt_vid_out
= vidioc_enum_fmt
,
512 .vidioc_try_fmt_vid_out
= vidioc_try_fmt
,
513 .vidioc_s_fmt_vid_out
= vidioc_s_fmt
,
514 .vidioc_g_fmt_vid_out
= vidioc_g_fmt
,
515 .vidioc_enum_output
= vidioc_enum_output
,
516 .vidioc_enum_frameintervals
= vidioc_enum_frameintervals
,
517 .vidioc_g_output
= vidioc_g_output
,
518 .vidioc_s_output
= vidioc_s_output
,
519 .vidioc_g_parm
= vidioc_g_parm
,
520 .vidioc_s_parm
= vidioc_s_parm
,
521 .vidioc_dv_timings_cap
= vidioc_dv_timings_cap
,
522 .vidioc_enum_dv_timings
= vidioc_enum_dv_timings
,
523 .vidioc_g_dv_timings
= vidioc_g_dv_timings
,
524 .vidioc_s_dv_timings
= vidioc_s_dv_timings
,
525 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
526 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
527 .vidioc_prepare_buf
= vb2_ioctl_prepare_buf
,
528 .vidioc_querybuf
= vb2_ioctl_querybuf
,
529 .vidioc_qbuf
= vb2_ioctl_qbuf
,
530 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
531 .vidioc_expbuf
= vb2_ioctl_expbuf
,
532 .vidioc_streamon
= vb2_ioctl_streamon
,
533 .vidioc_streamoff
= vb2_ioctl_streamoff
,
536 static int fh_open(struct file
*file
)
538 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
539 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
540 struct device
*dev
= &voutdev
->mgbdev
->pdev
->dev
;
541 u32 config
, resolution
;
544 /* Return EBUSY when the device is in loopback mode */
545 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
546 if ((config
& 0xc) >> 2 != voutdev
->config
->id
+ MGB4_VIN_DEVICES
) {
547 dev_dbg(dev
, "can not open - device in loopback mode");
551 mutex_lock(&voutdev
->lock
);
553 rv
= v4l2_fh_open(file
);
557 if (!v4l2_fh_is_singular_file(file
))
560 resolution
= mgb4_read_reg(video
, voutdev
->config
->regs
.resolution
);
561 voutdev
->width
= resolution
>> 16;
562 voutdev
->height
= resolution
& 0xFFFF;
565 mutex_unlock(&voutdev
->lock
);
569 static const struct v4l2_file_operations video_fops
= {
570 .owner
= THIS_MODULE
,
572 .release
= vb2_fop_release
,
573 .unlocked_ioctl
= video_ioctl2
,
574 .write
= vb2_fop_write
,
575 .mmap
= vb2_fop_mmap
,
576 .poll
= vb2_fop_poll
,
579 static void dma_transfer(struct work_struct
*work
)
581 struct mgb4_vout_dev
*voutdev
= container_of(work
, struct mgb4_vout_dev
,
583 struct device
*dev
= &voutdev
->mgbdev
->pdev
->dev
;
584 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
585 struct mgb4_frame_buffer
*buf
= NULL
;
590 spin_lock_irqsave(&voutdev
->qlock
, flags
);
591 if (!list_empty(&voutdev
->buf_list
)) {
592 buf
= list_first_entry(&voutdev
->buf_list
,
593 struct mgb4_frame_buffer
, list
);
594 list_del_init(voutdev
->buf_list
.next
);
596 spin_unlock_irqrestore(&voutdev
->qlock
, flags
);
601 addr
= mgb4_read_reg(video
, voutdev
->config
->regs
.address
);
602 if (addr
>= MGB4_ERR_QUEUE_FULL
) {
603 dev_dbg(dev
, "frame queue error (%d)\n", (int)addr
);
604 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
608 rv
= mgb4_dma_transfer(voutdev
->mgbdev
, voutdev
->config
->dma_channel
,
610 vb2_dma_sg_plane_desc(&buf
->vb
.vb2_buf
, 0));
612 dev_warn(dev
, "DMA transfer error\n");
613 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
615 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_DONE
);
619 static irqreturn_t
handler(int irq
, void *ctx
)
621 struct mgb4_vout_dev
*voutdev
= (struct mgb4_vout_dev
*)ctx
;
622 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
624 schedule_work(&voutdev
->dma_work
);
626 mgb4_write_reg(video
, 0xB4, 1U << voutdev
->config
->irq
);
631 static int ser_init(struct mgb4_vout_dev
*voutdev
, int id
)
634 const struct i2c_board_info
*info
= &fpdl3_ser_info
[id
];
635 struct mgb4_i2c_client
*ser
= &voutdev
->ser
;
636 struct device
*dev
= &voutdev
->mgbdev
->pdev
->dev
;
638 if (MGB4_IS_GMSL(voutdev
->mgbdev
))
641 rv
= mgb4_i2c_init(ser
, voutdev
->mgbdev
->i2c_adap
, info
, 8);
643 dev_err(dev
, "failed to create serializer\n");
646 rv
= mgb4_i2c_configure(ser
, fpdl3_i2c
, ARRAY_SIZE(fpdl3_i2c
));
648 dev_err(dev
, "failed to configure serializer\n");
660 static void fpga_init(struct mgb4_vout_dev
*voutdev
)
662 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
663 const struct mgb4_vout_regs
*regs
= &voutdev
->config
->regs
;
665 mgb4_write_reg(video
, regs
->config
, 0x00000011);
666 mgb4_write_reg(video
, regs
->resolution
,
667 (DEFAULT_WIDTH
<< 16) | DEFAULT_HEIGHT
);
668 mgb4_write_reg(video
, regs
->hsync
, 0x00283232);
669 mgb4_write_reg(video
, regs
->vsync
, 0x40141F1E);
670 mgb4_write_reg(video
, regs
->frame_limit
, DEFAULT_PERIOD
);
671 mgb4_write_reg(video
, regs
->padding
, 0x00000000);
673 voutdev
->freq
= mgb4_cmt_set_vout_freq(voutdev
, 61150 >> 1) << 1;
675 mgb4_write_reg(video
, regs
->config
,
676 (voutdev
->config
->id
+ MGB4_VIN_DEVICES
) << 2 | 1 << 4);
679 #ifdef CONFIG_DEBUG_FS
680 static void debugfs_init(struct mgb4_vout_dev
*voutdev
)
682 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
684 voutdev
->debugfs
= debugfs_create_dir(voutdev
->vdev
.name
,
685 voutdev
->mgbdev
->debugfs
);
686 if (!voutdev
->debugfs
)
689 voutdev
->regs
[0].name
= "CONFIG";
690 voutdev
->regs
[0].offset
= voutdev
->config
->regs
.config
;
691 voutdev
->regs
[1].name
= "STATUS";
692 voutdev
->regs
[1].offset
= voutdev
->config
->regs
.status
;
693 voutdev
->regs
[2].name
= "RESOLUTION";
694 voutdev
->regs
[2].offset
= voutdev
->config
->regs
.resolution
;
695 voutdev
->regs
[3].name
= "VIDEO_PARAMS_1";
696 voutdev
->regs
[3].offset
= voutdev
->config
->regs
.hsync
;
697 voutdev
->regs
[4].name
= "VIDEO_PARAMS_2";
698 voutdev
->regs
[4].offset
= voutdev
->config
->regs
.vsync
;
699 voutdev
->regs
[5].name
= "FRAME_LIMIT";
700 voutdev
->regs
[5].offset
= voutdev
->config
->regs
.frame_limit
;
701 voutdev
->regs
[6].name
= "PADDING_PIXELS";
702 voutdev
->regs
[6].offset
= voutdev
->config
->regs
.padding
;
703 if (has_timeperframe(video
)) {
704 voutdev
->regs
[7].name
= "TIMER";
705 voutdev
->regs
[7].offset
= voutdev
->config
->regs
.timer
;
706 voutdev
->regset
.nregs
= 8;
708 voutdev
->regset
.nregs
= 7;
711 voutdev
->regset
.base
= video
->membase
;
712 voutdev
->regset
.regs
= voutdev
->regs
;
714 debugfs_create_regset32("registers", 0444, voutdev
->debugfs
,
719 struct mgb4_vout_dev
*mgb4_vout_create(struct mgb4_dev
*mgbdev
, int id
)
722 const struct attribute_group
**groups
;
723 struct mgb4_vout_dev
*voutdev
;
724 struct pci_dev
*pdev
= mgbdev
->pdev
;
725 struct device
*dev
= &pdev
->dev
;
727 voutdev
= kzalloc(sizeof(*voutdev
), GFP_KERNEL
);
731 voutdev
->mgbdev
= mgbdev
;
732 voutdev
->config
= &vout_cfg
[id
];
735 INIT_LIST_HEAD(&voutdev
->buf_list
);
736 spin_lock_init(&voutdev
->qlock
);
738 /* DMA transfer stuff */
739 INIT_WORK(&voutdev
->dma_work
, dma_transfer
);
742 irq
= xdma_get_user_irq(mgbdev
->xdev
, voutdev
->config
->irq
);
743 rv
= request_irq(irq
, handler
, 0, "mgb4-vout", voutdev
);
745 dev_err(dev
, "failed to register irq handler\n");
749 /* Set the FPGA registers default values */
752 /* Set the serializer default values */
753 rv
= ser_init(voutdev
, id
);
757 /* V4L2 stuff init */
758 rv
= v4l2_device_register(dev
, &voutdev
->v4l2dev
);
760 dev_err(dev
, "failed to register v4l2 device\n");
764 mutex_init(&voutdev
->lock
);
766 voutdev
->queue
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT
;
767 voutdev
->queue
.io_modes
= VB2_MMAP
| VB2_DMABUF
| VB2_WRITE
;
768 voutdev
->queue
.buf_struct_size
= sizeof(struct mgb4_frame_buffer
);
769 voutdev
->queue
.ops
= &queue_ops
;
770 voutdev
->queue
.mem_ops
= &vb2_dma_sg_memops
;
771 voutdev
->queue
.gfp_flags
= GFP_DMA32
;
772 voutdev
->queue
.timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
773 voutdev
->queue
.min_queued_buffers
= 2;
774 voutdev
->queue
.drv_priv
= voutdev
;
775 voutdev
->queue
.lock
= &voutdev
->lock
;
776 voutdev
->queue
.dev
= dev
;
777 rv
= vb2_queue_init(&voutdev
->queue
);
779 dev_err(dev
, "failed to initialize vb2 queue\n");
783 snprintf(voutdev
->vdev
.name
, sizeof(voutdev
->vdev
.name
), "mgb4-out%d",
785 voutdev
->vdev
.device_caps
= V4L2_CAP_VIDEO_OUTPUT
| V4L2_CAP_READWRITE
786 | V4L2_CAP_STREAMING
;
787 voutdev
->vdev
.vfl_dir
= VFL_DIR_TX
;
788 voutdev
->vdev
.fops
= &video_fops
;
789 voutdev
->vdev
.ioctl_ops
= &video_ioctl_ops
;
790 voutdev
->vdev
.release
= video_device_release_empty
;
791 voutdev
->vdev
.v4l2_dev
= &voutdev
->v4l2dev
;
792 voutdev
->vdev
.lock
= &voutdev
->lock
;
793 voutdev
->vdev
.queue
= &voutdev
->queue
;
794 video_set_drvdata(&voutdev
->vdev
, voutdev
);
796 rv
= video_register_device(&voutdev
->vdev
, VFL_TYPE_VIDEO
, -1);
798 dev_err(dev
, "failed to register video device\n");
802 /* Module sysfs attributes */
803 groups
= MGB4_IS_GMSL(mgbdev
)
804 ? mgb4_gmsl_out_groups
: mgb4_fpdl3_out_groups
;
805 rv
= device_add_groups(&voutdev
->vdev
.dev
, groups
);
807 dev_err(dev
, "failed to create sysfs attributes\n");
811 #ifdef CONFIG_DEBUG_FS
812 debugfs_init(voutdev
);
818 video_unregister_device(&voutdev
->vdev
);
820 v4l2_device_unregister(&voutdev
->v4l2dev
);
822 free_irq(irq
, voutdev
);
829 void mgb4_vout_free(struct mgb4_vout_dev
*voutdev
)
831 const struct attribute_group
**groups
;
832 int irq
= xdma_get_user_irq(voutdev
->mgbdev
->xdev
, voutdev
->config
->irq
);
834 free_irq(irq
, voutdev
);
836 #ifdef CONFIG_DEBUG_FS
837 debugfs_remove_recursive(voutdev
->debugfs
);
840 groups
= MGB4_IS_GMSL(voutdev
->mgbdev
)
841 ? mgb4_gmsl_out_groups
: mgb4_fpdl3_out_groups
;
842 device_remove_groups(&voutdev
->vdev
.dev
, groups
);
844 mgb4_i2c_free(&voutdev
->ser
);
845 video_unregister_device(&voutdev
->vdev
);
846 v4l2_device_unregister(&voutdev
->v4l2dev
);