1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2020 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#include <linux/bitmap.h>
7#include <linux/clk.h>
8#include <linux/delay.h>
9#include <linux/host1x.h>
10#include <linux/lcm.h>
11#include <linux/list.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_graph.h>
15#include <linux/of_platform.h>
16#include <linux/platform_device.h>
17#include <linux/regulator/consumer.h>
18#include <linux/pm_runtime.h>
19#include <linux/slab.h>
20
21#include <media/v4l2-dv-timings.h>
22#include <media/v4l2-event.h>
23#include <media/v4l2-fh.h>
24#include <media/v4l2-fwnode.h>
25#include <media/v4l2-ioctl.h>
26#include <media/videobuf2-dma-contig.h>
27
28#include <soc/tegra/pmc.h>
29
30#include "vi.h"
31#include "video.h"
32
33#define MAX_CID_CONTROLS 3
34
35/**
36 * struct tegra_vi_graph_entity - Entity in the video graph
37 *
38 * @asd: subdev asynchronous registration information
39 * @entity: media entity from the corresponding V4L2 subdev
40 * @subdev: V4L2 subdev
41 */
42struct tegra_vi_graph_entity {
43 struct v4l2_async_connection asd;
44 struct media_entity *entity;
45 struct v4l2_subdev *subdev;
46};
47
48static inline struct tegra_vi *
49host1x_client_to_vi(struct host1x_client *client)
50{
51 return container_of(client, struct tegra_vi, client);
52}
53
54static inline struct tegra_channel_buffer *
55to_tegra_channel_buffer(struct vb2_v4l2_buffer *vb)
56{
57 return container_of(vb, struct tegra_channel_buffer, buf);
58}
59
60static inline struct tegra_vi_graph_entity *
61to_tegra_vi_graph_entity(struct v4l2_async_connection *asd)
62{
63 return container_of(asd, struct tegra_vi_graph_entity, asd);
64}
65
66static int tegra_get_format_idx_by_code(struct tegra_vi *vi,
67 unsigned int code,
68 unsigned int offset)
69{
70 unsigned int i;
71
72 for (i = offset; i < vi->soc->nformats; ++i) {
73 if (vi->soc->video_formats[i].code == code)
74 return i;
75 }
76
77 return -1;
78}
79
80static u32 tegra_get_format_fourcc_by_idx(struct tegra_vi *vi,
81 unsigned int index)
82{
83 if (index >= vi->soc->nformats)
84 return -EINVAL;
85
86 return vi->soc->video_formats[index].fourcc;
87}
88
89static const struct tegra_video_format *
90tegra_get_format_by_fourcc(struct tegra_vi *vi, u32 fourcc)
91{
92 unsigned int i;
93
94 for (i = 0; i < vi->soc->nformats; ++i) {
95 if (vi->soc->video_formats[i].fourcc == fourcc)
96 return &vi->soc->video_formats[i];
97 }
98
99 return NULL;
100}
101
102/*
103 * videobuf2 queue operations
104 */
105
106static int tegra_channel_queue_setup(struct vb2_queue *vq,
107 unsigned int *nbuffers,
108 unsigned int *nplanes,
109 unsigned int sizes[],
110 struct device *alloc_devs[])
111{
112 struct tegra_vi_channel *chan = vb2_get_drv_priv(q: vq);
113
114 if (*nplanes)
115 return sizes[0] < chan->format.sizeimage ? -EINVAL : 0;
116
117 *nplanes = 1;
118 sizes[0] = chan->format.sizeimage;
119 alloc_devs[0] = chan->vi->dev;
120
121 if (chan->vi->ops->channel_queue_setup)
122 chan->vi->ops->channel_queue_setup(chan);
123
124 return 0;
125}
126
127static int tegra_channel_buffer_prepare(struct vb2_buffer *vb)
128{
129 struct tegra_vi_channel *chan = vb2_get_drv_priv(q: vb->vb2_queue);
130 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
131 struct tegra_channel_buffer *buf = to_tegra_channel_buffer(vb: vbuf);
132 unsigned long size = chan->format.sizeimage;
133
134 if (vb2_plane_size(vb, plane_no: 0) < size) {
135 v4l2_err(chan->video.v4l2_dev,
136 "buffer too small (%lu < %lu)\n",
137 vb2_plane_size(vb, 0), size);
138 return -EINVAL;
139 }
140
141 vb2_set_plane_payload(vb, plane_no: 0, size);
142 buf->chan = chan;
143 buf->addr = vb2_dma_contig_plane_dma_addr(vb, plane_no: 0);
144
145 return 0;
146}
147
148static void tegra_channel_buffer_queue(struct vb2_buffer *vb)
149{
150 struct tegra_vi_channel *chan = vb2_get_drv_priv(q: vb->vb2_queue);
151 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
152 struct tegra_channel_buffer *buf = to_tegra_channel_buffer(vb: vbuf);
153
154 /* put buffer into the capture queue */
155 spin_lock(lock: &chan->start_lock);
156 list_add_tail(new: &buf->queue, head: &chan->capture);
157 spin_unlock(lock: &chan->start_lock);
158
159 /* wait up kthread for capture */
160 wake_up_interruptible(&chan->start_wait);
161}
162
163struct v4l2_subdev *
164tegra_channel_get_remote_csi_subdev(struct tegra_vi_channel *chan)
165{
166 struct media_pad *pad;
167
168 pad = media_pad_remote_pad_first(pad: &chan->pad);
169 if (!pad)
170 return NULL;
171
172 return media_entity_to_v4l2_subdev(pad->entity);
173}
174
175/*
176 * Walk up the chain until the initial source (e.g. image sensor)
177 */
178struct v4l2_subdev *
179tegra_channel_get_remote_source_subdev(struct tegra_vi_channel *chan)
180{
181 struct media_pad *pad;
182 struct v4l2_subdev *subdev;
183 struct media_entity *entity;
184
185 subdev = tegra_channel_get_remote_csi_subdev(chan);
186 if (!subdev)
187 return NULL;
188
189 pad = &subdev->entity.pads[0];
190 while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
191 pad = media_pad_remote_pad_first(pad);
192 if (!pad || !is_media_entity_v4l2_subdev(entity: pad->entity))
193 break;
194 entity = pad->entity;
195 pad = &entity->pads[0];
196 subdev = media_entity_to_v4l2_subdev(entity);
197 }
198
199 return subdev;
200}
201
202static int tegra_channel_enable_stream(struct tegra_vi_channel *chan)
203{
204 struct v4l2_subdev *subdev;
205 int ret;
206
207 subdev = tegra_channel_get_remote_csi_subdev(chan);
208 ret = v4l2_subdev_call(subdev, video, s_stream, true);
209 if (ret < 0 && ret != -ENOIOCTLCMD)
210 return ret;
211
212 return 0;
213}
214
215static int tegra_channel_disable_stream(struct tegra_vi_channel *chan)
216{
217 struct v4l2_subdev *subdev;
218 int ret;
219
220 subdev = tegra_channel_get_remote_csi_subdev(chan);
221 ret = v4l2_subdev_call(subdev, video, s_stream, false);
222 if (ret < 0 && ret != -ENOIOCTLCMD)
223 return ret;
224
225 return 0;
226}
227
228int tegra_channel_set_stream(struct tegra_vi_channel *chan, bool on)
229{
230 int ret;
231
232 if (on)
233 ret = tegra_channel_enable_stream(chan);
234 else
235 ret = tegra_channel_disable_stream(chan);
236
237 return ret;
238}
239
240void tegra_channel_release_buffers(struct tegra_vi_channel *chan,
241 enum vb2_buffer_state state)
242{
243 struct tegra_channel_buffer *buf, *nbuf;
244
245 spin_lock(lock: &chan->start_lock);
246 list_for_each_entry_safe(buf, nbuf, &chan->capture, queue) {
247 vb2_buffer_done(vb: &buf->buf.vb2_buf, state);
248 list_del(entry: &buf->queue);
249 }
250 spin_unlock(lock: &chan->start_lock);
251
252 spin_lock(lock: &chan->done_lock);
253 list_for_each_entry_safe(buf, nbuf, &chan->done, queue) {
254 vb2_buffer_done(vb: &buf->buf.vb2_buf, state);
255 list_del(entry: &buf->queue);
256 }
257 spin_unlock(lock: &chan->done_lock);
258}
259
260static int tegra_channel_start_streaming(struct vb2_queue *vq, u32 count)
261{
262 struct tegra_vi_channel *chan = vb2_get_drv_priv(q: vq);
263 int ret;
264
265 ret = pm_runtime_resume_and_get(dev: chan->vi->dev);
266 if (ret < 0) {
267 dev_err(chan->vi->dev, "failed to get runtime PM: %d\n", ret);
268 return ret;
269 }
270
271 ret = chan->vi->ops->vi_start_streaming(vq, count);
272 if (ret < 0)
273 pm_runtime_put(dev: chan->vi->dev);
274
275 return ret;
276}
277
278static void tegra_channel_stop_streaming(struct vb2_queue *vq)
279{
280 struct tegra_vi_channel *chan = vb2_get_drv_priv(q: vq);
281
282 chan->vi->ops->vi_stop_streaming(vq);
283 pm_runtime_put(dev: chan->vi->dev);
284}
285
286static const struct vb2_ops tegra_channel_queue_qops = {
287 .queue_setup = tegra_channel_queue_setup,
288 .buf_prepare = tegra_channel_buffer_prepare,
289 .buf_queue = tegra_channel_buffer_queue,
290 .wait_prepare = vb2_ops_wait_prepare,
291 .wait_finish = vb2_ops_wait_finish,
292 .start_streaming = tegra_channel_start_streaming,
293 .stop_streaming = tegra_channel_stop_streaming,
294};
295
296/*
297 * V4L2 ioctl operations
298 */
299static int tegra_channel_querycap(struct file *file, void *fh,
300 struct v4l2_capability *cap)
301{
302 struct tegra_vi_channel *chan = video_drvdata(file);
303
304 strscpy(cap->driver, "tegra-video", sizeof(cap->driver));
305 strscpy(cap->card, chan->video.name, sizeof(cap->card));
306 snprintf(buf: cap->bus_info, size: sizeof(cap->bus_info), fmt: "platform:%s",
307 dev_name(dev: chan->vi->dev));
308
309 return 0;
310}
311
312static int tegra_channel_g_parm(struct file *file, void *fh,
313 struct v4l2_streamparm *a)
314{
315 struct tegra_vi_channel *chan = video_drvdata(file);
316 struct v4l2_subdev *subdev;
317
318 subdev = tegra_channel_get_remote_source_subdev(chan);
319 return v4l2_g_parm_cap(vdev: &chan->video, sd: subdev, a);
320}
321
322static int tegra_channel_s_parm(struct file *file, void *fh,
323 struct v4l2_streamparm *a)
324{
325 struct tegra_vi_channel *chan = video_drvdata(file);
326 struct v4l2_subdev *subdev;
327
328 subdev = tegra_channel_get_remote_source_subdev(chan);
329 return v4l2_s_parm_cap(vdev: &chan->video, sd: subdev, a);
330}
331
332static int tegra_channel_enum_framesizes(struct file *file, void *fh,
333 struct v4l2_frmsizeenum *sizes)
334{
335 int ret;
336 struct tegra_vi_channel *chan = video_drvdata(file);
337 struct v4l2_subdev *subdev;
338 const struct tegra_video_format *fmtinfo;
339 struct v4l2_subdev_frame_size_enum fse = {
340 .index = sizes->index,
341 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
342 };
343
344 fmtinfo = tegra_get_format_by_fourcc(vi: chan->vi, fourcc: sizes->pixel_format);
345 if (!fmtinfo)
346 return -EINVAL;
347
348 fse.code = fmtinfo->code;
349
350 subdev = tegra_channel_get_remote_source_subdev(chan);
351 ret = v4l2_subdev_call(subdev, pad, enum_frame_size, NULL, &fse);
352 if (ret)
353 return ret;
354
355 sizes->type = V4L2_FRMSIZE_TYPE_DISCRETE;
356 sizes->discrete.width = fse.max_width;
357 sizes->discrete.height = fse.max_height;
358
359 return 0;
360}
361
362static int tegra_channel_enum_frameintervals(struct file *file, void *fh,
363 struct v4l2_frmivalenum *ivals)
364{
365 int ret;
366 struct tegra_vi_channel *chan = video_drvdata(file);
367 struct v4l2_subdev *subdev;
368 const struct tegra_video_format *fmtinfo;
369 struct v4l2_subdev_frame_interval_enum fie = {
370 .index = ivals->index,
371 .width = ivals->width,
372 .height = ivals->height,
373 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
374 };
375
376 fmtinfo = tegra_get_format_by_fourcc(vi: chan->vi, fourcc: ivals->pixel_format);
377 if (!fmtinfo)
378 return -EINVAL;
379
380 fie.code = fmtinfo->code;
381
382 subdev = tegra_channel_get_remote_source_subdev(chan);
383 ret = v4l2_subdev_call(subdev, pad, enum_frame_interval, NULL, &fie);
384 if (ret)
385 return ret;
386
387 ivals->type = V4L2_FRMIVAL_TYPE_DISCRETE;
388 ivals->discrete.numerator = fie.interval.numerator;
389 ivals->discrete.denominator = fie.interval.denominator;
390
391 return 0;
392}
393
394static int tegra_channel_enum_format(struct file *file, void *fh,
395 struct v4l2_fmtdesc *f)
396{
397 struct tegra_vi_channel *chan = video_drvdata(file);
398 unsigned int index = 0, i;
399 unsigned long *fmts_bitmap = chan->tpg_fmts_bitmap;
400
401 if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
402 fmts_bitmap = chan->fmts_bitmap;
403
404 if (f->index >= bitmap_weight(src: fmts_bitmap, MAX_FORMAT_NUM))
405 return -EINVAL;
406
407 for (i = 0; i < f->index + 1; i++, index++)
408 index = find_next_bit(addr: fmts_bitmap, MAX_FORMAT_NUM, offset: index);
409
410 f->pixelformat = tegra_get_format_fourcc_by_idx(vi: chan->vi, index: index - 1);
411
412 return 0;
413}
414
415static int tegra_channel_get_format(struct file *file, void *fh,
416 struct v4l2_format *format)
417{
418 struct tegra_vi_channel *chan = video_drvdata(file);
419
420 format->fmt.pix = chan->format;
421
422 return 0;
423}
424
425static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
426 struct v4l2_pix_format *pix)
427{
428 const struct tegra_video_format *fmtinfo;
429 static struct lock_class_key key;
430 struct v4l2_subdev *subdev;
431 struct v4l2_subdev_format fmt = {
432 .which = V4L2_SUBDEV_FORMAT_TRY,
433 };
434 struct v4l2_subdev_state *sd_state;
435 struct v4l2_subdev_frame_size_enum fse = {
436 .which = V4L2_SUBDEV_FORMAT_TRY,
437 };
438 struct v4l2_subdev_selection sdsel = {
439 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
440 .target = V4L2_SEL_TGT_CROP_BOUNDS,
441 };
442 struct v4l2_rect *try_crop;
443 int ret;
444
445 subdev = tegra_channel_get_remote_source_subdev(chan);
446 if (!subdev)
447 return -ENODEV;
448
449 /*
450 * FIXME: Drop this call, drivers are not supposed to use
451 * __v4l2_subdev_state_alloc().
452 */
453 sd_state = __v4l2_subdev_state_alloc(sd: subdev, lock_name: "tegra:state->lock",
454 key: &key);
455 if (IS_ERR(ptr: sd_state))
456 return PTR_ERR(ptr: sd_state);
457 /*
458 * Retrieve the format information and if requested format isn't
459 * supported, keep the current format.
460 */
461 fmtinfo = tegra_get_format_by_fourcc(vi: chan->vi, fourcc: pix->pixelformat);
462 if (!fmtinfo) {
463 pix->pixelformat = chan->format.pixelformat;
464 pix->colorspace = chan->format.colorspace;
465 fmtinfo = tegra_get_format_by_fourcc(vi: chan->vi,
466 fourcc: pix->pixelformat);
467 }
468
469 pix->field = V4L2_FIELD_NONE;
470 fmt.pad = 0;
471 v4l2_fill_mbus_format(mbus_fmt: &fmt.format, pix_fmt: pix, code: fmtinfo->code);
472
473 /*
474 * Attempt to obtain the format size from subdev.
475 * If not available, try to get crop boundary from subdev.
476 */
477 try_crop = v4l2_subdev_state_get_crop(sd_state, 0);
478 fse.code = fmtinfo->code;
479 ret = v4l2_subdev_call(subdev, pad, enum_frame_size, sd_state, &fse);
480 if (ret) {
481 if (!v4l2_subdev_has_op(subdev, pad, get_selection)) {
482 try_crop->width = 0;
483 try_crop->height = 0;
484 } else {
485 ret = v4l2_subdev_call(subdev, pad, get_selection,
486 NULL, &sdsel);
487 if (ret)
488 return -EINVAL;
489
490 try_crop->width = sdsel.r.width;
491 try_crop->height = sdsel.r.height;
492 }
493 } else {
494 try_crop->width = fse.max_width;
495 try_crop->height = fse.max_height;
496 }
497
498 ret = v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &fmt);
499 if (ret < 0)
500 return ret;
501
502 v4l2_fill_pix_format(pix_fmt: pix, mbus_fmt: &fmt.format);
503 chan->vi->ops->vi_fmt_align(pix, fmtinfo->bpp);
504
505 __v4l2_subdev_state_free(state: sd_state);
506
507 return 0;
508}
509
510static int tegra_channel_try_format(struct file *file, void *fh,
511 struct v4l2_format *format)
512{
513 struct tegra_vi_channel *chan = video_drvdata(file);
514
515 return __tegra_channel_try_format(chan, pix: &format->fmt.pix);
516}
517
518static void tegra_channel_update_gangports(struct tegra_vi_channel *chan)
519{
520 if (chan->format.width <= 1920)
521 chan->numgangports = 1;
522 else
523 chan->numgangports = chan->totalports;
524}
525
526static int tegra_channel_set_format(struct file *file, void *fh,
527 struct v4l2_format *format)
528{
529 struct tegra_vi_channel *chan = video_drvdata(file);
530 const struct tegra_video_format *fmtinfo;
531 struct v4l2_subdev_format fmt = {
532 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
533 };
534 struct v4l2_subdev *subdev;
535 struct v4l2_pix_format *pix = &format->fmt.pix;
536 int ret;
537
538 if (vb2_is_busy(q: &chan->queue))
539 return -EBUSY;
540
541 /* get supported format by try_fmt */
542 ret = __tegra_channel_try_format(chan, pix);
543 if (ret)
544 return ret;
545
546 fmtinfo = tegra_get_format_by_fourcc(vi: chan->vi, fourcc: pix->pixelformat);
547
548 fmt.pad = 0;
549 v4l2_fill_mbus_format(mbus_fmt: &fmt.format, pix_fmt: pix, code: fmtinfo->code);
550 subdev = tegra_channel_get_remote_source_subdev(chan);
551 ret = v4l2_subdev_call(subdev, pad, set_fmt, NULL, &fmt);
552 if (ret < 0)
553 return ret;
554
555 v4l2_fill_pix_format(pix_fmt: pix, mbus_fmt: &fmt.format);
556 chan->vi->ops->vi_fmt_align(pix, fmtinfo->bpp);
557
558 chan->format = *pix;
559 chan->fmtinfo = fmtinfo;
560 tegra_channel_update_gangports(chan);
561
562 return 0;
563}
564
565static int tegra_channel_set_subdev_active_fmt(struct tegra_vi_channel *chan)
566{
567 int ret, index;
568 struct v4l2_subdev *subdev;
569 struct v4l2_subdev_format fmt = {
570 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
571 };
572
573 /*
574 * Initialize channel format to the sub-device active format if there
575 * is corresponding match in the Tegra supported video formats.
576 */
577 subdev = tegra_channel_get_remote_source_subdev(chan);
578 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
579 if (ret)
580 return ret;
581
582 index = tegra_get_format_idx_by_code(vi: chan->vi, code: fmt.format.code, offset: 0);
583 if (index < 0)
584 return -EINVAL;
585
586 chan->fmtinfo = &chan->vi->soc->video_formats[index];
587 v4l2_fill_pix_format(pix_fmt: &chan->format, mbus_fmt: &fmt.format);
588 chan->format.pixelformat = chan->fmtinfo->fourcc;
589 chan->format.bytesperline = chan->format.width * chan->fmtinfo->bpp;
590 chan->format.sizeimage = chan->format.bytesperline *
591 chan->format.height;
592 chan->vi->ops->vi_fmt_align(&chan->format, chan->fmtinfo->bpp);
593 tegra_channel_update_gangports(chan);
594
595 return 0;
596}
597
598static int
599tegra_channel_subscribe_event(struct v4l2_fh *fh,
600 const struct v4l2_event_subscription *sub)
601{
602 switch (sub->type) {
603 case V4L2_EVENT_SOURCE_CHANGE:
604 return v4l2_event_subscribe(fh, sub, elems: 4, NULL);
605 }
606
607 return v4l2_ctrl_subscribe_event(fh, sub);
608}
609
610static int tegra_channel_g_selection(struct file *file, void *priv,
611 struct v4l2_selection *sel)
612{
613 struct tegra_vi_channel *chan = video_drvdata(file);
614 struct v4l2_subdev *subdev;
615 struct v4l2_subdev_format fmt = {
616 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
617 };
618 struct v4l2_subdev_selection sdsel = {
619 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
620 .target = sel->target,
621 };
622 int ret;
623
624 subdev = tegra_channel_get_remote_source_subdev(chan);
625 if (!v4l2_subdev_has_op(subdev, pad, get_selection))
626 return -ENOTTY;
627
628 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
629 return -EINVAL;
630 /*
631 * Try the get selection operation and fallback to get format if not
632 * implemented.
633 */
634 ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel);
635 if (!ret)
636 sel->r = sdsel.r;
637 if (ret != -ENOIOCTLCMD)
638 return ret;
639
640 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
641 if (ret < 0)
642 return ret;
643
644 sel->r.left = 0;
645 sel->r.top = 0;
646 sel->r.width = fmt.format.width;
647 sel->r.height = fmt.format.height;
648
649 return 0;
650}
651
652static int tegra_channel_s_selection(struct file *file, void *fh,
653 struct v4l2_selection *sel)
654{
655 struct tegra_vi_channel *chan = video_drvdata(file);
656 struct v4l2_subdev *subdev;
657 int ret;
658 struct v4l2_subdev_selection sdsel = {
659 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
660 .target = sel->target,
661 .flags = sel->flags,
662 .r = sel->r,
663 };
664
665 subdev = tegra_channel_get_remote_source_subdev(chan);
666 if (!v4l2_subdev_has_op(subdev, pad, set_selection))
667 return -ENOTTY;
668
669 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
670 return -EINVAL;
671
672 if (vb2_is_busy(q: &chan->queue))
673 return -EBUSY;
674
675 ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sdsel);
676 if (!ret) {
677 sel->r = sdsel.r;
678 /*
679 * Subdev active format resolution may have changed during
680 * set selection operation. So, update channel format to
681 * the sub-device active format.
682 */
683 return tegra_channel_set_subdev_active_fmt(chan);
684 }
685
686 return ret;
687}
688
689static int tegra_channel_g_edid(struct file *file, void *fh,
690 struct v4l2_edid *edid)
691{
692 struct tegra_vi_channel *chan = video_drvdata(file);
693 struct v4l2_subdev *subdev;
694
695 subdev = tegra_channel_get_remote_source_subdev(chan);
696 if (!v4l2_subdev_has_op(subdev, pad, get_edid))
697 return -ENOTTY;
698
699 return v4l2_subdev_call(subdev, pad, get_edid, edid);
700}
701
702static int tegra_channel_s_edid(struct file *file, void *fh,
703 struct v4l2_edid *edid)
704{
705 struct tegra_vi_channel *chan = video_drvdata(file);
706 struct v4l2_subdev *subdev;
707
708 subdev = tegra_channel_get_remote_source_subdev(chan);
709 if (!v4l2_subdev_has_op(subdev, pad, set_edid))
710 return -ENOTTY;
711
712 return v4l2_subdev_call(subdev, pad, set_edid, edid);
713}
714
715static int tegra_channel_g_dv_timings(struct file *file, void *fh,
716 struct v4l2_dv_timings *timings)
717{
718 struct tegra_vi_channel *chan = video_drvdata(file);
719 struct v4l2_subdev *subdev;
720
721 subdev = tegra_channel_get_remote_source_subdev(chan);
722 if (!v4l2_subdev_has_op(subdev, video, g_dv_timings))
723 return -ENOTTY;
724
725 return v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
726 video, g_dv_timings, timings);
727}
728
729static int tegra_channel_s_dv_timings(struct file *file, void *fh,
730 struct v4l2_dv_timings *timings)
731{
732 struct tegra_vi_channel *chan = video_drvdata(file);
733 struct v4l2_subdev *subdev;
734 struct v4l2_bt_timings *bt = &timings->bt;
735 struct v4l2_dv_timings curr_timings;
736 int ret;
737
738 subdev = tegra_channel_get_remote_source_subdev(chan);
739 if (!v4l2_subdev_has_op(subdev, video, s_dv_timings))
740 return -ENOTTY;
741
742 ret = tegra_channel_g_dv_timings(file, fh, timings: &curr_timings);
743 if (ret)
744 return ret;
745
746 if (v4l2_match_dv_timings(measured: timings, standard: &curr_timings, pclock_delta: 0, match_reduced_fps: false))
747 return 0;
748
749 if (vb2_is_busy(q: &chan->queue))
750 return -EBUSY;
751
752 ret = v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
753 video, s_dv_timings, timings);
754 if (ret)
755 return ret;
756
757 chan->format.width = bt->width;
758 chan->format.height = bt->height;
759 chan->format.bytesperline = bt->width * chan->fmtinfo->bpp;
760 chan->format.sizeimage = chan->format.bytesperline * bt->height;
761 chan->vi->ops->vi_fmt_align(&chan->format, chan->fmtinfo->bpp);
762 tegra_channel_update_gangports(chan);
763
764 return 0;
765}
766
767static int tegra_channel_query_dv_timings(struct file *file, void *fh,
768 struct v4l2_dv_timings *timings)
769{
770 struct tegra_vi_channel *chan = video_drvdata(file);
771 struct v4l2_subdev *subdev;
772
773 subdev = tegra_channel_get_remote_source_subdev(chan);
774 if (!v4l2_subdev_has_op(subdev, video, query_dv_timings))
775 return -ENOTTY;
776
777 return v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
778 video, query_dv_timings, timings);
779}
780
781static int tegra_channel_enum_dv_timings(struct file *file, void *fh,
782 struct v4l2_enum_dv_timings *timings)
783{
784 struct tegra_vi_channel *chan = video_drvdata(file);
785 struct v4l2_subdev *subdev;
786
787 subdev = tegra_channel_get_remote_source_subdev(chan);
788 if (!v4l2_subdev_has_op(subdev, pad, enum_dv_timings))
789 return -ENOTTY;
790
791 return v4l2_subdev_call(subdev, pad, enum_dv_timings, timings);
792}
793
794static int tegra_channel_dv_timings_cap(struct file *file, void *fh,
795 struct v4l2_dv_timings_cap *cap)
796{
797 struct tegra_vi_channel *chan = video_drvdata(file);
798 struct v4l2_subdev *subdev;
799
800 subdev = tegra_channel_get_remote_source_subdev(chan);
801 if (!v4l2_subdev_has_op(subdev, pad, dv_timings_cap))
802 return -ENOTTY;
803
804 return v4l2_subdev_call(subdev, pad, dv_timings_cap, cap);
805}
806
807static int tegra_channel_log_status(struct file *file, void *fh)
808{
809 struct tegra_vi_channel *chan = video_drvdata(file);
810
811 v4l2_device_call_all(chan->video.v4l2_dev, 0, core, log_status);
812
813 return 0;
814}
815
816static int tegra_channel_enum_input(struct file *file, void *fh,
817 struct v4l2_input *inp)
818{
819 struct tegra_vi_channel *chan = video_drvdata(file);
820 struct v4l2_subdev *subdev;
821
822 if (inp->index)
823 return -EINVAL;
824
825 inp->type = V4L2_INPUT_TYPE_CAMERA;
826 subdev = tegra_channel_get_remote_source_subdev(chan);
827 strscpy(inp->name, subdev->name, sizeof(inp->name));
828 if (v4l2_subdev_has_op(subdev, pad, dv_timings_cap))
829 inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
830
831 return 0;
832}
833
834static int tegra_channel_g_input(struct file *file, void *priv,
835 unsigned int *i)
836{
837 *i = 0;
838
839 return 0;
840}
841
842static int tegra_channel_s_input(struct file *file, void *priv,
843 unsigned int input)
844{
845 if (input > 0)
846 return -EINVAL;
847
848 return 0;
849}
850
851static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops = {
852 .vidioc_querycap = tegra_channel_querycap,
853 .vidioc_g_parm = tegra_channel_g_parm,
854 .vidioc_s_parm = tegra_channel_s_parm,
855 .vidioc_enum_framesizes = tegra_channel_enum_framesizes,
856 .vidioc_enum_frameintervals = tegra_channel_enum_frameintervals,
857 .vidioc_enum_fmt_vid_cap = tegra_channel_enum_format,
858 .vidioc_g_fmt_vid_cap = tegra_channel_get_format,
859 .vidioc_s_fmt_vid_cap = tegra_channel_set_format,
860 .vidioc_try_fmt_vid_cap = tegra_channel_try_format,
861 .vidioc_enum_input = tegra_channel_enum_input,
862 .vidioc_g_input = tegra_channel_g_input,
863 .vidioc_s_input = tegra_channel_s_input,
864 .vidioc_reqbufs = vb2_ioctl_reqbufs,
865 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
866 .vidioc_querybuf = vb2_ioctl_querybuf,
867 .vidioc_qbuf = vb2_ioctl_qbuf,
868 .vidioc_dqbuf = vb2_ioctl_dqbuf,
869 .vidioc_create_bufs = vb2_ioctl_create_bufs,
870 .vidioc_expbuf = vb2_ioctl_expbuf,
871 .vidioc_streamon = vb2_ioctl_streamon,
872 .vidioc_streamoff = vb2_ioctl_streamoff,
873 .vidioc_subscribe_event = tegra_channel_subscribe_event,
874 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
875 .vidioc_g_selection = tegra_channel_g_selection,
876 .vidioc_s_selection = tegra_channel_s_selection,
877 .vidioc_g_edid = tegra_channel_g_edid,
878 .vidioc_s_edid = tegra_channel_s_edid,
879 .vidioc_g_dv_timings = tegra_channel_g_dv_timings,
880 .vidioc_s_dv_timings = tegra_channel_s_dv_timings,
881 .vidioc_query_dv_timings = tegra_channel_query_dv_timings,
882 .vidioc_enum_dv_timings = tegra_channel_enum_dv_timings,
883 .vidioc_dv_timings_cap = tegra_channel_dv_timings_cap,
884 .vidioc_log_status = tegra_channel_log_status,
885};
886
887/*
888 * V4L2 file operations
889 */
890static const struct v4l2_file_operations tegra_channel_fops = {
891 .owner = THIS_MODULE,
892 .unlocked_ioctl = video_ioctl2,
893 .open = v4l2_fh_open,
894 .release = vb2_fop_release,
895 .read = vb2_fop_read,
896 .poll = vb2_fop_poll,
897 .mmap = vb2_fop_mmap,
898};
899
900/*
901 * V4L2 control operations
902 */
903static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
904{
905 struct tegra_vi_channel *chan = container_of(ctrl->handler,
906 struct tegra_vi_channel,
907 ctrl_handler);
908
909 switch (ctrl->id) {
910 case V4L2_CID_TEST_PATTERN:
911 /* pattern change takes effect on next stream */
912 chan->pg_mode = ctrl->val + 1;
913 break;
914 case V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY:
915 chan->syncpt_timeout_retry = ctrl->val;
916 break;
917 case V4L2_CID_HFLIP:
918 chan->hflip = ctrl->val;
919 break;
920 case V4L2_CID_VFLIP:
921 chan->vflip = ctrl->val;
922 break;
923 default:
924 return -EINVAL;
925 }
926
927 return 0;
928}
929
930static const struct v4l2_ctrl_ops vi_ctrl_ops = {
931 .s_ctrl = vi_s_ctrl,
932};
933
934#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
935static const char *const vi_pattern_strings[] = {
936 "Black/White Direct Mode",
937 "Color Patch Mode",
938};
939#else
940static const struct v4l2_ctrl_config syncpt_timeout_ctrl = {
941 .ops = &vi_ctrl_ops,
942 .id = V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY,
943 .name = "Syncpt timeout retry",
944 .type = V4L2_CTRL_TYPE_INTEGER,
945 .min = 1,
946 .max = 10000,
947 .step = 1,
948 .def = 5,
949};
950#endif
951
952static int tegra_channel_setup_ctrl_handler(struct tegra_vi_channel *chan)
953{
954 int ret;
955
956#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
957 /* add test pattern control handler to v4l2 device */
958 v4l2_ctrl_new_std_menu_items(&chan->ctrl_handler, &vi_ctrl_ops,
959 V4L2_CID_TEST_PATTERN,
960 ARRAY_SIZE(vi_pattern_strings) - 1,
961 0, 0, vi_pattern_strings);
962 if (chan->ctrl_handler.error) {
963 dev_err(chan->vi->dev, "failed to add TPG ctrl handler: %d\n",
964 chan->ctrl_handler.error);
965 v4l2_ctrl_handler_free(&chan->ctrl_handler);
966 return chan->ctrl_handler.error;
967 }
968#else
969 struct v4l2_subdev *subdev;
970
971 /* custom control */
972 v4l2_ctrl_new_custom(hdl: &chan->ctrl_handler, cfg: &syncpt_timeout_ctrl, NULL);
973 if (chan->ctrl_handler.error) {
974 dev_err(chan->vi->dev, "failed to add %s ctrl handler: %d\n",
975 syncpt_timeout_ctrl.name,
976 chan->ctrl_handler.error);
977 v4l2_ctrl_handler_free(hdl: &chan->ctrl_handler);
978 return chan->ctrl_handler.error;
979 }
980
981 subdev = tegra_channel_get_remote_source_subdev(chan);
982 if (!subdev)
983 return -ENODEV;
984
985 ret = v4l2_ctrl_add_handler(hdl: &chan->ctrl_handler, add: subdev->ctrl_handler,
986 NULL, from_other_dev: true);
987 if (ret < 0) {
988 dev_err(chan->vi->dev,
989 "failed to add subdev %s ctrl handler: %d\n",
990 subdev->name, ret);
991 v4l2_ctrl_handler_free(hdl: &chan->ctrl_handler);
992 return ret;
993 }
994
995 if (chan->vi->soc->has_h_v_flip) {
996 v4l2_ctrl_new_std(hdl: &chan->ctrl_handler, ops: &vi_ctrl_ops, V4L2_CID_HFLIP, min: 0, max: 1, step: 1, def: 0);
997 v4l2_ctrl_new_std(hdl: &chan->ctrl_handler, ops: &vi_ctrl_ops, V4L2_CID_VFLIP, min: 0, max: 1, step: 1, def: 0);
998 }
999
1000#endif
1001
1002 /* setup the controls */
1003 ret = v4l2_ctrl_handler_setup(hdl: &chan->ctrl_handler);
1004 if (ret < 0) {
1005 dev_err(chan->vi->dev,
1006 "failed to setup v4l2 ctrl handler: %d\n", ret);
1007 return ret;
1008 }
1009
1010 return 0;
1011}
1012
1013/* VI only support 2 formats in TPG mode */
1014static void vi_tpg_fmts_bitmap_init(struct tegra_vi_channel *chan)
1015{
1016 int index;
1017
1018 bitmap_zero(dst: chan->tpg_fmts_bitmap, MAX_FORMAT_NUM);
1019
1020 index = tegra_get_format_idx_by_code(vi: chan->vi,
1021 MEDIA_BUS_FMT_SRGGB10_1X10, offset: 0);
1022 bitmap_set(map: chan->tpg_fmts_bitmap, start: index, nbits: 1);
1023
1024 index = tegra_get_format_idx_by_code(vi: chan->vi,
1025 MEDIA_BUS_FMT_RGB888_1X32_PADHI,
1026 offset: 0);
1027 bitmap_set(map: chan->tpg_fmts_bitmap, start: index, nbits: 1);
1028}
1029
1030static int vi_fmts_bitmap_init(struct tegra_vi_channel *chan)
1031{
1032 int index, ret, match_code = 0;
1033 struct v4l2_subdev *subdev;
1034 struct v4l2_subdev_mbus_code_enum code = {
1035 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1036 };
1037
1038 bitmap_zero(dst: chan->fmts_bitmap, MAX_FORMAT_NUM);
1039
1040 /*
1041 * Set the bitmap bits based on all the matched formats between the
1042 * available media bus formats of sub-device and the pre-defined Tegra
1043 * supported video formats.
1044 */
1045 subdev = tegra_channel_get_remote_source_subdev(chan);
1046 while (1) {
1047 ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
1048 NULL, &code);
1049 if (ret < 0)
1050 break;
1051
1052 index = tegra_get_format_idx_by_code(vi: chan->vi, code: code.code, offset: 0);
1053 while (index >= 0) {
1054 bitmap_set(map: chan->fmts_bitmap, start: index, nbits: 1);
1055 if (!match_code)
1056 match_code = code.code;
1057 /* look for other formats with same mbus code */
1058 index = tegra_get_format_idx_by_code(vi: chan->vi,
1059 code: code.code,
1060 offset: index + 1);
1061 }
1062
1063 code.index++;
1064 }
1065
1066 /*
1067 * Set the bitmap bit corresponding to default tegra video format if
1068 * there are no matched formats.
1069 */
1070 if (!match_code) {
1071 match_code = chan->vi->soc->default_video_format->code;
1072 index = tegra_get_format_idx_by_code(vi: chan->vi, code: match_code, offset: 0);
1073 if (WARN_ON(index < 0))
1074 return -EINVAL;
1075
1076 bitmap_set(map: chan->fmts_bitmap, start: index, nbits: 1);
1077 }
1078
1079 /* initialize channel format to the sub-device active format */
1080 tegra_channel_set_subdev_active_fmt(chan);
1081
1082 return 0;
1083}
1084
1085static void tegra_channel_cleanup(struct tegra_vi_channel *chan)
1086{
1087 v4l2_ctrl_handler_free(hdl: &chan->ctrl_handler);
1088 media_entity_cleanup(entity: &chan->video.entity);
1089 chan->vi->ops->channel_host1x_syncpt_free(chan);
1090 mutex_destroy(lock: &chan->video_lock);
1091}
1092
1093void tegra_channels_cleanup(struct tegra_vi *vi)
1094{
1095 struct tegra_vi_channel *chan, *tmp;
1096
1097 if (!vi)
1098 return;
1099
1100 list_for_each_entry_safe(chan, tmp, &vi->vi_chans, list) {
1101 tegra_channel_cleanup(chan);
1102 list_del(entry: &chan->list);
1103 kfree(objp: chan);
1104 }
1105}
1106
1107static int tegra_channel_init(struct tegra_vi_channel *chan)
1108{
1109 struct tegra_vi *vi = chan->vi;
1110 struct tegra_video_device *vid = dev_get_drvdata(dev: vi->client.host);
1111 int ret;
1112
1113 mutex_init(&chan->video_lock);
1114 INIT_LIST_HEAD(list: &chan->capture);
1115 INIT_LIST_HEAD(list: &chan->done);
1116 spin_lock_init(&chan->start_lock);
1117 spin_lock_init(&chan->done_lock);
1118 init_waitqueue_head(&chan->start_wait);
1119 init_waitqueue_head(&chan->done_wait);
1120
1121 /* initialize the video format */
1122 chan->fmtinfo = chan->vi->soc->default_video_format;
1123 chan->format.pixelformat = chan->fmtinfo->fourcc;
1124 chan->format.colorspace = V4L2_COLORSPACE_SRGB;
1125 chan->format.field = V4L2_FIELD_NONE;
1126 chan->format.width = TEGRA_DEF_WIDTH;
1127 chan->format.height = TEGRA_DEF_HEIGHT;
1128 chan->format.bytesperline = TEGRA_DEF_WIDTH * chan->fmtinfo->bpp;
1129 chan->format.sizeimage = chan->format.bytesperline * TEGRA_DEF_HEIGHT;
1130 vi->ops->vi_fmt_align(&chan->format, chan->fmtinfo->bpp);
1131
1132 ret = vi->ops->channel_host1x_syncpt_init(chan);
1133 if (ret)
1134 return ret;
1135
1136 /* initialize the media entity */
1137 chan->pad.flags = MEDIA_PAD_FL_SINK;
1138 ret = media_entity_pads_init(entity: &chan->video.entity, num_pads: 1, pads: &chan->pad);
1139 if (ret < 0) {
1140 dev_err(vi->dev,
1141 "failed to initialize media entity: %d\n", ret);
1142 goto free_syncpts;
1143 }
1144
1145 ret = v4l2_ctrl_handler_init(&chan->ctrl_handler, MAX_CID_CONTROLS);
1146 if (chan->ctrl_handler.error) {
1147 dev_err(vi->dev,
1148 "failed to initialize v4l2 ctrl handler: %d\n", ret);
1149 goto cleanup_media;
1150 }
1151
1152 /* initialize the video_device */
1153 chan->video.fops = &tegra_channel_fops;
1154 chan->video.v4l2_dev = &vid->v4l2_dev;
1155 chan->video.release = video_device_release_empty;
1156 chan->video.queue = &chan->queue;
1157 snprintf(buf: chan->video.name, size: sizeof(chan->video.name), fmt: "%s-%s-%u",
1158 dev_name(dev: vi->dev), "output", chan->portnos[0]);
1159 chan->video.vfl_type = VFL_TYPE_VIDEO;
1160 chan->video.vfl_dir = VFL_DIR_RX;
1161 chan->video.ioctl_ops = &tegra_channel_ioctl_ops;
1162 chan->video.ctrl_handler = &chan->ctrl_handler;
1163 chan->video.lock = &chan->video_lock;
1164 chan->video.device_caps = V4L2_CAP_VIDEO_CAPTURE |
1165 V4L2_CAP_STREAMING |
1166 V4L2_CAP_READWRITE;
1167 video_set_drvdata(vdev: &chan->video, data: chan);
1168
1169 chan->queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1170 chan->queue.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
1171 chan->queue.lock = &chan->video_lock;
1172 chan->queue.drv_priv = chan;
1173 chan->queue.buf_struct_size = sizeof(struct tegra_channel_buffer);
1174 chan->queue.ops = &tegra_channel_queue_qops;
1175 chan->queue.mem_ops = &vb2_dma_contig_memops;
1176 chan->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1177 chan->queue.min_queued_buffers = 2;
1178 chan->queue.dev = vi->dev;
1179 ret = vb2_queue_init(q: &chan->queue);
1180 if (ret < 0) {
1181 dev_err(vi->dev, "failed to initialize vb2 queue: %d\n", ret);
1182 goto free_v4l2_ctrl_hdl;
1183 }
1184
1185 if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
1186 v4l2_async_nf_init(notifier: &chan->notifier, v4l2_dev: &vid->v4l2_dev);
1187
1188 return 0;
1189
1190free_v4l2_ctrl_hdl:
1191 v4l2_ctrl_handler_free(hdl: &chan->ctrl_handler);
1192cleanup_media:
1193 media_entity_cleanup(entity: &chan->video.entity);
1194free_syncpts:
1195 vi->ops->channel_host1x_syncpt_free(chan);
1196 return ret;
1197}
1198
1199static int tegra_vi_channel_alloc(struct tegra_vi *vi, unsigned int port_num,
1200 struct device_node *node, unsigned int lanes)
1201{
1202 struct tegra_vi_channel *chan;
1203 unsigned int i;
1204
1205 /*
1206 * Do not use devm_kzalloc as memory is freed immediately
1207 * when device instance is unbound but application might still
1208 * be holding the device node open. Channel memory allocated
1209 * with kzalloc is freed during video device release callback.
1210 */
1211 chan = kzalloc(size: sizeof(*chan), GFP_KERNEL);
1212 if (!chan)
1213 return -ENOMEM;
1214
1215 chan->vi = vi;
1216 chan->portnos[0] = port_num;
1217 /*
1218 * For data lanes more than maximum csi lanes per brick, multiple of
1219 * x4 ports are used simultaneously for capture.
1220 */
1221 if (lanes <= CSI_LANES_PER_BRICK)
1222 chan->totalports = 1;
1223 else
1224 chan->totalports = lanes / CSI_LANES_PER_BRICK;
1225 chan->numgangports = chan->totalports;
1226
1227 for (i = 1; i < chan->totalports; i++)
1228 chan->portnos[i] = chan->portnos[0] + i * CSI_PORTS_PER_BRICK;
1229
1230 chan->of_node = node;
1231 list_add_tail(new: &chan->list, head: &vi->vi_chans);
1232
1233 return 0;
1234}
1235
1236static int tegra_vi_tpg_channels_alloc(struct tegra_vi *vi)
1237{
1238 unsigned int port_num;
1239 unsigned int nchannels = vi->soc->vi_max_channels;
1240 int ret;
1241
1242 for (port_num = 0; port_num < nchannels; port_num++) {
1243 ret = tegra_vi_channel_alloc(vi, port_num,
1244 node: vi->dev->of_node, lanes: 2);
1245 if (ret < 0)
1246 return ret;
1247 }
1248
1249 return 0;
1250}
1251
1252static int tegra_vi_channels_alloc(struct tegra_vi *vi)
1253{
1254 struct device_node *node = vi->dev->of_node;
1255 struct device_node *ep = NULL;
1256 struct device_node *ports;
1257 struct device_node *port = NULL;
1258 unsigned int port_num;
1259 struct device_node *parent;
1260 struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
1261 unsigned int lanes;
1262 int ret = 0;
1263
1264 ports = of_get_child_by_name(node, name: "ports");
1265 if (!ports)
1266 return dev_err_probe(dev: vi->dev, err: -ENODEV, fmt: "%pOF: missing 'ports' node\n", node);
1267
1268 for_each_child_of_node(ports, port) {
1269 if (!of_node_name_eq(np: port, name: "port"))
1270 continue;
1271
1272 ret = of_property_read_u32(np: port, propname: "reg", out_value: &port_num);
1273 if (ret < 0)
1274 continue;
1275
1276 if (port_num > vi->soc->vi_max_channels) {
1277 dev_err(vi->dev, "invalid port num %d for %pOF\n",
1278 port_num, port);
1279 ret = -EINVAL;
1280 goto cleanup;
1281 }
1282
1283 ep = of_get_child_by_name(node: port, name: "endpoint");
1284 if (!ep)
1285 continue;
1286
1287 parent = of_graph_get_remote_port_parent(node: ep);
1288 of_node_put(node: ep);
1289 if (!parent)
1290 continue;
1291
1292 ep = of_graph_get_endpoint_by_regs(parent, port_reg: 0, reg: 0);
1293 of_node_put(node: parent);
1294 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep),
1295 vep: &v4l2_ep);
1296 of_node_put(node: ep);
1297 if (ret)
1298 continue;
1299
1300 lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
1301 ret = tegra_vi_channel_alloc(vi, port_num, node: port, lanes);
1302 if (ret < 0)
1303 goto cleanup;
1304 }
1305
1306cleanup:
1307 of_node_put(node: port);
1308 of_node_put(node: ports);
1309 return ret;
1310}
1311
1312static int tegra_vi_channels_init(struct tegra_vi *vi)
1313{
1314 struct tegra_vi_channel *chan;
1315 int ret;
1316
1317 list_for_each_entry(chan, &vi->vi_chans, list) {
1318 ret = tegra_channel_init(chan);
1319 if (ret < 0) {
1320 dev_err(vi->dev,
1321 "failed to initialize channel-%d: %d\n",
1322 chan->portnos[0], ret);
1323 goto cleanup;
1324 }
1325 }
1326
1327 return 0;
1328
1329cleanup:
1330 list_for_each_entry_continue_reverse(chan, &vi->vi_chans, list)
1331 tegra_channel_cleanup(chan);
1332
1333 return ret;
1334}
1335
1336void tegra_v4l2_nodes_cleanup_tpg(struct tegra_video_device *vid)
1337{
1338 struct tegra_vi *vi = vid->vi;
1339 struct tegra_csi *csi = vid->csi;
1340 struct tegra_csi_channel *csi_chan;
1341 struct tegra_vi_channel *chan;
1342
1343 list_for_each_entry(chan, &vi->vi_chans, list)
1344 vb2_video_unregister_device(vdev: &chan->video);
1345
1346 list_for_each_entry(csi_chan, &csi->csi_chans, list)
1347 v4l2_device_unregister_subdev(sd: &csi_chan->subdev);
1348}
1349
1350int tegra_v4l2_nodes_setup_tpg(struct tegra_video_device *vid)
1351{
1352 struct tegra_vi *vi = vid->vi;
1353 struct tegra_csi *csi = vid->csi;
1354 struct tegra_vi_channel *vi_chan;
1355 struct tegra_csi_channel *csi_chan;
1356 u32 link_flags = MEDIA_LNK_FL_ENABLED;
1357 int ret;
1358
1359 if (!vi || !csi)
1360 return -ENODEV;
1361
1362 csi_chan = list_first_entry(&csi->csi_chans,
1363 struct tegra_csi_channel, list);
1364
1365 list_for_each_entry(vi_chan, &vi->vi_chans, list) {
1366 struct media_entity *source = &csi_chan->subdev.entity;
1367 struct media_entity *sink = &vi_chan->video.entity;
1368 struct media_pad *source_pad = csi_chan->pads;
1369 struct media_pad *sink_pad = &vi_chan->pad;
1370
1371 ret = v4l2_device_register_subdev(v4l2_dev: &vid->v4l2_dev,
1372 sd: &csi_chan->subdev);
1373 if (ret) {
1374 dev_err(vi->dev,
1375 "failed to register subdev: %d\n", ret);
1376 goto cleanup;
1377 }
1378
1379 ret = video_register_device(vdev: &vi_chan->video,
1380 type: VFL_TYPE_VIDEO, nr: -1);
1381 if (ret < 0) {
1382 dev_err(vi->dev,
1383 "failed to register video device: %d\n", ret);
1384 goto cleanup;
1385 }
1386
1387 dev_dbg(vi->dev, "creating %s:%u -> %s:%u link\n",
1388 source->name, source_pad->index,
1389 sink->name, sink_pad->index);
1390
1391 ret = media_create_pad_link(source, source_pad: source_pad->index,
1392 sink, sink_pad: sink_pad->index,
1393 flags: link_flags);
1394 if (ret < 0) {
1395 dev_err(vi->dev,
1396 "failed to create %s:%u -> %s:%u link: %d\n",
1397 source->name, source_pad->index,
1398 sink->name, sink_pad->index, ret);
1399 goto cleanup;
1400 }
1401
1402 ret = tegra_channel_setup_ctrl_handler(chan: vi_chan);
1403 if (ret < 0)
1404 goto cleanup;
1405
1406 v4l2_set_subdev_hostdata(sd: &csi_chan->subdev, p: vi_chan);
1407 vi_tpg_fmts_bitmap_init(chan: vi_chan);
1408 csi_chan = list_next_entry(csi_chan, list);
1409 }
1410
1411 return 0;
1412
1413cleanup:
1414 tegra_v4l2_nodes_cleanup_tpg(vid);
1415 return ret;
1416}
1417
1418static int __maybe_unused vi_runtime_resume(struct device *dev)
1419{
1420 struct tegra_vi *vi = dev_get_drvdata(dev);
1421 int ret;
1422
1423 ret = regulator_enable(regulator: vi->vdd);
1424 if (ret) {
1425 dev_err(dev, "failed to enable VDD supply: %d\n", ret);
1426 return ret;
1427 }
1428
1429 ret = clk_set_rate(clk: vi->clk, rate: vi->soc->vi_max_clk_hz);
1430 if (ret) {
1431 dev_err(dev, "failed to set vi clock rate: %d\n", ret);
1432 goto disable_vdd;
1433 }
1434
1435 ret = clk_prepare_enable(clk: vi->clk);
1436 if (ret) {
1437 dev_err(dev, "failed to enable vi clock: %d\n", ret);
1438 goto disable_vdd;
1439 }
1440
1441 return 0;
1442
1443disable_vdd:
1444 regulator_disable(regulator: vi->vdd);
1445 return ret;
1446}
1447
1448static int __maybe_unused vi_runtime_suspend(struct device *dev)
1449{
1450 struct tegra_vi *vi = dev_get_drvdata(dev);
1451
1452 clk_disable_unprepare(clk: vi->clk);
1453
1454 regulator_disable(regulator: vi->vdd);
1455
1456 return 0;
1457}
1458
1459/*
1460 * Find the entity matching a given fwnode in an v4l2_async_notifier list
1461 */
1462static struct tegra_vi_graph_entity *
1463tegra_vi_graph_find_entity(struct list_head *list,
1464 const struct fwnode_handle *fwnode)
1465{
1466 struct tegra_vi_graph_entity *entity;
1467 struct v4l2_async_connection *asd;
1468
1469 list_for_each_entry(asd, list, asc_entry) {
1470 entity = to_tegra_vi_graph_entity(asd);
1471
1472 if (entity->asd.match.fwnode == fwnode)
1473 return entity;
1474 }
1475
1476 return NULL;
1477}
1478
1479static int tegra_vi_graph_build(struct tegra_vi_channel *chan,
1480 struct tegra_vi_graph_entity *entity)
1481{
1482 struct tegra_vi *vi = chan->vi;
1483 struct tegra_vi_graph_entity *ent;
1484 struct fwnode_handle *ep = NULL;
1485 struct v4l2_fwnode_link link;
1486 struct media_entity *local = entity->entity;
1487 struct media_entity *remote;
1488 struct media_pad *local_pad;
1489 struct media_pad *remote_pad;
1490 u32 link_flags = MEDIA_LNK_FL_ENABLED;
1491 int ret = 0;
1492
1493 dev_dbg(vi->dev, "creating links for entity %s\n", local->name);
1494
1495 while (1) {
1496 ep = fwnode_graph_get_next_endpoint(fwnode: entity->asd.match.fwnode,
1497 prev: ep);
1498 if (!ep)
1499 break;
1500
1501 ret = v4l2_fwnode_parse_link(fwnode: ep, link: &link);
1502 if (ret < 0) {
1503 dev_err(vi->dev, "failed to parse link for %pOF: %d\n",
1504 to_of_node(ep), ret);
1505 continue;
1506 }
1507
1508 if (link.local_port >= local->num_pads) {
1509 dev_err(vi->dev, "invalid port number %u on %pOF\n",
1510 link.local_port, to_of_node(link.local_node));
1511 v4l2_fwnode_put_link(link: &link);
1512 ret = -EINVAL;
1513 break;
1514 }
1515
1516 local_pad = &local->pads[link.local_port];
1517 /* Remote node is vi node. So use channel video entity and pad
1518 * as remote/sink.
1519 */
1520 if (link.remote_node == of_fwnode_handle(vi->dev->of_node)) {
1521 remote = &chan->video.entity;
1522 remote_pad = &chan->pad;
1523 goto create_link;
1524 }
1525
1526 /*
1527 * Skip sink ports, they will be processed from the other end
1528 * of the link.
1529 */
1530 if (local_pad->flags & MEDIA_PAD_FL_SINK) {
1531 dev_dbg(vi->dev, "skipping sink port %pOF:%u\n",
1532 to_of_node(link.local_node), link.local_port);
1533 v4l2_fwnode_put_link(link: &link);
1534 continue;
1535 }
1536
1537 /* find the remote entity from notifier list */
1538 ent = tegra_vi_graph_find_entity(list: &chan->notifier.done_list,
1539 fwnode: link.remote_node);
1540 if (!ent) {
1541 dev_err(vi->dev, "no entity found for %pOF\n",
1542 to_of_node(link.remote_node));
1543 v4l2_fwnode_put_link(link: &link);
1544 ret = -ENODEV;
1545 break;
1546 }
1547
1548 remote = ent->entity;
1549 if (link.remote_port >= remote->num_pads) {
1550 dev_err(vi->dev, "invalid port number %u on %pOF\n",
1551 link.remote_port,
1552 to_of_node(link.remote_node));
1553 v4l2_fwnode_put_link(link: &link);
1554 ret = -EINVAL;
1555 break;
1556 }
1557
1558 remote_pad = &remote->pads[link.remote_port];
1559
1560create_link:
1561 dev_dbg(vi->dev, "creating %s:%u -> %s:%u link\n",
1562 local->name, local_pad->index,
1563 remote->name, remote_pad->index);
1564
1565 ret = media_create_pad_link(source: local, source_pad: local_pad->index,
1566 sink: remote, sink_pad: remote_pad->index,
1567 flags: link_flags);
1568 v4l2_fwnode_put_link(link: &link);
1569 if (ret < 0) {
1570 dev_err(vi->dev,
1571 "failed to create %s:%u -> %s:%u link: %d\n",
1572 local->name, local_pad->index,
1573 remote->name, remote_pad->index, ret);
1574 break;
1575 }
1576 }
1577
1578 fwnode_handle_put(fwnode: ep);
1579 return ret;
1580}
1581
1582static int tegra_vi_graph_notify_complete(struct v4l2_async_notifier *notifier)
1583{
1584 struct tegra_vi_graph_entity *entity;
1585 struct v4l2_async_connection *asd;
1586 struct v4l2_subdev *subdev;
1587 struct tegra_vi_channel *chan;
1588 struct tegra_vi *vi;
1589 int ret;
1590
1591 chan = container_of(notifier, struct tegra_vi_channel, notifier);
1592 vi = chan->vi;
1593
1594 dev_dbg(vi->dev, "notify complete, all subdevs registered\n");
1595
1596 /*
1597 * Video device node should be created at the end of all the device
1598 * related initialization/setup.
1599 * Current video_register_device() does both initialize and register
1600 * video device in same API.
1601 *
1602 * TODO: Update v4l2-dev driver to split initialize and register into
1603 * separate APIs and then update Tegra video driver to do video device
1604 * initialize followed by all video device related setup and then
1605 * register the video device.
1606 */
1607 ret = video_register_device(vdev: &chan->video, type: VFL_TYPE_VIDEO, nr: -1);
1608 if (ret < 0) {
1609 dev_err(vi->dev,
1610 "failed to register video device: %d\n", ret);
1611 goto unregister_video;
1612 }
1613
1614 /* create links between the entities */
1615 list_for_each_entry(asd, &chan->notifier.done_list, asc_entry) {
1616 entity = to_tegra_vi_graph_entity(asd);
1617 ret = tegra_vi_graph_build(chan, entity);
1618 if (ret < 0)
1619 goto unregister_video;
1620 }
1621
1622 ret = tegra_channel_setup_ctrl_handler(chan);
1623 if (ret < 0) {
1624 dev_err(vi->dev,
1625 "failed to setup channel controls: %d\n", ret);
1626 goto unregister_video;
1627 }
1628
1629 ret = vi_fmts_bitmap_init(chan);
1630 if (ret < 0) {
1631 dev_err(vi->dev,
1632 "failed to initialize formats bitmap: %d\n", ret);
1633 goto unregister_video;
1634 }
1635
1636 subdev = tegra_channel_get_remote_csi_subdev(chan);
1637 if (!subdev) {
1638 ret = -ENODEV;
1639 dev_err(vi->dev,
1640 "failed to get remote csi subdev: %d\n", ret);
1641 goto unregister_video;
1642 }
1643
1644 v4l2_set_subdev_hostdata(sd: subdev, p: chan);
1645
1646 subdev = tegra_channel_get_remote_source_subdev(chan);
1647 v4l2_set_subdev_hostdata(sd: subdev, p: chan);
1648
1649 return 0;
1650
1651unregister_video:
1652 vb2_video_unregister_device(vdev: &chan->video);
1653 return ret;
1654}
1655
1656static int tegra_vi_graph_notify_bound(struct v4l2_async_notifier *notifier,
1657 struct v4l2_subdev *subdev,
1658 struct v4l2_async_connection *asd)
1659{
1660 struct tegra_vi_graph_entity *entity;
1661 struct tegra_vi *vi;
1662 struct tegra_vi_channel *chan;
1663
1664 chan = container_of(notifier, struct tegra_vi_channel, notifier);
1665 vi = chan->vi;
1666
1667 /*
1668 * Locate the entity corresponding to the bound subdev and store the
1669 * subdev pointer.
1670 */
1671 entity = tegra_vi_graph_find_entity(list: &chan->notifier.waiting_list,
1672 fwnode: subdev->fwnode);
1673 if (!entity) {
1674 dev_err(vi->dev, "no entity for subdev %s\n", subdev->name);
1675 return -EINVAL;
1676 }
1677
1678 if (entity->subdev) {
1679 dev_err(vi->dev, "duplicate subdev for node %pOF\n",
1680 to_of_node(entity->asd.match.fwnode));
1681 return -EINVAL;
1682 }
1683
1684 dev_dbg(vi->dev, "subdev %s bound\n", subdev->name);
1685 entity->entity = &subdev->entity;
1686 entity->subdev = subdev;
1687
1688 return 0;
1689}
1690
1691static const struct v4l2_async_notifier_operations tegra_vi_async_ops = {
1692 .bound = tegra_vi_graph_notify_bound,
1693 .complete = tegra_vi_graph_notify_complete,
1694};
1695
1696static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan,
1697 struct fwnode_handle *fwnode)
1698{
1699 struct tegra_vi *vi = chan->vi;
1700 struct fwnode_handle *ep = NULL;
1701 struct fwnode_handle *remote = NULL;
1702 struct tegra_vi_graph_entity *tvge;
1703 struct device_node *node = NULL;
1704 int ret;
1705
1706 dev_dbg(vi->dev, "parsing node %pOF\n", to_of_node(fwnode));
1707
1708 /* parse all the remote entities and put them into the list */
1709 for_each_endpoint_of_node(to_of_node(fwnode), node) {
1710 ep = of_fwnode_handle(node);
1711 remote = fwnode_graph_get_remote_port_parent(fwnode: ep);
1712 if (!remote) {
1713 dev_err(vi->dev,
1714 "remote device at %pOF not found\n", node);
1715 ret = -EINVAL;
1716 goto cleanup;
1717 }
1718
1719 /* skip entities that are already processed */
1720 if (device_match_fwnode(dev: vi->dev, fwnode: remote) ||
1721 tegra_vi_graph_find_entity(list: &chan->notifier.waiting_list,
1722 fwnode: remote)) {
1723 fwnode_handle_put(fwnode: remote);
1724 continue;
1725 }
1726
1727 tvge = v4l2_async_nf_add_fwnode(&chan->notifier, remote,
1728 struct tegra_vi_graph_entity);
1729 if (IS_ERR(ptr: tvge)) {
1730 ret = PTR_ERR(ptr: tvge);
1731 dev_err(vi->dev,
1732 "failed to add subdev to notifier: %d\n", ret);
1733 fwnode_handle_put(fwnode: remote);
1734 goto cleanup;
1735 }
1736
1737 ret = tegra_vi_graph_parse_one(chan, fwnode: remote);
1738 if (ret < 0) {
1739 fwnode_handle_put(fwnode: remote);
1740 goto cleanup;
1741 }
1742
1743 fwnode_handle_put(fwnode: remote);
1744 }
1745
1746 return 0;
1747
1748cleanup:
1749 dev_err(vi->dev, "failed parsing the graph: %d\n", ret);
1750 v4l2_async_nf_cleanup(notifier: &chan->notifier);
1751 of_node_put(node);
1752 return ret;
1753}
1754
1755static int tegra_vi_graph_init(struct tegra_vi *vi)
1756{
1757 struct tegra_vi_channel *chan;
1758 struct fwnode_handle *fwnode = dev_fwnode(vi->dev);
1759 int ret;
1760
1761 /*
1762 * Walk the links to parse the full graph. Each channel will have
1763 * one endpoint of the composite node. Start by parsing the
1764 * composite node and parse the remote entities in turn.
1765 * Each channel will register a v4l2 async notifier to make the graph
1766 * independent between the channels so we can skip the current channel
1767 * in case of something wrong during graph parsing and continue with
1768 * the next channels.
1769 */
1770 list_for_each_entry(chan, &vi->vi_chans, list) {
1771 struct fwnode_handle *ep, *remote;
1772
1773 ep = fwnode_graph_get_endpoint_by_id(fwnode,
1774 port: chan->portnos[0], endpoint: 0, flags: 0);
1775 if (!ep)
1776 continue;
1777
1778 remote = fwnode_graph_get_remote_port_parent(fwnode: ep);
1779 fwnode_handle_put(fwnode: ep);
1780
1781 ret = tegra_vi_graph_parse_one(chan, fwnode: remote);
1782 fwnode_handle_put(fwnode: remote);
1783 if (ret < 0 || list_empty(head: &chan->notifier.waiting_list))
1784 continue;
1785
1786 chan->notifier.ops = &tegra_vi_async_ops;
1787 ret = v4l2_async_nf_register(notifier: &chan->notifier);
1788 if (ret < 0) {
1789 dev_err(vi->dev,
1790 "failed to register channel %d notifier: %d\n",
1791 chan->portnos[0], ret);
1792 v4l2_async_nf_cleanup(notifier: &chan->notifier);
1793 }
1794 }
1795
1796 return 0;
1797}
1798
1799static void tegra_vi_graph_cleanup(struct tegra_vi *vi)
1800{
1801 struct tegra_vi_channel *chan;
1802
1803 list_for_each_entry(chan, &vi->vi_chans, list) {
1804 vb2_video_unregister_device(vdev: &chan->video);
1805 v4l2_async_nf_unregister(notifier: &chan->notifier);
1806 v4l2_async_nf_cleanup(notifier: &chan->notifier);
1807 }
1808}
1809
1810static int tegra_vi_init(struct host1x_client *client)
1811{
1812 struct tegra_video_device *vid = dev_get_drvdata(dev: client->host);
1813 struct tegra_vi *vi = host1x_client_to_vi(client);
1814 struct tegra_vi_channel *chan, *tmp;
1815 int ret;
1816
1817 vid->media_dev.hw_revision = vi->soc->hw_revision;
1818 snprintf(buf: vid->media_dev.bus_info, size: sizeof(vid->media_dev.bus_info),
1819 fmt: "platform:%s", dev_name(dev: vi->dev));
1820
1821 INIT_LIST_HEAD(list: &vi->vi_chans);
1822
1823 if (IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
1824 ret = tegra_vi_tpg_channels_alloc(vi);
1825 else
1826 ret = tegra_vi_channels_alloc(vi);
1827 if (ret < 0)
1828 goto free_chans;
1829
1830 ret = tegra_vi_channels_init(vi);
1831 if (ret < 0)
1832 goto free_chans;
1833
1834 vid->vi = vi;
1835
1836 if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)) {
1837 ret = tegra_vi_graph_init(vi);
1838 if (ret < 0)
1839 goto cleanup_chans;
1840 }
1841
1842 return 0;
1843
1844cleanup_chans:
1845 list_for_each_entry(chan, &vi->vi_chans, list)
1846 tegra_channel_cleanup(chan);
1847free_chans:
1848 list_for_each_entry_safe(chan, tmp, &vi->vi_chans, list) {
1849 list_del(entry: &chan->list);
1850 kfree(objp: chan);
1851 }
1852
1853 return ret;
1854}
1855
1856static int tegra_vi_exit(struct host1x_client *client)
1857{
1858 struct tegra_vi *vi = host1x_client_to_vi(client);
1859
1860 /*
1861 * Do not cleanup the channels here as application might still be
1862 * holding video device nodes. Channels cleanup will happen during
1863 * v4l2_device release callback which gets called after all video
1864 * device nodes are released.
1865 */
1866
1867 if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
1868 tegra_vi_graph_cleanup(vi);
1869
1870 return 0;
1871}
1872
1873static const struct host1x_client_ops vi_client_ops = {
1874 .init = tegra_vi_init,
1875 .exit = tegra_vi_exit,
1876};
1877
1878static int tegra_vi_probe(struct platform_device *pdev)
1879{
1880 struct tegra_vi *vi;
1881 int ret;
1882
1883 vi = devm_kzalloc(dev: &pdev->dev, size: sizeof(*vi), GFP_KERNEL);
1884 if (!vi)
1885 return -ENOMEM;
1886
1887 vi->iomem = devm_platform_ioremap_resource(pdev, index: 0);
1888 if (IS_ERR(ptr: vi->iomem))
1889 return PTR_ERR(ptr: vi->iomem);
1890
1891 vi->soc = of_device_get_match_data(dev: &pdev->dev);
1892
1893 vi->clk = devm_clk_get(dev: &pdev->dev, NULL);
1894 if (IS_ERR(ptr: vi->clk)) {
1895 ret = PTR_ERR(ptr: vi->clk);
1896 dev_err(&pdev->dev, "failed to get vi clock: %d\n", ret);
1897 return ret;
1898 }
1899
1900 vi->vdd = devm_regulator_get(dev: &pdev->dev, id: "avdd-dsi-csi");
1901 if (IS_ERR(ptr: vi->vdd)) {
1902 ret = PTR_ERR(ptr: vi->vdd);
1903 dev_err(&pdev->dev, "failed to get VDD supply: %d\n", ret);
1904 return ret;
1905 }
1906
1907 if (!pdev->dev.pm_domain) {
1908 ret = -ENOENT;
1909 dev_warn(&pdev->dev, "PM domain is not attached: %d\n", ret);
1910 return ret;
1911 }
1912
1913 ret = devm_of_platform_populate(dev: &pdev->dev);
1914 if (ret < 0) {
1915 dev_err(&pdev->dev,
1916 "failed to populate vi child device: %d\n", ret);
1917 return ret;
1918 }
1919
1920 vi->dev = &pdev->dev;
1921 vi->ops = vi->soc->ops;
1922 platform_set_drvdata(pdev, data: vi);
1923 pm_runtime_enable(dev: &pdev->dev);
1924
1925 /* initialize host1x interface */
1926 INIT_LIST_HEAD(list: &vi->client.list);
1927 vi->client.ops = &vi_client_ops;
1928 vi->client.dev = &pdev->dev;
1929
1930 if (vi->ops->vi_enable)
1931 vi->ops->vi_enable(vi, true);
1932
1933 ret = host1x_client_register(&vi->client);
1934 if (ret < 0) {
1935 dev_err(&pdev->dev,
1936 "failed to register host1x client: %d\n", ret);
1937 goto rpm_disable;
1938 }
1939
1940 return 0;
1941
1942rpm_disable:
1943 if (vi->ops->vi_enable)
1944 vi->ops->vi_enable(vi, false);
1945 pm_runtime_disable(dev: &pdev->dev);
1946 return ret;
1947}
1948
1949static void tegra_vi_remove(struct platform_device *pdev)
1950{
1951 struct tegra_vi *vi = platform_get_drvdata(pdev);
1952
1953 host1x_client_unregister(client: &vi->client);
1954
1955 if (vi->ops->vi_enable)
1956 vi->ops->vi_enable(vi, false);
1957 pm_runtime_disable(dev: &pdev->dev);
1958}
1959
1960static const struct of_device_id tegra_vi_of_id_table[] = {
1961#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
1962 { .compatible = "nvidia,tegra20-vi", .data = &tegra20_vi_soc },
1963#endif
1964#if defined(CONFIG_ARCH_TEGRA_210_SOC)
1965 { .compatible = "nvidia,tegra210-vi", .data = &tegra210_vi_soc },
1966#endif
1967 { }
1968};
1969MODULE_DEVICE_TABLE(of, tegra_vi_of_id_table);
1970
1971static const struct dev_pm_ops tegra_vi_pm_ops = {
1972 SET_RUNTIME_PM_OPS(vi_runtime_suspend, vi_runtime_resume, NULL)
1973};
1974
1975struct platform_driver tegra_vi_driver = {
1976 .driver = {
1977 .name = "tegra-vi",
1978 .of_match_table = tegra_vi_of_id_table,
1979 .pm = &tegra_vi_pm_ops,
1980 },
1981 .probe = tegra_vi_probe,
1982 .remove_new = tegra_vi_remove,
1983};
1984

source code of linux/drivers/staging/media/tegra-video/vi.c