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