1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Driver for Renesas R-Car VIN
4 *
5 * Copyright (C) 2016 Renesas Electronics Corp.
6 * Copyright (C) 2011-2013 Renesas Solutions Corp.
7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8 * Copyright (C) 2008 Magnus Damm
9 *
10 * Based on the soc-camera rcar_vin driver
11 */
12
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/of_graph.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/slab.h>
20 #include <linux/sys_soc.h>
21
22 #include <media/v4l2-async.h>
23 #include <media/v4l2-fwnode.h>
24 #include <media/v4l2-mc.h>
25
26 #include "rcar-vin.h"
27
28 /*
29 * The companion CSI-2 receiver driver (rcar-csi2) is known
30 * and we know it has one source pad (pad 0) and four sink
31 * pads (pad 1-4). So to translate a pad on the remote
32 * CSI-2 receiver to/from the VIN internal channel number simply
33 * subtract/add one from the pad/channel number.
34 */
35 #define rvin_group_csi_pad_to_channel(pad) ((pad) - 1)
36 #define rvin_group_csi_channel_to_pad(channel) ((channel) + 1)
37
38 /*
39 * Not all VINs are created equal, master VINs control the
40 * routing for other VIN's. We can figure out which VIN is
41 * master by looking at a VINs id.
42 */
43 #define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4)
44
45 #define v4l2_dev_to_vin(d) container_of(d, struct rvin_dev, v4l2_dev)
46
47 /* -----------------------------------------------------------------------------
48 * Gen3 Group Allocator
49 */
50
51 /* FIXME: This should if we find a system that supports more
52 * than one group for the whole system be replaced with a linked
53 * list of groups. And eventually all of this should be replaced
54 * with a global device allocator API.
55 *
56 * But for now this works as on all supported systems there will
57 * be only one group for all instances.
58 */
59
60 static DEFINE_MUTEX(rvin_group_lock);
61 static struct rvin_group *rvin_group_data;
62
rvin_group_cleanup(struct rvin_group * group)63 static void rvin_group_cleanup(struct rvin_group *group)
64 {
65 media_device_cleanup(&group->mdev);
66 mutex_destroy(&group->lock);
67 }
68
rvin_group_init(struct rvin_group * group,struct rvin_dev * vin,int (* link_setup)(struct rvin_dev *),const struct media_device_ops * ops)69 static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin,
70 int (*link_setup)(struct rvin_dev *),
71 const struct media_device_ops *ops)
72 {
73 struct media_device *mdev = &group->mdev;
74 const struct of_device_id *match;
75 struct device_node *np;
76
77 mutex_init(&group->lock);
78
79 /* Count number of VINs in the system */
80 group->count = 0;
81 for_each_matching_node(np, vin->dev->driver->of_match_table)
82 if (of_device_is_available(np))
83 group->count++;
84
85 vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
86
87 group->link_setup = link_setup;
88
89 mdev->dev = vin->dev;
90 mdev->ops = ops;
91
92 match = of_match_node(vin->dev->driver->of_match_table,
93 vin->dev->of_node);
94
95 strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
96 strscpy(mdev->model, match->compatible, sizeof(mdev->model));
97 snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
98 dev_name(mdev->dev));
99
100 media_device_init(mdev);
101
102 return 0;
103 }
104
rvin_group_release(struct kref * kref)105 static void rvin_group_release(struct kref *kref)
106 {
107 struct rvin_group *group =
108 container_of(kref, struct rvin_group, refcount);
109
110 mutex_lock(&rvin_group_lock);
111
112 rvin_group_data = NULL;
113
114 rvin_group_cleanup(group);
115
116 kfree(group);
117
118 mutex_unlock(&rvin_group_lock);
119 }
120
rvin_group_get(struct rvin_dev * vin,int (* link_setup)(struct rvin_dev *),const struct media_device_ops * ops)121 static int rvin_group_get(struct rvin_dev *vin,
122 int (*link_setup)(struct rvin_dev *),
123 const struct media_device_ops *ops)
124 {
125 struct rvin_group *group;
126 u32 id;
127 int ret;
128
129 /* Make sure VIN id is present and sane */
130 ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id);
131 if (ret) {
132 vin_err(vin, "%pOF: No renesas,id property found\n",
133 vin->dev->of_node);
134 return -EINVAL;
135 }
136
137 if (id >= RCAR_VIN_NUM) {
138 vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
139 vin->dev->of_node, id);
140 return -EINVAL;
141 }
142
143 /* Join or create a VIN group */
144 mutex_lock(&rvin_group_lock);
145 if (rvin_group_data) {
146 group = rvin_group_data;
147 kref_get(&group->refcount);
148 } else {
149 group = kzalloc(sizeof(*group), GFP_KERNEL);
150 if (!group) {
151 ret = -ENOMEM;
152 goto err_group;
153 }
154
155 ret = rvin_group_init(group, vin, link_setup, ops);
156 if (ret) {
157 kfree(group);
158 vin_err(vin, "Failed to initialize group\n");
159 goto err_group;
160 }
161
162 kref_init(&group->refcount);
163
164 rvin_group_data = group;
165 }
166 mutex_unlock(&rvin_group_lock);
167
168 /* Add VIN to group */
169 mutex_lock(&group->lock);
170
171 if (group->vin[id]) {
172 vin_err(vin, "Duplicate renesas,id property value %u\n", id);
173 mutex_unlock(&group->lock);
174 kref_put(&group->refcount, rvin_group_release);
175 return -EINVAL;
176 }
177
178 group->vin[id] = vin;
179
180 vin->id = id;
181 vin->group = group;
182 vin->v4l2_dev.mdev = &group->mdev;
183
184 mutex_unlock(&group->lock);
185
186 return 0;
187 err_group:
188 mutex_unlock(&rvin_group_lock);
189 return ret;
190 }
191
rvin_group_put(struct rvin_dev * vin)192 static void rvin_group_put(struct rvin_dev *vin)
193 {
194 struct rvin_group *group = vin->group;
195
196 mutex_lock(&group->lock);
197
198 vin->group = NULL;
199 vin->v4l2_dev.mdev = NULL;
200
201 if (WARN_ON(group->vin[vin->id] != vin))
202 goto out;
203
204 group->vin[vin->id] = NULL;
205 out:
206 mutex_unlock(&group->lock);
207
208 kref_put(&group->refcount, rvin_group_release);
209 }
210
211 /* group lock should be held when calling this function. */
rvin_group_entity_to_remote_id(struct rvin_group * group,struct media_entity * entity)212 static int rvin_group_entity_to_remote_id(struct rvin_group *group,
213 struct media_entity *entity)
214 {
215 struct v4l2_subdev *sd;
216 unsigned int i;
217
218 sd = media_entity_to_v4l2_subdev(entity);
219
220 for (i = 0; i < RVIN_REMOTES_MAX; i++)
221 if (group->remotes[i].subdev == sd)
222 return i;
223
224 return -ENODEV;
225 }
226
rvin_group_notify_complete(struct v4l2_async_notifier * notifier)227 static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
228 {
229 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
230 unsigned int i;
231 int ret;
232
233 ret = media_device_register(&vin->group->mdev);
234 if (ret)
235 return ret;
236
237 ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
238 if (ret) {
239 vin_err(vin, "Failed to register subdev nodes\n");
240 return ret;
241 }
242
243 /* Register all video nodes for the group. */
244 for (i = 0; i < RCAR_VIN_NUM; i++) {
245 if (vin->group->vin[i] &&
246 !video_is_registered(&vin->group->vin[i]->vdev)) {
247 ret = rvin_v4l2_register(vin->group->vin[i]);
248 if (ret)
249 return ret;
250 }
251 }
252
253 return vin->group->link_setup(vin);
254 }
255
rvin_group_notify_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)256 static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
257 struct v4l2_subdev *subdev,
258 struct v4l2_async_subdev *asd)
259 {
260 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
261 unsigned int i;
262
263 for (i = 0; i < RCAR_VIN_NUM; i++)
264 if (vin->group->vin[i])
265 rvin_v4l2_unregister(vin->group->vin[i]);
266
267 mutex_lock(&vin->group->lock);
268
269 for (i = 0; i < RVIN_CSI_MAX; i++) {
270 if (vin->group->remotes[i].asd != asd)
271 continue;
272 vin->group->remotes[i].subdev = NULL;
273 vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
274 break;
275 }
276
277 mutex_unlock(&vin->group->lock);
278
279 media_device_unregister(&vin->group->mdev);
280 }
281
rvin_group_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)282 static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
283 struct v4l2_subdev *subdev,
284 struct v4l2_async_subdev *asd)
285 {
286 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
287 unsigned int i;
288
289 mutex_lock(&vin->group->lock);
290
291 for (i = 0; i < RVIN_CSI_MAX; i++) {
292 if (vin->group->remotes[i].asd != asd)
293 continue;
294 vin->group->remotes[i].subdev = subdev;
295 vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
296 break;
297 }
298
299 mutex_unlock(&vin->group->lock);
300
301 return 0;
302 }
303
304 static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
305 .bound = rvin_group_notify_bound,
306 .unbind = rvin_group_notify_unbind,
307 .complete = rvin_group_notify_complete,
308 };
309
rvin_group_parse_of(struct rvin_dev * vin,unsigned int port,unsigned int id)310 static int rvin_group_parse_of(struct rvin_dev *vin, unsigned int port,
311 unsigned int id)
312 {
313 struct fwnode_handle *ep, *fwnode;
314 struct v4l2_fwnode_endpoint vep = {
315 .bus_type = V4L2_MBUS_CSI2_DPHY,
316 };
317 struct v4l2_async_subdev *asd;
318 int ret;
319
320 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), port, id, 0);
321 if (!ep)
322 return 0;
323
324 fwnode = fwnode_graph_get_remote_endpoint(ep);
325 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
326 fwnode_handle_put(ep);
327 if (ret) {
328 vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
329 ret = -EINVAL;
330 goto out;
331 }
332
333 asd = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode,
334 struct v4l2_async_subdev);
335 if (IS_ERR(asd)) {
336 ret = PTR_ERR(asd);
337 goto out;
338 }
339
340 vin->group->remotes[vep.base.id].asd = asd;
341
342 vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
343 to_of_node(fwnode), vep.base.id);
344 out:
345 fwnode_handle_put(fwnode);
346
347 return ret;
348 }
349
rvin_group_notifier_cleanup(struct rvin_dev * vin)350 static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
351 {
352 mutex_lock(&vin->group->lock);
353 if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
354 v4l2_async_nf_unregister(&vin->group->notifier);
355 v4l2_async_nf_cleanup(&vin->group->notifier);
356 }
357 mutex_unlock(&vin->group->lock);
358 }
359
rvin_group_notifier_init(struct rvin_dev * vin,unsigned int port,unsigned int max_id)360 static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port,
361 unsigned int max_id)
362 {
363 unsigned int count = 0, vin_mask = 0;
364 unsigned int i, id;
365 int ret;
366
367 mutex_lock(&vin->group->lock);
368
369 /* If not all VIN's are registered don't register the notifier. */
370 for (i = 0; i < RCAR_VIN_NUM; i++) {
371 if (vin->group->vin[i]) {
372 count++;
373 vin_mask |= BIT(i);
374 }
375 }
376
377 if (vin->group->count != count) {
378 mutex_unlock(&vin->group->lock);
379 return 0;
380 }
381
382 mutex_unlock(&vin->group->lock);
383
384 v4l2_async_nf_init(&vin->group->notifier);
385
386 /*
387 * Some subdevices may overlap but the parser function can handle it and
388 * each subdevice will only be registered once with the group notifier.
389 */
390 for (i = 0; i < RCAR_VIN_NUM; i++) {
391 if (!(vin_mask & BIT(i)))
392 continue;
393
394 for (id = 0; id < max_id; id++) {
395 if (vin->group->remotes[id].asd)
396 continue;
397
398 ret = rvin_group_parse_of(vin->group->vin[i], port, id);
399 if (ret)
400 return ret;
401 }
402 }
403
404 if (list_empty(&vin->group->notifier.asd_list))
405 return 0;
406
407 vin->group->notifier.ops = &rvin_group_notify_ops;
408 ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->group->notifier);
409 if (ret < 0) {
410 vin_err(vin, "Notifier registration failed\n");
411 v4l2_async_nf_cleanup(&vin->group->notifier);
412 return ret;
413 }
414
415 return 0;
416 }
417
418 /* -----------------------------------------------------------------------------
419 * Controls
420 */
421
rvin_s_ctrl(struct v4l2_ctrl * ctrl)422 static int rvin_s_ctrl(struct v4l2_ctrl *ctrl)
423 {
424 struct rvin_dev *vin =
425 container_of(ctrl->handler, struct rvin_dev, ctrl_handler);
426
427 switch (ctrl->id) {
428 case V4L2_CID_ALPHA_COMPONENT:
429 rvin_set_alpha(vin, ctrl->val);
430 break;
431 }
432
433 return 0;
434 }
435
436 static const struct v4l2_ctrl_ops rvin_ctrl_ops = {
437 .s_ctrl = rvin_s_ctrl,
438 };
439
rvin_free_controls(struct rvin_dev * vin)440 static void rvin_free_controls(struct rvin_dev *vin)
441 {
442 v4l2_ctrl_handler_free(&vin->ctrl_handler);
443 vin->vdev.ctrl_handler = NULL;
444 }
445
rvin_create_controls(struct rvin_dev * vin,struct v4l2_subdev * subdev)446 static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev)
447 {
448 int ret;
449
450 ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
451 if (ret < 0)
452 return ret;
453
454 /* The VIN directly deals with alpha component. */
455 v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
456 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
457
458 if (vin->ctrl_handler.error) {
459 ret = vin->ctrl_handler.error;
460 rvin_free_controls(vin);
461 return ret;
462 }
463
464 /* For the non-MC mode add controls from the subdevice. */
465 if (subdev) {
466 ret = v4l2_ctrl_add_handler(&vin->ctrl_handler,
467 subdev->ctrl_handler, NULL, true);
468 if (ret < 0) {
469 rvin_free_controls(vin);
470 return ret;
471 }
472 }
473
474 vin->vdev.ctrl_handler = &vin->ctrl_handler;
475
476 return 0;
477 }
478
479 /* -----------------------------------------------------------------------------
480 * Async notifier
481 */
482
rvin_find_pad(struct v4l2_subdev * sd,int direction)483 static int rvin_find_pad(struct v4l2_subdev *sd, int direction)
484 {
485 unsigned int pad;
486
487 if (sd->entity.num_pads <= 1)
488 return 0;
489
490 for (pad = 0; pad < sd->entity.num_pads; pad++)
491 if (sd->entity.pads[pad].flags & direction)
492 return pad;
493
494 return -EINVAL;
495 }
496
497 /* -----------------------------------------------------------------------------
498 * Parallel async notifier
499 */
500
501 /* The vin lock should be held when calling the subdevice attach and detach */
rvin_parallel_subdevice_attach(struct rvin_dev * vin,struct v4l2_subdev * subdev)502 static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
503 struct v4l2_subdev *subdev)
504 {
505 struct v4l2_subdev_mbus_code_enum code = {
506 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
507 };
508 int ret;
509
510 /* Find source and sink pad of remote subdevice */
511 ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
512 if (ret < 0)
513 return ret;
514 vin->parallel.source_pad = ret;
515
516 ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
517 vin->parallel.sink_pad = ret < 0 ? 0 : ret;
518
519 if (vin->info->use_mc) {
520 vin->parallel.subdev = subdev;
521 return 0;
522 }
523
524 /* Find compatible subdevices mbus format */
525 vin->mbus_code = 0;
526 code.index = 0;
527 code.pad = vin->parallel.source_pad;
528 while (!vin->mbus_code &&
529 !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
530 code.index++;
531 switch (code.code) {
532 case MEDIA_BUS_FMT_YUYV8_1X16:
533 case MEDIA_BUS_FMT_UYVY8_1X16:
534 case MEDIA_BUS_FMT_UYVY8_2X8:
535 case MEDIA_BUS_FMT_UYVY10_2X10:
536 case MEDIA_BUS_FMT_RGB888_1X24:
537 vin->mbus_code = code.code;
538 vin_dbg(vin, "Found media bus format for %s: %d\n",
539 subdev->name, vin->mbus_code);
540 break;
541 default:
542 break;
543 }
544 }
545
546 if (!vin->mbus_code) {
547 vin_err(vin, "Unsupported media bus format for %s\n",
548 subdev->name);
549 return -EINVAL;
550 }
551
552 /* Read tvnorms */
553 ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms);
554 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
555 return ret;
556
557 /* Read standard */
558 vin->std = V4L2_STD_UNKNOWN;
559 ret = v4l2_subdev_call(subdev, video, g_std, &vin->std);
560 if (ret < 0 && ret != -ENOIOCTLCMD)
561 return ret;
562
563 /* Add the controls */
564 ret = rvin_create_controls(vin, subdev);
565 if (ret < 0)
566 return ret;
567
568 vin->parallel.subdev = subdev;
569
570 return 0;
571 }
572
rvin_parallel_subdevice_detach(struct rvin_dev * vin)573 static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
574 {
575 rvin_v4l2_unregister(vin);
576 vin->parallel.subdev = NULL;
577
578 if (!vin->info->use_mc)
579 rvin_free_controls(vin);
580 }
581
rvin_parallel_notify_complete(struct v4l2_async_notifier * notifier)582 static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
583 {
584 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
585 struct media_entity *source;
586 struct media_entity *sink;
587 int ret;
588
589 ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
590 if (ret < 0) {
591 vin_err(vin, "Failed to register subdev nodes\n");
592 return ret;
593 }
594
595 if (!video_is_registered(&vin->vdev)) {
596 ret = rvin_v4l2_register(vin);
597 if (ret < 0)
598 return ret;
599 }
600
601 if (!vin->info->use_mc)
602 return 0;
603
604 /* If we're running with media-controller, link the subdevs. */
605 source = &vin->parallel.subdev->entity;
606 sink = &vin->vdev.entity;
607
608 ret = media_create_pad_link(source, vin->parallel.source_pad,
609 sink, vin->parallel.sink_pad, 0);
610 if (ret)
611 vin_err(vin, "Error adding link from %s to %s: %d\n",
612 source->name, sink->name, ret);
613
614 return ret;
615 }
616
rvin_parallel_notify_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)617 static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier,
618 struct v4l2_subdev *subdev,
619 struct v4l2_async_subdev *asd)
620 {
621 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
622
623 vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name);
624
625 mutex_lock(&vin->lock);
626 rvin_parallel_subdevice_detach(vin);
627 mutex_unlock(&vin->lock);
628 }
629
rvin_parallel_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)630 static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier,
631 struct v4l2_subdev *subdev,
632 struct v4l2_async_subdev *asd)
633 {
634 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
635 int ret;
636
637 mutex_lock(&vin->lock);
638 ret = rvin_parallel_subdevice_attach(vin, subdev);
639 mutex_unlock(&vin->lock);
640 if (ret)
641 return ret;
642
643 v4l2_set_subdev_hostdata(subdev, vin);
644
645 vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
646 subdev->name, vin->parallel.source_pad,
647 vin->parallel.sink_pad);
648
649 return 0;
650 }
651
652 static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops = {
653 .bound = rvin_parallel_notify_bound,
654 .unbind = rvin_parallel_notify_unbind,
655 .complete = rvin_parallel_notify_complete,
656 };
657
rvin_parallel_parse_of(struct rvin_dev * vin)658 static int rvin_parallel_parse_of(struct rvin_dev *vin)
659 {
660 struct fwnode_handle *ep, *fwnode;
661 struct v4l2_fwnode_endpoint vep = {
662 .bus_type = V4L2_MBUS_UNKNOWN,
663 };
664 struct v4l2_async_subdev *asd;
665 int ret;
666
667 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 0, 0, 0);
668 if (!ep)
669 return 0;
670
671 fwnode = fwnode_graph_get_remote_endpoint(ep);
672 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
673 fwnode_handle_put(ep);
674 if (ret) {
675 vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
676 ret = -EINVAL;
677 goto out;
678 }
679
680 switch (vep.bus_type) {
681 case V4L2_MBUS_PARALLEL:
682 case V4L2_MBUS_BT656:
683 vin_dbg(vin, "Found %s media bus\n",
684 vep.bus_type == V4L2_MBUS_PARALLEL ?
685 "PARALLEL" : "BT656");
686 vin->parallel.mbus_type = vep.bus_type;
687 vin->parallel.bus = vep.bus.parallel;
688 break;
689 default:
690 vin_err(vin, "Unknown media bus type\n");
691 ret = -EINVAL;
692 goto out;
693 }
694
695 asd = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode,
696 struct v4l2_async_subdev);
697 if (IS_ERR(asd)) {
698 ret = PTR_ERR(asd);
699 goto out;
700 }
701
702 vin->parallel.asd = asd;
703
704 vin_dbg(vin, "Add parallel OF device %pOF\n", to_of_node(fwnode));
705 out:
706 fwnode_handle_put(fwnode);
707
708 return ret;
709 }
710
rvin_parallel_cleanup(struct rvin_dev * vin)711 static void rvin_parallel_cleanup(struct rvin_dev *vin)
712 {
713 v4l2_async_nf_unregister(&vin->notifier);
714 v4l2_async_nf_cleanup(&vin->notifier);
715 }
716
rvin_parallel_init(struct rvin_dev * vin)717 static int rvin_parallel_init(struct rvin_dev *vin)
718 {
719 int ret;
720
721 v4l2_async_nf_init(&vin->notifier);
722
723 ret = rvin_parallel_parse_of(vin);
724 if (ret)
725 return ret;
726
727 if (!vin->parallel.asd)
728 return -ENODEV;
729
730 vin_dbg(vin, "Found parallel subdevice %pOF\n",
731 to_of_node(vin->parallel.asd->match.fwnode));
732
733 vin->notifier.ops = &rvin_parallel_notify_ops;
734 ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->notifier);
735 if (ret < 0) {
736 vin_err(vin, "Notifier registration failed\n");
737 v4l2_async_nf_cleanup(&vin->notifier);
738 return ret;
739 }
740
741 return 0;
742 }
743
744 /* -----------------------------------------------------------------------------
745 * CSI-2
746 */
747
rvin_csi2_get_mask(struct rvin_dev * vin,enum rvin_csi_id csi_id,unsigned char channel)748 static unsigned int rvin_csi2_get_mask(struct rvin_dev *vin,
749 enum rvin_csi_id csi_id,
750 unsigned char channel)
751 {
752 const struct rvin_group_route *route;
753 unsigned int mask = 0;
754
755 for (route = vin->info->routes; route->mask; route++) {
756 if (route->vin == vin->id &&
757 route->csi == csi_id &&
758 route->channel == channel) {
759 vin_dbg(vin,
760 "Adding route: vin: %d csi: %d channel: %d\n",
761 route->vin, route->csi, route->channel);
762 mask |= route->mask;
763 }
764 }
765
766 return mask;
767 }
768
769 /*
770 * Link setup for the links between a VIN and a CSI-2 receiver is a bit
771 * complex. The reason for this is that the register controlling routing
772 * is not present in each VIN instance. There are special VINs which
773 * control routing for themselves and other VINs. There are not many
774 * different possible links combinations that can be enabled at the same
775 * time, therefor all already enabled links which are controlled by a
776 * master VIN need to be taken into account when making the decision
777 * if a new link can be enabled or not.
778 *
779 * 1. Find out which VIN the link the user tries to enable is connected to.
780 * 2. Lookup which master VIN controls the links for this VIN.
781 * 3. Start with a bitmask with all bits set.
782 * 4. For each previously enabled link from the master VIN bitwise AND its
783 * route mask (see documentation for mask in struct rvin_group_route)
784 * with the bitmask.
785 * 5. Bitwise AND the mask for the link the user tries to enable to the bitmask.
786 * 6. If the bitmask is not empty at this point the new link can be enabled
787 * while keeping all previous links enabled. Update the CHSEL value of the
788 * master VIN and inform the user that the link could be enabled.
789 *
790 * Please note that no link can be enabled if any VIN in the group is
791 * currently open.
792 */
rvin_csi2_link_notify(struct media_link * link,u32 flags,unsigned int notification)793 static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
794 unsigned int notification)
795 {
796 struct rvin_group *group = container_of(link->graph_obj.mdev,
797 struct rvin_group, mdev);
798 unsigned int master_id, channel, mask_new, i;
799 unsigned int mask = ~0;
800 struct media_entity *entity;
801 struct video_device *vdev;
802 struct media_pad *csi_pad;
803 struct rvin_dev *vin = NULL;
804 int csi_id, ret;
805
806 ret = v4l2_pipeline_link_notify(link, flags, notification);
807 if (ret)
808 return ret;
809
810 /* Only care about link enablement for VIN nodes. */
811 if (!(flags & MEDIA_LNK_FL_ENABLED) ||
812 !is_media_entity_v4l2_video_device(link->sink->entity))
813 return 0;
814
815 /*
816 * Don't allow link changes if any entity in the graph is
817 * streaming, modifying the CHSEL register fields can disrupt
818 * running streams.
819 */
820 media_device_for_each_entity(entity, &group->mdev)
821 if (entity->stream_count)
822 return -EBUSY;
823
824 mutex_lock(&group->lock);
825
826 /* Find the master VIN that controls the routes. */
827 vdev = media_entity_to_video_device(link->sink->entity);
828 vin = container_of(vdev, struct rvin_dev, vdev);
829 master_id = rvin_group_id_to_master(vin->id);
830
831 if (WARN_ON(!group->vin[master_id])) {
832 ret = -ENODEV;
833 goto out;
834 }
835
836 /* Build a mask for already enabled links. */
837 for (i = master_id; i < master_id + 4; i++) {
838 if (!group->vin[i])
839 continue;
840
841 /* Get remote CSI-2, if any. */
842 csi_pad = media_entity_remote_pad(
843 &group->vin[i]->vdev.entity.pads[0]);
844 if (!csi_pad)
845 continue;
846
847 csi_id = rvin_group_entity_to_remote_id(group, csi_pad->entity);
848 channel = rvin_group_csi_pad_to_channel(csi_pad->index);
849
850 mask &= rvin_csi2_get_mask(group->vin[i], csi_id, channel);
851 }
852
853 /* Add the new link to the existing mask and check if it works. */
854 csi_id = rvin_group_entity_to_remote_id(group, link->source->entity);
855
856 if (csi_id == -ENODEV) {
857 struct v4l2_subdev *sd;
858
859 /*
860 * Make sure the source entity subdevice is registered as
861 * a parallel input of one of the enabled VINs if it is not
862 * one of the CSI-2 subdevices.
863 *
864 * No hardware configuration required for parallel inputs,
865 * we can return here.
866 */
867 sd = media_entity_to_v4l2_subdev(link->source->entity);
868 for (i = 0; i < RCAR_VIN_NUM; i++) {
869 if (group->vin[i] &&
870 group->vin[i]->parallel.subdev == sd) {
871 group->vin[i]->is_csi = false;
872 ret = 0;
873 goto out;
874 }
875 }
876
877 vin_err(vin, "Subdevice %s not registered to any VIN\n",
878 link->source->entity->name);
879 ret = -ENODEV;
880 goto out;
881 }
882
883 channel = rvin_group_csi_pad_to_channel(link->source->index);
884 mask_new = mask & rvin_csi2_get_mask(vin, csi_id, channel);
885 vin_dbg(vin, "Try link change mask: 0x%x new: 0x%x\n", mask, mask_new);
886
887 if (!mask_new) {
888 ret = -EMLINK;
889 goto out;
890 }
891
892 /* New valid CHSEL found, set the new value. */
893 ret = rvin_set_channel_routing(group->vin[master_id], __ffs(mask_new));
894 if (ret)
895 goto out;
896
897 vin->is_csi = true;
898
899 out:
900 mutex_unlock(&group->lock);
901
902 return ret;
903 }
904
905 static const struct media_device_ops rvin_csi2_media_ops = {
906 .link_notify = rvin_csi2_link_notify,
907 };
908
rvin_csi2_setup_links(struct rvin_dev * vin)909 static int rvin_csi2_setup_links(struct rvin_dev *vin)
910 {
911 const struct rvin_group_route *route;
912 int ret = -EINVAL;
913
914 /* Create all media device links between VINs and CSI-2's. */
915 mutex_lock(&vin->group->lock);
916 for (route = vin->info->routes; route->mask; route++) {
917 struct media_pad *source_pad, *sink_pad;
918 struct media_entity *source, *sink;
919 unsigned int source_idx;
920
921 /* Check that VIN is part of the group. */
922 if (!vin->group->vin[route->vin])
923 continue;
924
925 /* Check that VIN' master is part of the group. */
926 if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
927 continue;
928
929 /* Check that CSI-2 is part of the group. */
930 if (!vin->group->remotes[route->csi].subdev)
931 continue;
932
933 source = &vin->group->remotes[route->csi].subdev->entity;
934 source_idx = rvin_group_csi_channel_to_pad(route->channel);
935 source_pad = &source->pads[source_idx];
936
937 sink = &vin->group->vin[route->vin]->vdev.entity;
938 sink_pad = &sink->pads[0];
939
940 /* Skip if link already exists. */
941 if (media_entity_find_link(source_pad, sink_pad))
942 continue;
943
944 ret = media_create_pad_link(source, source_idx, sink, 0, 0);
945 if (ret) {
946 vin_err(vin, "Error adding link from %s to %s\n",
947 source->name, sink->name);
948 break;
949 }
950 }
951 mutex_unlock(&vin->group->lock);
952
953 return ret;
954 }
955
rvin_csi2_cleanup(struct rvin_dev * vin)956 static void rvin_csi2_cleanup(struct rvin_dev *vin)
957 {
958 rvin_parallel_cleanup(vin);
959 rvin_group_notifier_cleanup(vin);
960 rvin_group_put(vin);
961 rvin_free_controls(vin);
962 }
963
rvin_csi2_init(struct rvin_dev * vin)964 static int rvin_csi2_init(struct rvin_dev *vin)
965 {
966 int ret;
967
968 vin->pad.flags = MEDIA_PAD_FL_SINK;
969 ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
970 if (ret)
971 return ret;
972
973 ret = rvin_create_controls(vin, NULL);
974 if (ret < 0)
975 return ret;
976
977 ret = rvin_group_get(vin, rvin_csi2_setup_links, &rvin_csi2_media_ops);
978 if (ret)
979 goto err_controls;
980
981 /* It's OK to not have a parallel subdevice. */
982 ret = rvin_parallel_init(vin);
983 if (ret && ret != -ENODEV)
984 goto err_group;
985
986 ret = rvin_group_notifier_init(vin, 1, RVIN_CSI_MAX);
987 if (ret)
988 goto err_parallel;
989
990 return 0;
991 err_parallel:
992 rvin_parallel_cleanup(vin);
993 err_group:
994 rvin_group_put(vin);
995 err_controls:
996 rvin_free_controls(vin);
997
998 return ret;
999 }
1000
1001 /* -----------------------------------------------------------------------------
1002 * ISP
1003 */
1004
rvin_isp_setup_links(struct rvin_dev * vin)1005 static int rvin_isp_setup_links(struct rvin_dev *vin)
1006 {
1007 unsigned int i;
1008 int ret = -EINVAL;
1009
1010 /* Create all media device links between VINs and ISP's. */
1011 mutex_lock(&vin->group->lock);
1012 for (i = 0; i < RCAR_VIN_NUM; i++) {
1013 struct media_pad *source_pad, *sink_pad;
1014 struct media_entity *source, *sink;
1015 unsigned int source_slot = i / 8;
1016 unsigned int source_idx = i % 8 + 1;
1017
1018 if (!vin->group->vin[i])
1019 continue;
1020
1021 /* Check that ISP is part of the group. */
1022 if (!vin->group->remotes[source_slot].subdev)
1023 continue;
1024
1025 source = &vin->group->remotes[source_slot].subdev->entity;
1026 source_pad = &source->pads[source_idx];
1027
1028 sink = &vin->group->vin[i]->vdev.entity;
1029 sink_pad = &sink->pads[0];
1030
1031 /* Skip if link already exists. */
1032 if (media_entity_find_link(source_pad, sink_pad))
1033 continue;
1034
1035 ret = media_create_pad_link(source, source_idx, sink, 0,
1036 MEDIA_LNK_FL_ENABLED |
1037 MEDIA_LNK_FL_IMMUTABLE);
1038 if (ret) {
1039 vin_err(vin, "Error adding link from %s to %s\n",
1040 source->name, sink->name);
1041 break;
1042 }
1043 }
1044 mutex_unlock(&vin->group->lock);
1045
1046 return ret;
1047 }
1048
rvin_isp_cleanup(struct rvin_dev * vin)1049 static void rvin_isp_cleanup(struct rvin_dev *vin)
1050 {
1051 rvin_group_notifier_cleanup(vin);
1052 rvin_group_put(vin);
1053 rvin_free_controls(vin);
1054 }
1055
rvin_isp_init(struct rvin_dev * vin)1056 static int rvin_isp_init(struct rvin_dev *vin)
1057 {
1058 int ret;
1059
1060 vin->pad.flags = MEDIA_PAD_FL_SINK;
1061 ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
1062 if (ret)
1063 return ret;
1064
1065 ret = rvin_create_controls(vin, NULL);
1066 if (ret < 0)
1067 return ret;
1068
1069 ret = rvin_group_get(vin, rvin_isp_setup_links, NULL);
1070 if (ret)
1071 goto err_controls;
1072
1073 ret = rvin_group_notifier_init(vin, 2, RVIN_ISP_MAX);
1074 if (ret)
1075 goto err_group;
1076
1077 return 0;
1078 err_group:
1079 rvin_group_put(vin);
1080 err_controls:
1081 rvin_free_controls(vin);
1082
1083 return ret;
1084 }
1085
1086 /* -----------------------------------------------------------------------------
1087 * Suspend / Resume
1088 */
1089
rvin_suspend(struct device * dev)1090 static int __maybe_unused rvin_suspend(struct device *dev)
1091 {
1092 struct rvin_dev *vin = dev_get_drvdata(dev);
1093
1094 if (vin->state != RUNNING)
1095 return 0;
1096
1097 rvin_stop_streaming(vin);
1098
1099 vin->state = SUSPENDED;
1100
1101 return 0;
1102 }
1103
rvin_resume(struct device * dev)1104 static int __maybe_unused rvin_resume(struct device *dev)
1105 {
1106 struct rvin_dev *vin = dev_get_drvdata(dev);
1107
1108 if (vin->state != SUSPENDED)
1109 return 0;
1110
1111 /*
1112 * Restore group master CHSEL setting.
1113 *
1114 * This needs to be done by every VIN resuming not only the master
1115 * as we don't know if and in which order the master VINs will
1116 * be resumed.
1117 */
1118 if (vin->info->use_mc) {
1119 unsigned int master_id = rvin_group_id_to_master(vin->id);
1120 struct rvin_dev *master = vin->group->vin[master_id];
1121 int ret;
1122
1123 if (WARN_ON(!master))
1124 return -ENODEV;
1125
1126 ret = rvin_set_channel_routing(master, master->chsel);
1127 if (ret)
1128 return ret;
1129 }
1130
1131 return rvin_start_streaming(vin);
1132 }
1133
1134 /* -----------------------------------------------------------------------------
1135 * Platform Device Driver
1136 */
1137
1138 static const struct rvin_info rcar_info_h1 = {
1139 .model = RCAR_H1,
1140 .use_mc = false,
1141 .max_width = 2048,
1142 .max_height = 2048,
1143 };
1144
1145 static const struct rvin_info rcar_info_m1 = {
1146 .model = RCAR_M1,
1147 .use_mc = false,
1148 .max_width = 2048,
1149 .max_height = 2048,
1150 };
1151
1152 static const struct rvin_info rcar_info_gen2 = {
1153 .model = RCAR_GEN2,
1154 .use_mc = false,
1155 .max_width = 2048,
1156 .max_height = 2048,
1157 };
1158
1159 static const struct rvin_group_route rcar_info_r8a774e1_routes[] = {
1160 { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1161 { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1162 { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1163 { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1164 { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1165 { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1166 { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1167 { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
1168 { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1169 { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1170 { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1171 { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1172 { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1173 { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
1174 { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1175 { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1176 { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1177 { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1178 { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1179 { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
1180 { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1181 { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1182 { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
1183 { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1184 { /* Sentinel */ }
1185 };
1186
1187 static const struct rvin_info rcar_info_r8a774e1 = {
1188 .model = RCAR_GEN3,
1189 .use_mc = true,
1190 .max_width = 4096,
1191 .max_height = 4096,
1192 .routes = rcar_info_r8a774e1_routes,
1193 };
1194
1195 static const struct rvin_group_route rcar_info_r8a7795_routes[] = {
1196 { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1197 { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1198 { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1199 { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1200 { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1201 { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1202 { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1203 { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
1204 { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1205 { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1206 { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1207 { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1208 { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1209 { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
1210 { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1211 { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1212 { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1213 { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1214 { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
1215 { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1216 { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1217 { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
1218 { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1219 { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
1220 { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
1221 { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1222 { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
1223 { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1224 { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
1225 { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
1226 { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
1227 { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1228 { /* Sentinel */ }
1229 };
1230
1231 static const struct rvin_info rcar_info_r8a7795 = {
1232 .model = RCAR_GEN3,
1233 .use_mc = true,
1234 .nv12 = true,
1235 .max_width = 4096,
1236 .max_height = 4096,
1237 .routes = rcar_info_r8a7795_routes,
1238 };
1239
1240 static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = {
1241 { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1242 { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1243 { .csi = RVIN_CSI21, .channel = 0, .vin = 0, .mask = BIT(2) | BIT(5) },
1244 { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1245 { .csi = RVIN_CSI21, .channel = 0, .vin = 1, .mask = BIT(1) },
1246 { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1247 { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
1248 { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1249 { .csi = RVIN_CSI21, .channel = 1, .vin = 1, .mask = BIT(5) },
1250 { .csi = RVIN_CSI21, .channel = 0, .vin = 2, .mask = BIT(0) },
1251 { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1252 { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1253 { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1254 { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1255 { .csi = RVIN_CSI21, .channel = 2, .vin = 2, .mask = BIT(5) },
1256 { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1257 { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
1258 { .csi = RVIN_CSI21, .channel = 1, .vin = 3, .mask = BIT(2) },
1259 { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1260 { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1261 { .csi = RVIN_CSI21, .channel = 3, .vin = 3, .mask = BIT(5) },
1262 { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1263 { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1264 { .csi = RVIN_CSI21, .channel = 0, .vin = 4, .mask = BIT(2) | BIT(5) },
1265 { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1266 { .csi = RVIN_CSI21, .channel = 0, .vin = 5, .mask = BIT(1) },
1267 { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
1268 { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(3) },
1269 { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1270 { .csi = RVIN_CSI21, .channel = 1, .vin = 5, .mask = BIT(5) },
1271 { .csi = RVIN_CSI21, .channel = 0, .vin = 6, .mask = BIT(0) },
1272 { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
1273 { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1274 { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
1275 { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1276 { .csi = RVIN_CSI21, .channel = 2, .vin = 6, .mask = BIT(5) },
1277 { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
1278 { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
1279 { .csi = RVIN_CSI21, .channel = 1, .vin = 7, .mask = BIT(2) },
1280 { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
1281 { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1282 { .csi = RVIN_CSI21, .channel = 3, .vin = 7, .mask = BIT(5) },
1283 { /* Sentinel */ }
1284 };
1285
1286 static const struct rvin_info rcar_info_r8a7795es1 = {
1287 .model = RCAR_GEN3,
1288 .use_mc = true,
1289 .max_width = 4096,
1290 .max_height = 4096,
1291 .routes = rcar_info_r8a7795es1_routes,
1292 };
1293
1294 static const struct rvin_group_route rcar_info_r8a7796_routes[] = {
1295 { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1296 { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1297 { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1298 { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1299 { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
1300 { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1301 { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1302 { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1303 { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1304 { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1305 { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1306 { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
1307 { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1308 { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1309 { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1310 { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1311 { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1312 { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1313 { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(3) },
1314 { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1315 { .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
1316 { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1317 { .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
1318 { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1319 { .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
1320 { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
1321 { .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
1322 { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1323 { /* Sentinel */ }
1324 };
1325
1326 static const struct rvin_info rcar_info_r8a7796 = {
1327 .model = RCAR_GEN3,
1328 .use_mc = true,
1329 .nv12 = true,
1330 .max_width = 4096,
1331 .max_height = 4096,
1332 .routes = rcar_info_r8a7796_routes,
1333 };
1334
1335 static const struct rvin_group_route rcar_info_r8a77965_routes[] = {
1336 { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1337 { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1338 { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1339 { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1340 { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1341 { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1342 { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1343 { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
1344 { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1345 { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1346 { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1347 { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1348 { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1349 { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
1350 { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1351 { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1352 { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1353 { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1354 { .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) },
1355 { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1356 { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1357 { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1358 { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1359 { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
1360 { .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
1361 { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1362 { .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
1363 { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1364 { .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
1365 { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
1366 { .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
1367 { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1368 { /* Sentinel */ }
1369 };
1370
1371 static const struct rvin_info rcar_info_r8a77965 = {
1372 .model = RCAR_GEN3,
1373 .use_mc = true,
1374 .nv12 = true,
1375 .max_width = 4096,
1376 .max_height = 4096,
1377 .routes = rcar_info_r8a77965_routes,
1378 };
1379
1380 static const struct rvin_group_route rcar_info_r8a77970_routes[] = {
1381 { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1382 { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1383 { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
1384 { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1385 { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1386 { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1387 { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1388 { /* Sentinel */ }
1389 };
1390
1391 static const struct rvin_info rcar_info_r8a77970 = {
1392 .model = RCAR_GEN3,
1393 .use_mc = true,
1394 .max_width = 4096,
1395 .max_height = 4096,
1396 .routes = rcar_info_r8a77970_routes,
1397 };
1398
1399 static const struct rvin_group_route rcar_info_r8a77980_routes[] = {
1400 { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1401 { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1402 { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1403 { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1404 { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1405 { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1406 { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1407 { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1408 { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1409 { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
1410 { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
1411 { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1412 { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
1413 { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
1414 { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
1415 { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
1416 { /* Sentinel */ }
1417 };
1418
1419 static const struct rvin_info rcar_info_r8a77980 = {
1420 .model = RCAR_GEN3,
1421 .use_mc = true,
1422 .nv12 = true,
1423 .max_width = 4096,
1424 .max_height = 4096,
1425 .routes = rcar_info_r8a77980_routes,
1426 };
1427
1428 static const struct rvin_group_route rcar_info_r8a77990_routes[] = {
1429 { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1430 { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1431 { .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) },
1432 { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1433 { /* Sentinel */ }
1434 };
1435
1436 static const struct rvin_info rcar_info_r8a77990 = {
1437 .model = RCAR_GEN3,
1438 .use_mc = true,
1439 .nv12 = true,
1440 .max_width = 4096,
1441 .max_height = 4096,
1442 .routes = rcar_info_r8a77990_routes,
1443 };
1444
1445 static const struct rvin_group_route rcar_info_r8a77995_routes[] = {
1446 { /* Sentinel */ }
1447 };
1448
1449 static const struct rvin_info rcar_info_r8a77995 = {
1450 .model = RCAR_GEN3,
1451 .use_mc = true,
1452 .nv12 = true,
1453 .max_width = 4096,
1454 .max_height = 4096,
1455 .routes = rcar_info_r8a77995_routes,
1456 };
1457
1458 static const struct rvin_info rcar_info_r8a779a0 = {
1459 .model = RCAR_GEN3,
1460 .use_mc = true,
1461 .use_isp = true,
1462 .nv12 = true,
1463 .max_width = 4096,
1464 .max_height = 4096,
1465 };
1466
1467 static const struct of_device_id rvin_of_id_table[] = {
1468 {
1469 .compatible = "renesas,vin-r8a774a1",
1470 .data = &rcar_info_r8a7796,
1471 },
1472 {
1473 .compatible = "renesas,vin-r8a774b1",
1474 .data = &rcar_info_r8a77965,
1475 },
1476 {
1477 .compatible = "renesas,vin-r8a774c0",
1478 .data = &rcar_info_r8a77990,
1479 },
1480 {
1481 .compatible = "renesas,vin-r8a774e1",
1482 .data = &rcar_info_r8a774e1,
1483 },
1484 {
1485 .compatible = "renesas,vin-r8a7778",
1486 .data = &rcar_info_m1,
1487 },
1488 {
1489 .compatible = "renesas,vin-r8a7779",
1490 .data = &rcar_info_h1,
1491 },
1492 {
1493 .compatible = "renesas,rcar-gen2-vin",
1494 .data = &rcar_info_gen2,
1495 },
1496 {
1497 .compatible = "renesas,vin-r8a7795",
1498 .data = &rcar_info_r8a7795,
1499 },
1500 {
1501 .compatible = "renesas,vin-r8a7796",
1502 .data = &rcar_info_r8a7796,
1503 },
1504 {
1505 .compatible = "renesas,vin-r8a77961",
1506 .data = &rcar_info_r8a7796,
1507 },
1508 {
1509 .compatible = "renesas,vin-r8a77965",
1510 .data = &rcar_info_r8a77965,
1511 },
1512 {
1513 .compatible = "renesas,vin-r8a77970",
1514 .data = &rcar_info_r8a77970,
1515 },
1516 {
1517 .compatible = "renesas,vin-r8a77980",
1518 .data = &rcar_info_r8a77980,
1519 },
1520 {
1521 .compatible = "renesas,vin-r8a77990",
1522 .data = &rcar_info_r8a77990,
1523 },
1524 {
1525 .compatible = "renesas,vin-r8a77995",
1526 .data = &rcar_info_r8a77995,
1527 },
1528 {
1529 .compatible = "renesas,vin-r8a779a0",
1530 .data = &rcar_info_r8a779a0,
1531 },
1532 { /* Sentinel */ },
1533 };
1534 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
1535
1536 static const struct soc_device_attribute r8a7795es1[] = {
1537 {
1538 .soc_id = "r8a7795", .revision = "ES1.*",
1539 .data = &rcar_info_r8a7795es1,
1540 },
1541 { /* Sentinel */ }
1542 };
1543
rcar_vin_probe(struct platform_device * pdev)1544 static int rcar_vin_probe(struct platform_device *pdev)
1545 {
1546 const struct soc_device_attribute *attr;
1547 struct rvin_dev *vin;
1548 int irq, ret;
1549
1550 vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
1551 if (!vin)
1552 return -ENOMEM;
1553
1554 vin->dev = &pdev->dev;
1555 vin->info = of_device_get_match_data(&pdev->dev);
1556 vin->alpha = 0xff;
1557
1558 /*
1559 * Special care is needed on r8a7795 ES1.x since it
1560 * uses different routing than r8a7795 ES2.0.
1561 */
1562 attr = soc_device_match(r8a7795es1);
1563 if (attr)
1564 vin->info = attr->data;
1565
1566 vin->base = devm_platform_ioremap_resource(pdev, 0);
1567 if (IS_ERR(vin->base))
1568 return PTR_ERR(vin->base);
1569
1570 irq = platform_get_irq(pdev, 0);
1571 if (irq < 0)
1572 return irq;
1573
1574 ret = rvin_dma_register(vin, irq);
1575 if (ret)
1576 return ret;
1577
1578 platform_set_drvdata(pdev, vin);
1579
1580 if (vin->info->use_isp)
1581 ret = rvin_isp_init(vin);
1582 else if (vin->info->use_mc)
1583 ret = rvin_csi2_init(vin);
1584 else
1585 ret = rvin_parallel_init(vin);
1586
1587 if (ret) {
1588 rvin_dma_unregister(vin);
1589 return ret;
1590 }
1591
1592 pm_suspend_ignore_children(&pdev->dev, true);
1593 pm_runtime_enable(&pdev->dev);
1594
1595 return 0;
1596 }
1597
rcar_vin_remove(struct platform_device * pdev)1598 static int rcar_vin_remove(struct platform_device *pdev)
1599 {
1600 struct rvin_dev *vin = platform_get_drvdata(pdev);
1601
1602 pm_runtime_disable(&pdev->dev);
1603
1604 rvin_v4l2_unregister(vin);
1605
1606 if (vin->info->use_isp)
1607 rvin_isp_cleanup(vin);
1608 else if (vin->info->use_mc)
1609 rvin_csi2_cleanup(vin);
1610 else
1611 rvin_parallel_cleanup(vin);
1612
1613 rvin_dma_unregister(vin);
1614
1615 return 0;
1616 }
1617
1618 static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);
1619
1620 static struct platform_driver rcar_vin_driver = {
1621 .driver = {
1622 .name = "rcar-vin",
1623 .pm = &rvin_pm_ops,
1624 .of_match_table = rvin_of_id_table,
1625 },
1626 .probe = rcar_vin_probe,
1627 .remove = rcar_vin_remove,
1628 };
1629
1630 module_platform_driver(rcar_vin_driver);
1631
1632 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
1633 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1634 MODULE_LICENSE("GPL");
1635