1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. */
3
4 #include <linux/delay.h>
5 #include <linux/pm_runtime.h>
6 #include <media/v4l2-common.h>
7 #include <media/v4l2-event.h>
8 #include <media/v4l2-fh.h>
9 #include <media/v4l2-ioctl.h>
10 #include <media/v4l2-subdev.h>
11 #include <media/videobuf2-dma-contig.h>
12 #include <linux/dma-iommu.h>
13 #include "dev.h"
14 #include "regs.h"
15
16 #define CIF_ISP_REQ_BUFS_MIN 1
17
18 static const struct capture_fmt dmarx_fmts[] = {
19 /* bayer raw */
20 {
21 .fourcc = V4L2_PIX_FMT_SRGGB8,
22 .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
23 .fmt_type = FMT_BAYER,
24 .bpp = { 8 },
25 .mplanes = 1,
26 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
27 .output_format = CIF_MI_DMA_CTRL_RGB_BAYER_8BIT,
28 }, {
29 .fourcc = V4L2_PIX_FMT_SGRBG8,
30 .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
31 .fmt_type = FMT_BAYER,
32 .bpp = { 8 },
33 .mplanes = 1,
34 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
35 .output_format = CIF_MI_DMA_CTRL_RGB_BAYER_8BIT,
36 }, {
37 .fourcc = V4L2_PIX_FMT_SGBRG8,
38 .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
39 .fmt_type = FMT_BAYER,
40 .bpp = { 8 },
41 .mplanes = 1,
42 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
43 .output_format = CIF_MI_DMA_CTRL_RGB_BAYER_8BIT,
44 }, {
45 .fourcc = V4L2_PIX_FMT_SBGGR8,
46 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
47 .fmt_type = FMT_BAYER,
48 .bpp = { 8 },
49 .mplanes = 1,
50 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
51 .output_format = CIF_MI_DMA_CTRL_RGB_BAYER_8BIT,
52 }, { /* 12bit used, 4 lower bits of LSB unused */
53 .fourcc = V4L2_PIX_FMT_SBGGR16,
54 .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
55 .fmt_type = FMT_BAYER,
56 .bpp = { 16 },
57 .mplanes = 1,
58 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
59 .output_format = CIF_MI_DMA_CTRL_RGB_BAYER_16BIT,
60 }, {
61 .fourcc = V4L2_PIX_FMT_YUYV,
62 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
63 .fmt_type = FMT_YUV,
64 .bpp = { 16 },
65 .cplanes = 1,
66 .mplanes = 1,
67 .uv_swap = 0,
68 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
69 .output_format = CIF_MI_DMA_CTRL_FMT_YUV422,
70 }, {
71 .fourcc = V4L2_PIX_FMT_YVYU,
72 .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
73 .fmt_type = FMT_YUV,
74 .bpp = { 16 },
75 .cplanes = 1,
76 .mplanes = 1,
77 .uv_swap = 0,
78 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
79 .output_format = CIF_MI_DMA_CTRL_FMT_YUV422,
80 }, {
81 .fourcc = V4L2_PIX_FMT_UYVY,
82 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
83 .fmt_type = FMT_YUV,
84 .bpp = { 16 },
85 .cplanes = 1,
86 .mplanes = 1,
87 .uv_swap = 0,
88 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
89 .output_format = CIF_MI_DMA_CTRL_FMT_YUV422,
90 }, {
91 .fourcc = V4L2_PIX_FMT_VYUY,
92 .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
93 .fmt_type = FMT_YUV,
94 .bpp = { 16 },
95 .cplanes = 1,
96 .mplanes = 1,
97 .uv_swap = 0,
98 .write_format = CIF_MI_DMA_CTRL_READ_FMT_PACKED,
99 .output_format = CIF_MI_DMA_CTRL_FMT_YUV422,
100 }
101 };
102
103 static struct stream_config rkisp1_dmarx_stream_config = {
104 .fmts = dmarx_fmts,
105 .fmt_size = ARRAY_SIZE(dmarx_fmts),
106 .mi = {
107 .y_size_init = CIF_MI_DMA_Y_PIC_SIZE,
108 .y_base_ad_init = CIF_MI_DMA_Y_PIC_START_AD,
109 .cb_base_ad_init = CIF_MI_DMA_CB_PIC_START_AD,
110 .cr_base_ad_init = CIF_MI_DMA_CR_PIC_START_AD,
111 },
112 };
113
114 static const
find_fmt(struct rkisp1_stream * stream,const u32 pixelfmt)115 struct capture_fmt *find_fmt(struct rkisp1_stream *stream,
116 const u32 pixelfmt)
117 {
118 const struct capture_fmt *fmt;
119 int i;
120
121 for (i = 0; i < stream->config->fmt_size; i++) {
122 fmt = &stream->config->fmts[i];
123 if (fmt->fourcc == pixelfmt)
124 return fmt;
125 }
126 return NULL;
127 }
128
dmarx_config_mi(struct rkisp1_stream * stream)129 static int dmarx_config_mi(struct rkisp1_stream *stream)
130 {
131 struct rkisp1_device *dev = stream->ispdev;
132 void __iomem *base = dev->base_addr;
133 struct capture_fmt *dmarx_in_fmt = &stream->out_isp_fmt;
134
135 v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev,
136 "%s %dx%x y_stride:%d\n", __func__,
137 stream->out_fmt.width,
138 stream->out_fmt.height,
139 stream->u.dmarx.y_stride);
140
141 mi_set_y_size(stream, stream->out_fmt.width *
142 stream->out_fmt.height);
143 dmarx_set_y_width(base, stream->out_fmt.width);
144 dmarx_set_y_line_length(base, stream->u.dmarx.y_stride);
145
146 mi_dmarx_ready_enable(stream);
147 if (dmarx_in_fmt->uv_swap)
148 dmarx_set_uv_swap(base);
149
150 dmarx_ctrl(base,
151 dmarx_in_fmt->write_format |
152 dmarx_in_fmt->output_format |
153 CIF_MI_DMA_CTRL_BURST_LEN_LUM_16 |
154 CIF_MI_DMA_CTRL_BURST_LEN_CHROM_16);
155 return 0;
156 }
157
update_dmarx(struct rkisp1_stream * stream)158 static void update_dmarx(struct rkisp1_stream *stream)
159 {
160 void __iomem *base = stream->ispdev->base_addr;
161
162 if (stream->curr_buf) {
163 mi_set_y_addr(stream,
164 stream->curr_buf->buff_addr[RKISP1_PLANE_Y]);
165 mi_set_cb_addr(stream,
166 stream->curr_buf->buff_addr[RKISP1_PLANE_CB]);
167 mi_set_cr_addr(stream,
168 stream->curr_buf->buff_addr[RKISP1_PLANE_CR]);
169 mi_dmarx_start(base);
170 stream->frame_end = false;
171 }
172 }
173
dmarx_stop_mi(struct rkisp1_stream * stream)174 static void dmarx_stop_mi(struct rkisp1_stream *stream)
175 {
176 mi_dmarx_ready_disable(stream);
177 }
178
179 static struct streams_ops rkisp1_dmarx_streams_ops = {
180 .config_mi = dmarx_config_mi,
181 .stop_mi = dmarx_stop_mi,
182 .update_mi = update_dmarx,
183 };
184
dmarx_frame_end(struct rkisp1_stream * stream)185 static int dmarx_frame_end(struct rkisp1_stream *stream)
186 {
187 unsigned long lock_flags = 0;
188
189 if (stream->curr_buf) {
190 vb2_buffer_done(&stream->curr_buf->vb.vb2_buf,
191 VB2_BUF_STATE_DONE);
192 stream->curr_buf = NULL;
193 }
194
195 spin_lock_irqsave(&stream->vbq_lock, lock_flags);
196 if (!list_empty(&stream->buf_queue)) {
197 stream->curr_buf =
198 list_first_entry(&stream->buf_queue,
199 struct rkisp1_buffer,
200 queue);
201 list_del(&stream->curr_buf->queue);
202 }
203 spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
204
205 stream->ops->update_mi(stream);
206 return 0;
207 }
208
209 /***************************** vb2 operations*******************************/
210
dmarx_stop(struct rkisp1_stream * stream)211 static void dmarx_stop(struct rkisp1_stream *stream)
212 {
213 struct rkisp1_device *dev = stream->ispdev;
214 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
215 int ret = 0;
216
217 stream->stopping = true;
218 if (dev->isp_state == ISP_START &&
219 !stream->frame_end) {
220 ret = wait_event_timeout(stream->done,
221 !stream->streaming,
222 msecs_to_jiffies(500));
223 if (!ret)
224 v4l2_warn(v4l2_dev,
225 "dmarx:%d waiting on event return error %d\n",
226 stream->id, ret);
227 }
228 if (stream->ops->stop_mi)
229 stream->ops->stop_mi(stream);
230 stream->stopping = false;
231 stream->streaming = false;
232 stream->frame_end = false;
233 }
234
dmarx_start(struct rkisp1_stream * stream)235 static int dmarx_start(struct rkisp1_stream *stream)
236 {
237 int ret;
238
239 ret = stream->ops->config_mi(stream);
240 if (ret)
241 return ret;
242
243 stream->curr_buf = NULL;
244 dmarx_frame_end(stream);
245 stream->streaming = true;
246 return 0;
247 }
248
rkisp1_queue_setup(struct vb2_queue * queue,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],struct device * alloc_ctxs[])249 static int rkisp1_queue_setup(struct vb2_queue *queue,
250 unsigned int *num_buffers,
251 unsigned int *num_planes,
252 unsigned int sizes[],
253 struct device *alloc_ctxs[])
254 {
255 struct rkisp1_stream *stream = queue->drv_priv;
256 struct rkisp1_device *dev = stream->ispdev;
257 const struct v4l2_pix_format_mplane *pixm = NULL;
258 const struct capture_fmt *isp_fmt = NULL;
259 u32 i;
260
261 pixm = &stream->out_fmt;
262 isp_fmt = &stream->out_isp_fmt;
263
264 *num_planes = isp_fmt->mplanes;
265
266 for (i = 0; i < isp_fmt->mplanes; i++) {
267 const struct v4l2_plane_pix_format *plane_fmt;
268
269 plane_fmt = &pixm->plane_fmt[i];
270 sizes[i] = plane_fmt->sizeimage;
271 }
272
273 v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev, "%s count %d, size %d\n",
274 v4l2_type_names[queue->type], *num_buffers, sizes[0]);
275
276 return 0;
277 }
278
279 /*
280 * The vb2_buffer are stored in rkisp1_buffer, in order to unify
281 * mplane buffer and none-mplane buffer.
282 */
rkisp1_buf_queue(struct vb2_buffer * vb)283 static void rkisp1_buf_queue(struct vb2_buffer *vb)
284 {
285 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
286 struct rkisp1_buffer *ispbuf = to_rkisp1_buffer(vbuf);
287 struct vb2_queue *queue = vb->vb2_queue;
288 struct rkisp1_stream *stream = queue->drv_priv;
289 unsigned long lock_flags = 0;
290 struct v4l2_pix_format_mplane *pixm = &stream->out_fmt;
291 struct capture_fmt *isp_fmt = &stream->out_isp_fmt;
292 int i;
293
294 memset(ispbuf->buff_addr, 0, sizeof(ispbuf->buff_addr));
295 for (i = 0; i < isp_fmt->mplanes; i++)
296 ispbuf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
297
298 /*
299 * NOTE: plane_fmt[0].sizeimage is total size of all planes for single
300 * memory plane formats, so calculate the size explicitly.
301 */
302 if (isp_fmt->mplanes == 1) {
303 for (i = 0; i < isp_fmt->cplanes - 1; i++) {
304 ispbuf->buff_addr[i + 1] = (i == 0) ?
305 ispbuf->buff_addr[i] +
306 pixm->plane_fmt[i].bytesperline *
307 pixm->height :
308 ispbuf->buff_addr[i] +
309 pixm->plane_fmt[i].sizeimage;
310 }
311 }
312
313 spin_lock_irqsave(&stream->vbq_lock, lock_flags);
314 if (stream->streaming &&
315 list_empty(&stream->buf_queue) &&
316 !stream->curr_buf) {
317 stream->curr_buf = ispbuf;
318 stream->ops->update_mi(stream);
319 } else {
320 list_add_tail(&ispbuf->queue, &stream->buf_queue);
321 }
322 spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
323 }
324
dmarx_stop_streaming(struct vb2_queue * queue)325 static void dmarx_stop_streaming(struct vb2_queue *queue)
326 {
327 struct rkisp1_stream *stream = queue->drv_priv;
328 struct rkisp1_buffer *buf;
329 unsigned long lock_flags = 0;
330
331 dmarx_stop(stream);
332
333 spin_lock_irqsave(&stream->vbq_lock, lock_flags);
334 if (stream->curr_buf) {
335 list_add_tail(&stream->curr_buf->queue, &stream->buf_queue);
336 stream->curr_buf = NULL;
337 }
338 while (!list_empty(&stream->buf_queue)) {
339 buf = list_first_entry(&stream->buf_queue,
340 struct rkisp1_buffer, queue);
341 list_del(&buf->queue);
342 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
343 }
344 spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
345 }
346
dmarx_start_streaming(struct vb2_queue * queue,unsigned int count)347 static int dmarx_start_streaming(struct vb2_queue *queue,
348 unsigned int count)
349 {
350 struct rkisp1_stream *stream = queue->drv_priv;
351 struct rkisp1_device *dev = stream->ispdev;
352 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
353 int ret = 0;
354
355 if (atomic_read(&dev->open_cnt) < 2) {
356 v4l2_err(v4l2_dev,
357 "other stream should enable first\n");
358 return -EINVAL;
359 }
360
361 if (WARN_ON(stream->streaming))
362 return -EBUSY;
363
364 ret = dmarx_start(stream);
365 if (ret < 0)
366 v4l2_err(v4l2_dev,
367 "start dmarx stream:%d failed\n",
368 stream->id);
369
370 return ret;
371 }
372
373 static struct vb2_ops dmarx_vb2_ops = {
374 .queue_setup = rkisp1_queue_setup,
375 .buf_queue = rkisp1_buf_queue,
376 .wait_prepare = vb2_ops_wait_prepare,
377 .wait_finish = vb2_ops_wait_finish,
378 .stop_streaming = dmarx_stop_streaming,
379 .start_streaming = dmarx_start_streaming,
380 };
381
rkisp_init_vb2_queue(struct vb2_queue * q,struct rkisp1_stream * stream,enum v4l2_buf_type buf_type)382 static int rkisp_init_vb2_queue(struct vb2_queue *q,
383 struct rkisp1_stream *stream,
384 enum v4l2_buf_type buf_type)
385 {
386 q->type = buf_type;
387 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
388 q->drv_priv = stream;
389 q->ops = &dmarx_vb2_ops;
390 q->mem_ops = &vb2_dma_contig_memops;
391 q->buf_struct_size = sizeof(struct rkisp1_buffer);
392 q->min_buffers_needed = CIF_ISP_REQ_BUFS_MIN;
393 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
394 q->lock = &stream->ispdev->apilock;
395
396 return vb2_queue_init(q);
397 }
398
rkisp1_set_fmt(struct rkisp1_stream * stream,struct v4l2_pix_format_mplane * pixm,bool try)399 static int rkisp1_set_fmt(struct rkisp1_stream *stream,
400 struct v4l2_pix_format_mplane *pixm,
401 bool try)
402 {
403 const struct capture_fmt *fmt;
404 unsigned int imagsize = 0;
405 unsigned int planes;
406 u32 xsubs = 1, ysubs = 1;
407 unsigned int i;
408
409 fmt = find_fmt(stream, pixm->pixelformat);
410 if (!fmt) {
411 v4l2_err(&stream->ispdev->v4l2_dev,
412 "nonsupport pixelformat:%c%c%c%c\n",
413 pixm->pixelformat,
414 pixm->pixelformat >> 8,
415 pixm->pixelformat >> 16,
416 pixm->pixelformat >> 24);
417 return -EINVAL;
418 }
419
420 pixm->num_planes = fmt->mplanes;
421 pixm->field = V4L2_FIELD_NONE;
422 if (!pixm->quantization)
423 pixm->quantization = V4L2_QUANTIZATION_FULL_RANGE;
424
425 /* calculate size */
426 fcc_xysubs(fmt->fourcc, &xsubs, &ysubs);
427 planes = fmt->cplanes ? fmt->cplanes : fmt->mplanes;
428 for (i = 0; i < planes; i++) {
429 struct v4l2_plane_pix_format *plane_fmt;
430 unsigned int width, height, bytesperline;
431
432 plane_fmt = pixm->plane_fmt + i;
433
434 if (i == 0) {
435 width = pixm->width;
436 height = pixm->height;
437 } else {
438 width = pixm->width / xsubs;
439 height = pixm->height / ysubs;
440 }
441
442 bytesperline = width * DIV_ROUND_UP(fmt->bpp[i], 8);
443 /* stride is only available for sp stream and y plane */
444 if (i != 0 ||
445 plane_fmt->bytesperline < bytesperline)
446 plane_fmt->bytesperline = bytesperline;
447
448 plane_fmt->sizeimage = plane_fmt->bytesperline * height;
449
450 imagsize += plane_fmt->sizeimage;
451 }
452
453 /* convert to non-MPLANE format.
454 * it's important since we want to unify none-MPLANE
455 * and MPLANE.
456 */
457 if (fmt->mplanes == 1)
458 pixm->plane_fmt[0].sizeimage = imagsize;
459
460 if (!try) {
461 stream->out_isp_fmt = *fmt;
462 stream->out_fmt = *pixm;
463
464 stream->u.dmarx.y_stride =
465 pixm->plane_fmt[0].bytesperline /
466 DIV_ROUND_UP(fmt->bpp[0], 8);
467
468 v4l2_dbg(1, rkisp1_debug, &stream->ispdev->v4l2_dev,
469 "%s: stream: %d req(%d, %d) out(%d, %d)\n", __func__,
470 stream->id, pixm->width, pixm->height,
471 stream->out_fmt.width, stream->out_fmt.height);
472 }
473
474 return 0;
475 }
476
477 /************************* v4l2_file_operations***************************/
478
479 static const struct v4l2_file_operations rkisp1_fops = {
480 .open = rkisp1_fh_open,
481 .release = rkisp1_fop_release,
482 .unlocked_ioctl = video_ioctl2,
483 .poll = vb2_fop_poll,
484 .mmap = vb2_fop_mmap,
485 };
486
rkisp1_try_fmt_vid_out_mplane(struct file * file,void * fh,struct v4l2_format * f)487 static int rkisp1_try_fmt_vid_out_mplane(struct file *file, void *fh,
488 struct v4l2_format *f)
489 {
490 struct rkisp1_stream *stream = video_drvdata(file);
491
492 return rkisp1_set_fmt(stream, &f->fmt.pix_mp, true);
493 }
494
rkisp1_enum_fmt_vid_out_mplane(struct file * file,void * priv,struct v4l2_fmtdesc * f)495 static int rkisp1_enum_fmt_vid_out_mplane(struct file *file, void *priv,
496 struct v4l2_fmtdesc *f)
497 {
498 struct rkisp1_stream *stream = video_drvdata(file);
499 const struct capture_fmt *fmt = NULL;
500
501 if (f->index >= stream->config->fmt_size)
502 return -EINVAL;
503
504 fmt = &stream->config->fmts[f->index];
505 f->pixelformat = fmt->fourcc;
506
507 return 0;
508 }
509
rkisp1_s_fmt_vid_out_mplane(struct file * file,void * priv,struct v4l2_format * f)510 static int rkisp1_s_fmt_vid_out_mplane(struct file *file,
511 void *priv, struct v4l2_format *f)
512 {
513 struct rkisp1_stream *stream = video_drvdata(file);
514 struct video_device *vdev = &stream->vnode.vdev;
515 struct rkisp1_vdev_node *node = vdev_to_node(vdev);
516 struct rkisp1_device *dev = stream->ispdev;
517
518 if (vb2_is_busy(&node->buf_queue)) {
519 v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
520 return -EBUSY;
521 }
522
523 return rkisp1_set_fmt(stream, &f->fmt.pix_mp, false);
524 }
525
rkisp1_g_fmt_vid_out_mplane(struct file * file,void * fh,struct v4l2_format * f)526 static int rkisp1_g_fmt_vid_out_mplane(struct file *file, void *fh,
527 struct v4l2_format *f)
528 {
529 struct rkisp1_stream *stream = video_drvdata(file);
530
531 f->fmt.pix_mp = stream->out_fmt;
532
533 return 0;
534 }
535
rkisp1_querycap(struct file * file,void * priv,struct v4l2_capability * cap)536 static int rkisp1_querycap(struct file *file, void *priv,
537 struct v4l2_capability *cap)
538 {
539 struct rkisp1_stream *stream = video_drvdata(file);
540 struct device *dev = stream->ispdev->dev;
541 struct video_device *vdev = video_devdata(file);
542
543 strlcpy(cap->card, vdev->name, sizeof(cap->card));
544 snprintf(cap->driver, sizeof(cap->driver),
545 "%s_v%d", dev->driver->name,
546 stream->ispdev->isp_ver >> 4);
547 snprintf(cap->bus_info, sizeof(cap->bus_info),
548 "platform:%s", dev_name(dev));
549
550 return 0;
551 }
552
553 static const struct v4l2_ioctl_ops rkisp1_dmarx_ioctl = {
554 .vidioc_reqbufs = vb2_ioctl_reqbufs,
555 .vidioc_querybuf = vb2_ioctl_querybuf,
556 .vidioc_create_bufs = vb2_ioctl_create_bufs,
557 .vidioc_qbuf = vb2_ioctl_qbuf,
558 .vidioc_expbuf = vb2_ioctl_expbuf,
559 .vidioc_dqbuf = vb2_ioctl_dqbuf,
560 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
561 .vidioc_streamon = vb2_ioctl_streamon,
562 .vidioc_streamoff = vb2_ioctl_streamoff,
563 .vidioc_try_fmt_vid_out_mplane = rkisp1_try_fmt_vid_out_mplane,
564 .vidioc_enum_fmt_vid_out = rkisp1_enum_fmt_vid_out_mplane,
565 .vidioc_s_fmt_vid_out_mplane = rkisp1_s_fmt_vid_out_mplane,
566 .vidioc_g_fmt_vid_out_mplane = rkisp1_g_fmt_vid_out_mplane,
567 .vidioc_querycap = rkisp1_querycap,
568 };
569
rkisp1_unregister_dmarx_video(struct rkisp1_stream * stream)570 static void rkisp1_unregister_dmarx_video(struct rkisp1_stream *stream)
571 {
572 media_entity_cleanup(&stream->vnode.vdev.entity);
573 video_unregister_device(&stream->vnode.vdev);
574 }
575
rkisp1_register_dmarx_video(struct rkisp1_stream * stream)576 static int rkisp1_register_dmarx_video(struct rkisp1_stream *stream)
577 {
578 struct rkisp1_device *dev = stream->ispdev;
579 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
580 struct video_device *vdev = &stream->vnode.vdev;
581 struct rkisp1_vdev_node *node;
582 int ret = 0;
583
584 node = vdev_to_node(vdev);
585
586 vdev->release = video_device_release_empty;
587 vdev->fops = &rkisp1_fops;
588 vdev->minor = -1;
589 vdev->v4l2_dev = v4l2_dev;
590 vdev->lock = &dev->apilock;
591 video_set_drvdata(vdev, stream);
592
593 vdev->ioctl_ops = &rkisp1_dmarx_ioctl;
594 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
595 V4L2_CAP_STREAMING;
596 vdev->vfl_dir = VFL_DIR_TX;
597 node->pad.flags = MEDIA_PAD_FL_SOURCE;
598
599 rkisp_init_vb2_queue(&node->buf_queue, stream,
600 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
601 vdev->queue = &node->buf_queue;
602
603 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
604 if (ret < 0) {
605 v4l2_err(v4l2_dev,
606 "video register failed with error %d\n", ret);
607 return ret;
608 }
609
610 ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
611 if (ret < 0)
612 goto unreg;
613
614 return 0;
615 unreg:
616 video_unregister_device(vdev);
617 return ret;
618 }
619
620 /**************** Interrupter Handler ****************/
621
rkisp1_dmarx_isr(u32 mis_val,struct rkisp1_device * dev)622 void rkisp1_dmarx_isr(u32 mis_val, struct rkisp1_device *dev)
623 {
624 void __iomem *base = dev->base_addr;
625 struct rkisp1_stream *stream;
626
627 if (mis_val & CIF_MI_DMA_READY) {
628 stream = &dev->dmarx_dev.stream[RKISP1_STREAM_DMARX];
629 stream->frame_end = true;
630 writel(CIF_MI_DMA_READY, base + CIF_MI_ICR);
631
632 if (stream->stopping) {
633 stream->stopping = false;
634 stream->streaming = false;
635 wake_up(&stream->done);
636 } else {
637 dmarx_frame_end(stream);
638 }
639 }
640 }
641
rkisp1_register_dmarx_vdev(struct rkisp1_device * dev)642 int rkisp1_register_dmarx_vdev(struct rkisp1_device *dev)
643 {
644 struct rkisp1_dmarx_device *dmarx_dev = &dev->dmarx_dev;
645 struct rkisp1_stream *stream;
646 struct video_device *vdev;
647 struct media_entity *source, *sink;
648 int ret = 0;
649
650 memset(dmarx_dev, 0, sizeof(*dmarx_dev));
651 dmarx_dev->ispdev = dev;
652
653 if (dev->isp_ver <= ISP_V13) {
654 stream = &dmarx_dev->stream[RKISP1_STREAM_DMARX];
655 INIT_LIST_HEAD(&stream->buf_queue);
656 init_waitqueue_head(&stream->done);
657 spin_lock_init(&stream->vbq_lock);
658 stream->id = RKISP1_STREAM_DMARX;
659 stream->ispdev = dev;
660 stream->ops = &rkisp1_dmarx_streams_ops;
661 stream->config = &rkisp1_dmarx_stream_config;
662 vdev = &stream->vnode.vdev;
663 strlcpy(vdev->name, DMA_VDEV_NAME, sizeof(vdev->name));
664 ret = rkisp1_register_dmarx_video(stream);
665 if (ret < 0)
666 return ret;
667
668 /* dmarx links -> isp subdev */
669 source = &vdev->entity;
670 sink = &dev->isp_sdev.sd.entity;
671 ret = media_create_pad_link(source, 0,
672 sink, RKISP1_ISP_PAD_SINK, 0);
673 }
674
675 return ret;
676 }
677
rkisp1_unregister_dmarx_vdev(struct rkisp1_device * dev)678 void rkisp1_unregister_dmarx_vdev(struct rkisp1_device *dev)
679 {
680 struct rkisp1_dmarx_device *dmarx_dev = &dev->dmarx_dev;
681 struct rkisp1_stream *stream;
682
683 if (dev->isp_ver <= ISP_V13) {
684 stream = &dmarx_dev->stream[RKISP1_STREAM_DMARX];
685 rkisp1_unregister_dmarx_video(stream);
686 }
687 }
688