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
,
235 static int vidioc_querycap(struct file
*file
, void *priv
,
236 struct v4l2_capability
*cap
)
238 strscpy(cap
->driver
, KBUILD_MODNAME
, sizeof(cap
->driver
));
239 strscpy(cap
->card
, "MGB4 PCIe Card", sizeof(cap
->card
));
244 static int vidioc_enum_fmt(struct file
*file
, void *priv
,
245 struct v4l2_fmtdesc
*f
)
247 struct mgb4_vin_dev
*voutdev
= video_drvdata(file
);
248 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
251 f
->pixelformat
= V4L2_PIX_FMT_ABGR32
;
253 } else if (f
->index
== 1 && has_yuv(video
)) {
254 f
->pixelformat
= V4L2_PIX_FMT_YUYV
;
261 static int vidioc_g_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
263 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
264 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
265 u32 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
267 f
->fmt
.pix
.width
= voutdev
->width
;
268 f
->fmt
.pix
.height
= voutdev
->height
;
269 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
271 if (config
& (1U << 16)) {
272 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_YUYV
;
273 if (config
& (1U << 20)) {
274 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_REC709
;
276 if (config
& (1U << 19))
277 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
279 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
281 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
+ voutdev
->padding
) * 2;
283 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_ABGR32
;
284 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_RAW
;
285 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
+ voutdev
->padding
) * 4;
288 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.bytesperline
* f
->fmt
.pix
.height
;
293 static int vidioc_try_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
295 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
296 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
299 f
->fmt
.pix
.width
= voutdev
->width
;
300 f
->fmt
.pix
.height
= voutdev
->height
;
301 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
303 if (has_yuv(video
) && f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_YUYV
) {
305 if (!(f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_REC709
||
306 f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_SMPTE170M
))
307 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
310 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_ABGR32
;
311 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_RAW
;
314 if (f
->fmt
.pix
.bytesperline
> f
->fmt
.pix
.width
* pixelsize
&&
315 f
->fmt
.pix
.bytesperline
< f
->fmt
.pix
.width
* pixelsize
* 2)
316 f
->fmt
.pix
.bytesperline
= ALIGN(f
->fmt
.pix
.bytesperline
,
319 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
* pixelsize
;
320 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.bytesperline
* f
->fmt
.pix
.height
;
325 static int vidioc_s_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
327 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
328 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
329 u32 config
, pixelsize
;
332 if (vb2_is_busy(&voutdev
->queue
))
335 ret
= vidioc_try_fmt(file
, priv
, f
);
339 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
340 if (f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_YUYV
) {
344 if (f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_REC709
) {
347 } else if (f
->fmt
.pix
.colorspace
== V4L2_COLORSPACE_SMPTE170M
) {
348 config
&= ~(1U << 20);
351 config
&= ~(1U << 20);
352 config
&= ~(1U << 19);
356 config
&= ~(1U << 16);
358 mgb4_write_reg(video
, voutdev
->config
->regs
.config
, config
);
360 voutdev
->padding
= (f
->fmt
.pix
.bytesperline
- (f
->fmt
.pix
.width
361 * pixelsize
)) / pixelsize
;
362 mgb4_write_reg(video
, voutdev
->config
->regs
.padding
, voutdev
->padding
);
367 static int vidioc_g_output(struct file
*file
, void *priv
, unsigned int *i
)
373 static int vidioc_s_output(struct file
*file
, void *priv
, unsigned int i
)
375 return i
? -EINVAL
: 0;
378 static int vidioc_enum_output(struct file
*file
, void *priv
,
379 struct v4l2_output
*out
)
384 out
->type
= V4L2_OUTPUT_TYPE_ANALOG
;
385 out
->capabilities
= V4L2_OUT_CAP_DV_TIMINGS
;
386 strscpy(out
->name
, "MGB4", sizeof(out
->name
));
391 static int vidioc_enum_frameintervals(struct file
*file
, void *priv
,
392 struct v4l2_frmivalenum
*ival
)
394 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
395 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
396 struct v4l2_dv_timings timings
;
398 if (ival
->index
!= 0)
400 if (!(ival
->pixel_format
== V4L2_PIX_FMT_ABGR32
||
401 ((has_yuv(video
) && ival
->pixel_format
== V4L2_PIX_FMT_YUYV
))))
403 if (ival
->width
!= voutdev
->width
|| ival
->height
!= voutdev
->height
)
406 get_timings(voutdev
, &timings
);
408 ival
->type
= V4L2_FRMIVAL_TYPE_STEPWISE
;
409 ival
->stepwise
.max
.denominator
= MGB4_HW_FREQ
;
410 ival
->stepwise
.max
.numerator
= 0xFFFFFFFF;
411 ival
->stepwise
.min
.denominator
= timings
.bt
.pixelclock
;
412 ival
->stepwise
.min
.numerator
= pixel_size(&timings
);
413 ival
->stepwise
.step
.denominator
= MGB4_HW_FREQ
;
414 ival
->stepwise
.step
.numerator
= 1;
419 static int vidioc_g_parm(struct file
*file
, void *priv
,
420 struct v4l2_streamparm
*parm
)
422 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
423 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
424 struct v4l2_fract
*tpf
= &parm
->parm
.output
.timeperframe
;
425 struct v4l2_dv_timings timings
;
428 parm
->parm
.output
.writebuffers
= 2;
430 if (has_timeperframe(video
)) {
431 timer
= mgb4_read_reg(video
, voutdev
->config
->regs
.timer
);
432 if (timer
< 0xFFFF) {
433 get_timings(voutdev
, &timings
);
434 tpf
->numerator
= pixel_size(&timings
);
435 tpf
->denominator
= timings
.bt
.pixelclock
;
437 tpf
->numerator
= timer
;
438 tpf
->denominator
= MGB4_HW_FREQ
;
441 parm
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
447 static int vidioc_s_parm(struct file
*file
, void *priv
,
448 struct v4l2_streamparm
*parm
)
450 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
451 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
452 struct v4l2_fract
*tpf
= &parm
->parm
.output
.timeperframe
;
453 struct v4l2_dv_timings timings
;
456 if (has_timeperframe(video
)) {
457 timer
= tpf
->denominator
?
458 MGB4_PERIOD(tpf
->numerator
, tpf
->denominator
) : 0;
460 get_timings(voutdev
, &timings
);
461 period
= MGB4_PERIOD(pixel_size(&timings
),
462 timings
.bt
.pixelclock
);
467 mgb4_write_reg(video
, voutdev
->config
->regs
.timer
, timer
);
470 return vidioc_g_parm(file
, priv
, parm
);
473 static int vidioc_g_dv_timings(struct file
*file
, void *fh
,
474 struct v4l2_dv_timings
*timings
)
476 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
478 get_timings(voutdev
, timings
);
483 static int vidioc_s_dv_timings(struct file
*file
, void *fh
,
484 struct v4l2_dv_timings
*timings
)
486 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
488 get_timings(voutdev
, timings
);
493 static int vidioc_enum_dv_timings(struct file
*file
, void *fh
,
494 struct v4l2_enum_dv_timings
*timings
)
496 return v4l2_enum_dv_timings_cap(timings
, &video_timings_cap
, NULL
, NULL
);
499 static int vidioc_dv_timings_cap(struct file
*file
, void *fh
,
500 struct v4l2_dv_timings_cap
*cap
)
502 *cap
= video_timings_cap
;
507 static const struct v4l2_ioctl_ops video_ioctl_ops
= {
508 .vidioc_querycap
= vidioc_querycap
,
509 .vidioc_enum_fmt_vid_out
= vidioc_enum_fmt
,
510 .vidioc_try_fmt_vid_out
= vidioc_try_fmt
,
511 .vidioc_s_fmt_vid_out
= vidioc_s_fmt
,
512 .vidioc_g_fmt_vid_out
= vidioc_g_fmt
,
513 .vidioc_enum_output
= vidioc_enum_output
,
514 .vidioc_enum_frameintervals
= vidioc_enum_frameintervals
,
515 .vidioc_g_output
= vidioc_g_output
,
516 .vidioc_s_output
= vidioc_s_output
,
517 .vidioc_g_parm
= vidioc_g_parm
,
518 .vidioc_s_parm
= vidioc_s_parm
,
519 .vidioc_dv_timings_cap
= vidioc_dv_timings_cap
,
520 .vidioc_enum_dv_timings
= vidioc_enum_dv_timings
,
521 .vidioc_g_dv_timings
= vidioc_g_dv_timings
,
522 .vidioc_s_dv_timings
= vidioc_s_dv_timings
,
523 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
524 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
525 .vidioc_prepare_buf
= vb2_ioctl_prepare_buf
,
526 .vidioc_querybuf
= vb2_ioctl_querybuf
,
527 .vidioc_qbuf
= vb2_ioctl_qbuf
,
528 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
529 .vidioc_expbuf
= vb2_ioctl_expbuf
,
530 .vidioc_streamon
= vb2_ioctl_streamon
,
531 .vidioc_streamoff
= vb2_ioctl_streamoff
,
534 static int fh_open(struct file
*file
)
536 struct mgb4_vout_dev
*voutdev
= video_drvdata(file
);
537 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
538 struct device
*dev
= &voutdev
->mgbdev
->pdev
->dev
;
539 u32 config
, resolution
;
542 /* Return EBUSY when the device is in loopback mode */
543 config
= mgb4_read_reg(video
, voutdev
->config
->regs
.config
);
544 if ((config
& 0xc) >> 2 != voutdev
->config
->id
+ MGB4_VIN_DEVICES
) {
545 dev_dbg(dev
, "can not open - device in loopback mode");
549 mutex_lock(&voutdev
->lock
);
551 rv
= v4l2_fh_open(file
);
555 if (!v4l2_fh_is_singular_file(file
))
558 resolution
= mgb4_read_reg(video
, voutdev
->config
->regs
.resolution
);
559 voutdev
->width
= resolution
>> 16;
560 voutdev
->height
= resolution
& 0xFFFF;
563 mutex_unlock(&voutdev
->lock
);
567 static const struct v4l2_file_operations video_fops
= {
568 .owner
= THIS_MODULE
,
570 .release
= vb2_fop_release
,
571 .unlocked_ioctl
= video_ioctl2
,
572 .write
= vb2_fop_write
,
573 .mmap
= vb2_fop_mmap
,
574 .poll
= vb2_fop_poll
,
577 static void dma_transfer(struct work_struct
*work
)
579 struct mgb4_vout_dev
*voutdev
= container_of(work
, struct mgb4_vout_dev
,
581 struct device
*dev
= &voutdev
->mgbdev
->pdev
->dev
;
582 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
583 struct mgb4_frame_buffer
*buf
= NULL
;
588 spin_lock_irqsave(&voutdev
->qlock
, flags
);
589 if (!list_empty(&voutdev
->buf_list
)) {
590 buf
= list_first_entry(&voutdev
->buf_list
,
591 struct mgb4_frame_buffer
, list
);
592 list_del_init(voutdev
->buf_list
.next
);
594 spin_unlock_irqrestore(&voutdev
->qlock
, flags
);
599 addr
= mgb4_read_reg(video
, voutdev
->config
->regs
.address
);
600 if (addr
>= MGB4_ERR_QUEUE_FULL
) {
601 dev_dbg(dev
, "frame queue error (%d)\n", (int)addr
);
602 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
606 rv
= mgb4_dma_transfer(voutdev
->mgbdev
, voutdev
->config
->dma_channel
,
608 vb2_dma_sg_plane_desc(&buf
->vb
.vb2_buf
, 0));
610 dev_warn(dev
, "DMA transfer error\n");
611 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
613 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_DONE
);
617 static irqreturn_t
handler(int irq
, void *ctx
)
619 struct mgb4_vout_dev
*voutdev
= (struct mgb4_vout_dev
*)ctx
;
620 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
622 schedule_work(&voutdev
->dma_work
);
624 mgb4_write_reg(video
, 0xB4, 1U << voutdev
->config
->irq
);
629 static int ser_init(struct mgb4_vout_dev
*voutdev
, int id
)
632 const struct i2c_board_info
*info
= &fpdl3_ser_info
[id
];
633 struct mgb4_i2c_client
*ser
= &voutdev
->ser
;
634 struct device
*dev
= &voutdev
->mgbdev
->pdev
->dev
;
636 if (MGB4_IS_GMSL(voutdev
->mgbdev
))
639 rv
= mgb4_i2c_init(ser
, voutdev
->mgbdev
->i2c_adap
, info
, 8);
641 dev_err(dev
, "failed to create serializer\n");
644 rv
= mgb4_i2c_configure(ser
, fpdl3_i2c
, ARRAY_SIZE(fpdl3_i2c
));
646 dev_err(dev
, "failed to configure serializer\n");
658 static void fpga_init(struct mgb4_vout_dev
*voutdev
)
660 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
661 const struct mgb4_vout_regs
*regs
= &voutdev
->config
->regs
;
663 mgb4_write_reg(video
, regs
->config
, 0x00000011);
664 mgb4_write_reg(video
, regs
->resolution
,
665 (DEFAULT_WIDTH
<< 16) | DEFAULT_HEIGHT
);
666 mgb4_write_reg(video
, regs
->hsync
, 0x00283232);
667 mgb4_write_reg(video
, regs
->vsync
, 0x40141F1E);
668 mgb4_write_reg(video
, regs
->frame_limit
, DEFAULT_PERIOD
);
669 mgb4_write_reg(video
, regs
->padding
, 0x00000000);
671 voutdev
->freq
= mgb4_cmt_set_vout_freq(voutdev
, 61150 >> 1) << 1;
673 mgb4_write_reg(video
, regs
->config
,
674 (voutdev
->config
->id
+ MGB4_VIN_DEVICES
) << 2 | 1 << 4);
677 static void create_debugfs(struct mgb4_vout_dev
*voutdev
)
679 #ifdef CONFIG_DEBUG_FS
680 struct mgb4_regs
*video
= &voutdev
->mgbdev
->video
;
681 struct dentry
*entry
;
683 if (IS_ERR_OR_NULL(voutdev
->mgbdev
->debugfs
))
685 entry
= debugfs_create_dir(voutdev
->vdev
.name
, voutdev
->mgbdev
->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, entry
, &voutdev
->regset
);
718 struct mgb4_vout_dev
*mgb4_vout_create(struct mgb4_dev
*mgbdev
, int id
)
721 const struct attribute_group
**groups
;
722 struct mgb4_vout_dev
*voutdev
;
723 struct pci_dev
*pdev
= mgbdev
->pdev
;
724 struct device
*dev
= &pdev
->dev
;
726 voutdev
= kzalloc(sizeof(*voutdev
), GFP_KERNEL
);
730 voutdev
->mgbdev
= mgbdev
;
731 voutdev
->config
= &vout_cfg
[id
];
734 INIT_LIST_HEAD(&voutdev
->buf_list
);
735 spin_lock_init(&voutdev
->qlock
);
737 /* DMA transfer stuff */
738 INIT_WORK(&voutdev
->dma_work
, dma_transfer
);
741 irq
= xdma_get_user_irq(mgbdev
->xdev
, voutdev
->config
->irq
);
742 rv
= request_irq(irq
, handler
, 0, "mgb4-vout", voutdev
);
744 dev_err(dev
, "failed to register irq handler\n");
748 /* Set the FPGA registers default values */
751 /* Set the serializer default values */
752 rv
= ser_init(voutdev
, id
);
756 /* V4L2 stuff init */
757 rv
= v4l2_device_register(dev
, &voutdev
->v4l2dev
);
759 dev_err(dev
, "failed to register v4l2 device\n");
763 mutex_init(&voutdev
->lock
);
765 voutdev
->queue
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT
;
766 voutdev
->queue
.io_modes
= VB2_MMAP
| VB2_DMABUF
| VB2_WRITE
;
767 voutdev
->queue
.buf_struct_size
= sizeof(struct mgb4_frame_buffer
);
768 voutdev
->queue
.ops
= &queue_ops
;
769 voutdev
->queue
.mem_ops
= &vb2_dma_sg_memops
;
770 voutdev
->queue
.gfp_flags
= GFP_DMA32
;
771 voutdev
->queue
.timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
772 voutdev
->queue
.min_queued_buffers
= 2;
773 voutdev
->queue
.drv_priv
= voutdev
;
774 voutdev
->queue
.lock
= &voutdev
->lock
;
775 voutdev
->queue
.dev
= dev
;
776 rv
= vb2_queue_init(&voutdev
->queue
);
778 dev_err(dev
, "failed to initialize vb2 queue\n");
782 snprintf(voutdev
->vdev
.name
, sizeof(voutdev
->vdev
.name
), "mgb4-out%d",
784 voutdev
->vdev
.device_caps
= V4L2_CAP_VIDEO_OUTPUT
| V4L2_CAP_READWRITE
785 | V4L2_CAP_STREAMING
;
786 voutdev
->vdev
.vfl_dir
= VFL_DIR_TX
;
787 voutdev
->vdev
.fops
= &video_fops
;
788 voutdev
->vdev
.ioctl_ops
= &video_ioctl_ops
;
789 voutdev
->vdev
.release
= video_device_release_empty
;
790 voutdev
->vdev
.v4l2_dev
= &voutdev
->v4l2dev
;
791 voutdev
->vdev
.lock
= &voutdev
->lock
;
792 voutdev
->vdev
.queue
= &voutdev
->queue
;
793 video_set_drvdata(&voutdev
->vdev
, voutdev
);
795 rv
= video_register_device(&voutdev
->vdev
, VFL_TYPE_VIDEO
, -1);
797 dev_err(dev
, "failed to register video device\n");
801 /* Module sysfs attributes */
802 groups
= MGB4_IS_GMSL(mgbdev
)
803 ? mgb4_gmsl_out_groups
: mgb4_fpdl3_out_groups
;
804 rv
= device_add_groups(&voutdev
->vdev
.dev
, groups
);
806 dev_err(dev
, "failed to create sysfs attributes\n");
810 create_debugfs(voutdev
);
815 video_unregister_device(&voutdev
->vdev
);
817 v4l2_device_unregister(&voutdev
->v4l2dev
);
819 free_irq(irq
, voutdev
);
826 void mgb4_vout_free(struct mgb4_vout_dev
*voutdev
)
828 const struct attribute_group
**groups
;
829 int irq
= xdma_get_user_irq(voutdev
->mgbdev
->xdev
, voutdev
->config
->irq
);
831 free_irq(irq
, voutdev
);
833 groups
= MGB4_IS_GMSL(voutdev
->mgbdev
)
834 ? mgb4_gmsl_out_groups
: mgb4_fpdl3_out_groups
;
835 device_remove_groups(&voutdev
->vdev
.dev
, groups
);
837 mgb4_i2c_free(&voutdev
->ser
);
838 video_unregister_device(&voutdev
->vdev
);
839 v4l2_device_unregister(&voutdev
->v4l2dev
);