• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_unregister(&group->mdev);
247 	media_device_cleanup(&group->mdev);
248 	mutex_destroy(&group->lock);
249 }
250 
rvin_group_init(struct rvin_group * group,struct rvin_dev * vin)251 static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin)
252 {
253 	struct media_device *mdev = &group->mdev;
254 	const struct of_device_id *match;
255 	struct device_node *np;
256 	int ret;
257 
258 	mutex_init(&group->lock);
259 
260 	/* Count number of VINs in the system */
261 	group->count = 0;
262 	for_each_matching_node(np, vin->dev->driver->of_match_table)
263 		if (of_device_is_available(np))
264 			group->count++;
265 
266 	vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
267 
268 	mdev->dev = vin->dev;
269 	mdev->ops = &rvin_media_ops;
270 
271 	match = of_match_node(vin->dev->driver->of_match_table,
272 			      vin->dev->of_node);
273 
274 	strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
275 	strlcpy(mdev->model, match->compatible, sizeof(mdev->model));
276 	snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
277 		 dev_name(mdev->dev));
278 
279 	media_device_init(mdev);
280 
281 	ret = media_device_register(&group->mdev);
282 	if (ret)
283 		rvin_group_cleanup(group);
284 
285 	return ret;
286 }
287 
rvin_group_release(struct kref * kref)288 static void rvin_group_release(struct kref *kref)
289 {
290 	struct rvin_group *group =
291 		container_of(kref, struct rvin_group, refcount);
292 
293 	mutex_lock(&rvin_group_lock);
294 
295 	rvin_group_data = NULL;
296 
297 	rvin_group_cleanup(group);
298 
299 	kfree(group);
300 
301 	mutex_unlock(&rvin_group_lock);
302 }
303 
rvin_group_get(struct rvin_dev * vin)304 static int rvin_group_get(struct rvin_dev *vin)
305 {
306 	struct rvin_group *group;
307 	u32 id;
308 	int ret;
309 
310 	/* Make sure VIN id is present and sane */
311 	ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id);
312 	if (ret) {
313 		vin_err(vin, "%pOF: No renesas,id property found\n",
314 			vin->dev->of_node);
315 		return -EINVAL;
316 	}
317 
318 	if (id >= RCAR_VIN_NUM) {
319 		vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
320 			vin->dev->of_node, id);
321 		return -EINVAL;
322 	}
323 
324 	/* Join or create a VIN group */
325 	mutex_lock(&rvin_group_lock);
326 	if (rvin_group_data) {
327 		group = rvin_group_data;
328 		kref_get(&group->refcount);
329 	} else {
330 		group = kzalloc(sizeof(*group), GFP_KERNEL);
331 		if (!group) {
332 			ret = -ENOMEM;
333 			goto err_group;
334 		}
335 
336 		ret = rvin_group_init(group, vin);
337 		if (ret) {
338 			kfree(group);
339 			vin_err(vin, "Failed to initialize group\n");
340 			goto err_group;
341 		}
342 
343 		kref_init(&group->refcount);
344 
345 		rvin_group_data = group;
346 	}
347 	mutex_unlock(&rvin_group_lock);
348 
349 	/* Add VIN to group */
350 	mutex_lock(&group->lock);
351 
352 	if (group->vin[id]) {
353 		vin_err(vin, "Duplicate renesas,id property value %u\n", id);
354 		mutex_unlock(&group->lock);
355 		kref_put(&group->refcount, rvin_group_release);
356 		return -EINVAL;
357 	}
358 
359 	group->vin[id] = vin;
360 
361 	vin->id = id;
362 	vin->group = group;
363 	vin->v4l2_dev.mdev = &group->mdev;
364 
365 	mutex_unlock(&group->lock);
366 
367 	return 0;
368 err_group:
369 	mutex_unlock(&rvin_group_lock);
370 	return ret;
371 }
372 
rvin_group_put(struct rvin_dev * vin)373 static void rvin_group_put(struct rvin_dev *vin)
374 {
375 	struct rvin_group *group = vin->group;
376 
377 	mutex_lock(&group->lock);
378 
379 	vin->group = NULL;
380 	vin->v4l2_dev.mdev = NULL;
381 
382 	if (WARN_ON(group->vin[vin->id] != vin))
383 		goto out;
384 
385 	group->vin[vin->id] = NULL;
386 out:
387 	mutex_unlock(&group->lock);
388 
389 	kref_put(&group->refcount, rvin_group_release);
390 }
391 
392 /* -----------------------------------------------------------------------------
393  * Async notifier
394  */
395 
rvin_find_pad(struct v4l2_subdev * sd,int direction)396 static int rvin_find_pad(struct v4l2_subdev *sd, int direction)
397 {
398 	unsigned int pad;
399 
400 	if (sd->entity.num_pads <= 1)
401 		return 0;
402 
403 	for (pad = 0; pad < sd->entity.num_pads; pad++)
404 		if (sd->entity.pads[pad].flags & direction)
405 			return pad;
406 
407 	return -EINVAL;
408 }
409 
410 /* -----------------------------------------------------------------------------
411  * Parallel async notifier
412  */
413 
414 /* 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)415 static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
416 					  struct v4l2_subdev *subdev)
417 {
418 	struct v4l2_subdev_mbus_code_enum code = {
419 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
420 	};
421 	int ret;
422 
423 	/* Find source and sink pad of remote subdevice */
424 	ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
425 	if (ret < 0)
426 		return ret;
427 	vin->parallel->source_pad = ret;
428 
429 	ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
430 	vin->parallel->sink_pad = ret < 0 ? 0 : ret;
431 
432 	if (vin->info->use_mc) {
433 		vin->parallel->subdev = subdev;
434 		return 0;
435 	}
436 
437 	/* Find compatible subdevices mbus format */
438 	vin->mbus_code = 0;
439 	code.index = 0;
440 	code.pad = vin->parallel->source_pad;
441 	while (!vin->mbus_code &&
442 	       !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
443 		code.index++;
444 		switch (code.code) {
445 		case MEDIA_BUS_FMT_YUYV8_1X16:
446 		case MEDIA_BUS_FMT_UYVY8_1X16:
447 		case MEDIA_BUS_FMT_UYVY8_2X8:
448 		case MEDIA_BUS_FMT_UYVY10_2X10:
449 		case MEDIA_BUS_FMT_RGB888_1X24:
450 			vin->mbus_code = code.code;
451 			vin_dbg(vin, "Found media bus format for %s: %d\n",
452 				subdev->name, vin->mbus_code);
453 			break;
454 		default:
455 			break;
456 		}
457 	}
458 
459 	if (!vin->mbus_code) {
460 		vin_err(vin, "Unsupported media bus format for %s\n",
461 			subdev->name);
462 		return -EINVAL;
463 	}
464 
465 	/* Read tvnorms */
466 	ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms);
467 	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
468 		return ret;
469 
470 	/* Read standard */
471 	vin->std = V4L2_STD_UNKNOWN;
472 	ret = v4l2_subdev_call(subdev, video, g_std, &vin->std);
473 	if (ret < 0 && ret != -ENOIOCTLCMD)
474 		return ret;
475 
476 	/* Add the controls */
477 	ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
478 	if (ret < 0)
479 		return ret;
480 
481 	ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler,
482 				    NULL);
483 	if (ret < 0) {
484 		v4l2_ctrl_handler_free(&vin->ctrl_handler);
485 		return ret;
486 	}
487 
488 	vin->vdev.ctrl_handler = &vin->ctrl_handler;
489 
490 	vin->parallel->subdev = subdev;
491 
492 	return 0;
493 }
494 
rvin_parallel_subdevice_detach(struct rvin_dev * vin)495 static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
496 {
497 	rvin_v4l2_unregister(vin);
498 	vin->parallel->subdev = NULL;
499 
500 	if (!vin->info->use_mc) {
501 		v4l2_ctrl_handler_free(&vin->ctrl_handler);
502 		vin->vdev.ctrl_handler = NULL;
503 	}
504 }
505 
rvin_parallel_notify_complete(struct v4l2_async_notifier * notifier)506 static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
507 {
508 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
509 	struct media_entity *source;
510 	struct media_entity *sink;
511 	int ret;
512 
513 	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
514 	if (ret < 0) {
515 		vin_err(vin, "Failed to register subdev nodes\n");
516 		return ret;
517 	}
518 
519 	if (!video_is_registered(&vin->vdev)) {
520 		ret = rvin_v4l2_register(vin);
521 		if (ret < 0)
522 			return ret;
523 	}
524 
525 	if (!vin->info->use_mc)
526 		return 0;
527 
528 	/* If we're running with media-controller, link the subdevs. */
529 	source = &vin->parallel->subdev->entity;
530 	sink = &vin->vdev.entity;
531 
532 	ret = media_create_pad_link(source, vin->parallel->source_pad,
533 				    sink, vin->parallel->sink_pad, 0);
534 	if (ret)
535 		vin_err(vin, "Error adding link from %s to %s: %d\n",
536 			source->name, sink->name, ret);
537 
538 	return ret;
539 }
540 
rvin_parallel_notify_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)541 static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier,
542 					struct v4l2_subdev *subdev,
543 					struct v4l2_async_subdev *asd)
544 {
545 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
546 
547 	vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name);
548 
549 	mutex_lock(&vin->lock);
550 	rvin_parallel_subdevice_detach(vin);
551 	mutex_unlock(&vin->lock);
552 }
553 
rvin_parallel_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)554 static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier,
555 				      struct v4l2_subdev *subdev,
556 				      struct v4l2_async_subdev *asd)
557 {
558 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
559 	int ret;
560 
561 	mutex_lock(&vin->lock);
562 	ret = rvin_parallel_subdevice_attach(vin, subdev);
563 	mutex_unlock(&vin->lock);
564 	if (ret)
565 		return ret;
566 
567 	v4l2_set_subdev_hostdata(subdev, vin);
568 
569 	vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
570 		subdev->name, vin->parallel->source_pad,
571 		vin->parallel->sink_pad);
572 
573 	return 0;
574 }
575 
576 static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops = {
577 	.bound = rvin_parallel_notify_bound,
578 	.unbind = rvin_parallel_notify_unbind,
579 	.complete = rvin_parallel_notify_complete,
580 };
581 
rvin_parallel_parse_v4l2(struct device * dev,struct v4l2_fwnode_endpoint * vep,struct v4l2_async_subdev * asd)582 static int rvin_parallel_parse_v4l2(struct device *dev,
583 				    struct v4l2_fwnode_endpoint *vep,
584 				    struct v4l2_async_subdev *asd)
585 {
586 	struct rvin_dev *vin = dev_get_drvdata(dev);
587 	struct rvin_parallel_entity *rvpe =
588 		container_of(asd, struct rvin_parallel_entity, asd);
589 
590 	if (vep->base.port || vep->base.id)
591 		return -ENOTCONN;
592 
593 	vin->parallel = rvpe;
594 	vin->parallel->mbus_type = vep->bus_type;
595 
596 	switch (vin->parallel->mbus_type) {
597 	case V4L2_MBUS_PARALLEL:
598 		vin_dbg(vin, "Found PARALLEL media bus\n");
599 		vin->parallel->mbus_flags = vep->bus.parallel.flags;
600 		break;
601 	case V4L2_MBUS_BT656:
602 		vin_dbg(vin, "Found BT656 media bus\n");
603 		vin->parallel->mbus_flags = 0;
604 		break;
605 	default:
606 		vin_err(vin, "Unknown media bus type\n");
607 		return -EINVAL;
608 	}
609 
610 	return 0;
611 }
612 
rvin_parallel_init(struct rvin_dev * vin)613 static int rvin_parallel_init(struct rvin_dev *vin)
614 {
615 	int ret;
616 
617 	ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
618 		vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity),
619 		0, rvin_parallel_parse_v4l2);
620 	if (ret)
621 		return ret;
622 
623 	/* If using mc, it's fine not to have any input registered. */
624 	if (!vin->parallel)
625 		return vin->info->use_mc ? 0 : -ENODEV;
626 
627 	vin_dbg(vin, "Found parallel subdevice %pOF\n",
628 		to_of_node(vin->parallel->asd.match.fwnode));
629 
630 	vin->notifier.ops = &rvin_parallel_notify_ops;
631 	ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
632 	if (ret < 0) {
633 		vin_err(vin, "Notifier registration failed\n");
634 		v4l2_async_notifier_cleanup(&vin->notifier);
635 		return ret;
636 	}
637 
638 	return 0;
639 }
640 
641 /* -----------------------------------------------------------------------------
642  * Group async notifier
643  */
644 
rvin_group_notify_complete(struct v4l2_async_notifier * notifier)645 static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
646 {
647 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
648 	const struct rvin_group_route *route;
649 	unsigned int i;
650 	int ret;
651 
652 	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
653 	if (ret) {
654 		vin_err(vin, "Failed to register subdev nodes\n");
655 		return ret;
656 	}
657 
658 	/* Register all video nodes for the group. */
659 	for (i = 0; i < RCAR_VIN_NUM; i++) {
660 		if (vin->group->vin[i] &&
661 		    !video_is_registered(&vin->group->vin[i]->vdev)) {
662 			ret = rvin_v4l2_register(vin->group->vin[i]);
663 			if (ret)
664 				return ret;
665 		}
666 	}
667 
668 	/* Create all media device links between VINs and CSI-2's. */
669 	mutex_lock(&vin->group->lock);
670 	for (route = vin->info->routes; route->mask; route++) {
671 		struct media_pad *source_pad, *sink_pad;
672 		struct media_entity *source, *sink;
673 		unsigned int source_idx;
674 
675 		/* Check that VIN is part of the group. */
676 		if (!vin->group->vin[route->vin])
677 			continue;
678 
679 		/* Check that VIN' master is part of the group. */
680 		if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
681 			continue;
682 
683 		/* Check that CSI-2 is part of the group. */
684 		if (!vin->group->csi[route->csi].subdev)
685 			continue;
686 
687 		source = &vin->group->csi[route->csi].subdev->entity;
688 		source_idx = rvin_group_csi_channel_to_pad(route->channel);
689 		source_pad = &source->pads[source_idx];
690 
691 		sink = &vin->group->vin[route->vin]->vdev.entity;
692 		sink_pad = &sink->pads[0];
693 
694 		/* Skip if link already exists. */
695 		if (media_entity_find_link(source_pad, sink_pad))
696 			continue;
697 
698 		ret = media_create_pad_link(source, source_idx, sink, 0, 0);
699 		if (ret) {
700 			vin_err(vin, "Error adding link from %s to %s\n",
701 				source->name, sink->name);
702 			break;
703 		}
704 	}
705 	mutex_unlock(&vin->group->lock);
706 
707 	return ret;
708 }
709 
rvin_group_notify_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)710 static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
711 				     struct v4l2_subdev *subdev,
712 				     struct v4l2_async_subdev *asd)
713 {
714 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
715 	unsigned int i;
716 
717 	for (i = 0; i < RCAR_VIN_NUM; i++)
718 		if (vin->group->vin[i])
719 			rvin_v4l2_unregister(vin->group->vin[i]);
720 
721 	mutex_lock(&vin->group->lock);
722 
723 	for (i = 0; i < RVIN_CSI_MAX; i++) {
724 		if (vin->group->csi[i].fwnode != asd->match.fwnode)
725 			continue;
726 		vin->group->csi[i].subdev = NULL;
727 		vin_dbg(vin, "Unbind CSI-2 %s from slot %u\n", subdev->name, i);
728 		break;
729 	}
730 
731 	mutex_unlock(&vin->group->lock);
732 }
733 
rvin_group_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)734 static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
735 				   struct v4l2_subdev *subdev,
736 				   struct v4l2_async_subdev *asd)
737 {
738 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
739 	unsigned int i;
740 
741 	mutex_lock(&vin->group->lock);
742 
743 	for (i = 0; i < RVIN_CSI_MAX; i++) {
744 		if (vin->group->csi[i].fwnode != asd->match.fwnode)
745 			continue;
746 		vin->group->csi[i].subdev = subdev;
747 		vin_dbg(vin, "Bound CSI-2 %s to slot %u\n", subdev->name, i);
748 		break;
749 	}
750 
751 	mutex_unlock(&vin->group->lock);
752 
753 	return 0;
754 }
755 
756 static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
757 	.bound = rvin_group_notify_bound,
758 	.unbind = rvin_group_notify_unbind,
759 	.complete = rvin_group_notify_complete,
760 };
761 
rvin_mc_parse_of_endpoint(struct device * dev,struct v4l2_fwnode_endpoint * vep,struct v4l2_async_subdev * asd)762 static int rvin_mc_parse_of_endpoint(struct device *dev,
763 				     struct v4l2_fwnode_endpoint *vep,
764 				     struct v4l2_async_subdev *asd)
765 {
766 	struct rvin_dev *vin = dev_get_drvdata(dev);
767 
768 	if (vep->base.port != 1 || vep->base.id >= RVIN_CSI_MAX)
769 		return -EINVAL;
770 
771 	if (!of_device_is_available(to_of_node(asd->match.fwnode))) {
772 		vin_dbg(vin, "OF device %pOF disabled, ignoring\n",
773 			to_of_node(asd->match.fwnode));
774 		return -ENOTCONN;
775 	}
776 
777 	if (vin->group->csi[vep->base.id].fwnode) {
778 		vin_dbg(vin, "OF device %pOF already handled\n",
779 			to_of_node(asd->match.fwnode));
780 		return -ENOTCONN;
781 	}
782 
783 	vin->group->csi[vep->base.id].fwnode = asd->match.fwnode;
784 
785 	vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
786 		to_of_node(asd->match.fwnode), vep->base.id);
787 
788 	return 0;
789 }
790 
rvin_mc_parse_of_graph(struct rvin_dev * vin)791 static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
792 {
793 	unsigned int count = 0;
794 	unsigned int i;
795 	int ret;
796 
797 	mutex_lock(&vin->group->lock);
798 
799 	/* If not all VIN's are registered don't register the notifier. */
800 	for (i = 0; i < RCAR_VIN_NUM; i++)
801 		if (vin->group->vin[i])
802 			count++;
803 
804 	if (vin->group->count != count) {
805 		mutex_unlock(&vin->group->lock);
806 		return 0;
807 	}
808 
809 	/*
810 	 * Have all VIN's look for CSI-2 subdevices. Some subdevices will
811 	 * overlap but the parser function can handle it, so each subdevice
812 	 * will only be registered once with the group notifier.
813 	 */
814 	for (i = 0; i < RCAR_VIN_NUM; i++) {
815 		if (!vin->group->vin[i])
816 			continue;
817 
818 		ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
819 				vin->group->vin[i]->dev, &vin->group->notifier,
820 				sizeof(struct v4l2_async_subdev), 1,
821 				rvin_mc_parse_of_endpoint);
822 		if (ret) {
823 			mutex_unlock(&vin->group->lock);
824 			return ret;
825 		}
826 	}
827 
828 	mutex_unlock(&vin->group->lock);
829 
830 	if (!vin->group->notifier.num_subdevs)
831 		return 0;
832 
833 	vin->group->notifier.ops = &rvin_group_notify_ops;
834 	ret = v4l2_async_notifier_register(&vin->v4l2_dev,
835 					   &vin->group->notifier);
836 	if (ret < 0) {
837 		vin_err(vin, "Notifier registration failed\n");
838 		v4l2_async_notifier_cleanup(&vin->group->notifier);
839 		return ret;
840 	}
841 
842 	return 0;
843 }
844 
rvin_mc_init(struct rvin_dev * vin)845 static int rvin_mc_init(struct rvin_dev *vin)
846 {
847 	int ret;
848 
849 	vin->pad.flags = MEDIA_PAD_FL_SINK;
850 	ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
851 	if (ret)
852 		return ret;
853 
854 	ret = rvin_group_get(vin);
855 	if (ret)
856 		return ret;
857 
858 	ret = rvin_mc_parse_of_graph(vin);
859 	if (ret)
860 		rvin_group_put(vin);
861 
862 	return ret;
863 }
864 
865 /* -----------------------------------------------------------------------------
866  * Platform Device Driver
867  */
868 
869 static const struct rvin_info rcar_info_h1 = {
870 	.model = RCAR_H1,
871 	.use_mc = false,
872 	.max_width = 2048,
873 	.max_height = 2048,
874 };
875 
876 static const struct rvin_info rcar_info_m1 = {
877 	.model = RCAR_M1,
878 	.use_mc = false,
879 	.max_width = 2048,
880 	.max_height = 2048,
881 };
882 
883 static const struct rvin_info rcar_info_gen2 = {
884 	.model = RCAR_GEN2,
885 	.use_mc = false,
886 	.max_width = 2048,
887 	.max_height = 2048,
888 };
889 
890 static const struct rvin_group_route rcar_info_r8a7795_routes[] = {
891 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
892 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
893 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
894 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
895 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
896 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
897 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
898 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
899 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
900 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
901 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
902 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
903 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
904 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
905 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
906 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
907 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
908 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
909 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
910 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
911 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
912 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
913 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
914 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
915 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
916 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
917 	{ .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
918 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
919 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
920 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
921 	{ .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
922 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
923 	{ /* Sentinel */ }
924 };
925 
926 static const struct rvin_info rcar_info_r8a7795 = {
927 	.model = RCAR_GEN3,
928 	.use_mc = true,
929 	.max_width = 4096,
930 	.max_height = 4096,
931 	.routes = rcar_info_r8a7795_routes,
932 };
933 
934 static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = {
935 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
936 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
937 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 0, .mask = BIT(2) | BIT(5) },
938 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
939 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 1, .mask = BIT(1) },
940 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
941 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
942 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
943 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 1, .mask = BIT(5) },
944 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 2, .mask = BIT(0) },
945 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
946 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
947 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
948 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
949 	{ .csi = RVIN_CSI21, .channel = 2, .vin = 2, .mask = BIT(5) },
950 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
951 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
952 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 3, .mask = BIT(2) },
953 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
954 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
955 	{ .csi = RVIN_CSI21, .channel = 3, .vin = 3, .mask = BIT(5) },
956 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
957 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
958 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 4, .mask = BIT(2) | BIT(5) },
959 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
960 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 5, .mask = BIT(1) },
961 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
962 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(3) },
963 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
964 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 5, .mask = BIT(5) },
965 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 6, .mask = BIT(0) },
966 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
967 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
968 	{ .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
969 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
970 	{ .csi = RVIN_CSI21, .channel = 2, .vin = 6, .mask = BIT(5) },
971 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
972 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
973 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 7, .mask = BIT(2) },
974 	{ .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
975 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
976 	{ .csi = RVIN_CSI21, .channel = 3, .vin = 7, .mask = BIT(5) },
977 	{ /* Sentinel */ }
978 };
979 
980 static const struct rvin_info rcar_info_r8a7795es1 = {
981 	.model = RCAR_GEN3,
982 	.use_mc = true,
983 	.max_width = 4096,
984 	.max_height = 4096,
985 	.routes = rcar_info_r8a7795es1_routes,
986 };
987 
988 static const struct rvin_group_route rcar_info_r8a7796_routes[] = {
989 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
990 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
991 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
992 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
993 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
994 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
995 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
996 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
997 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
998 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
999 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1000 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
1001 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1002 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1003 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1004 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1005 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1006 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1007 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(3) },
1008 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1009 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
1010 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1011 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
1012 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1013 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
1014 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
1015 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
1016 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1017 	{ /* Sentinel */ }
1018 };
1019 
1020 static const struct rvin_info rcar_info_r8a7796 = {
1021 	.model = RCAR_GEN3,
1022 	.use_mc = true,
1023 	.max_width = 4096,
1024 	.max_height = 4096,
1025 	.routes = rcar_info_r8a7796_routes,
1026 };
1027 
1028 static const struct rvin_group_route rcar_info_r8a77965_routes[] = {
1029 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1030 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1031 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1032 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1033 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1034 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1035 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1036 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
1037 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1038 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1039 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1040 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1041 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1042 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
1043 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1044 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1045 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1046 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1047 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) },
1048 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1049 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1050 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1051 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1052 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
1053 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
1054 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1055 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
1056 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1057 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
1058 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
1059 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
1060 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1061 	{ /* Sentinel */ }
1062 };
1063 
1064 static const struct rvin_info rcar_info_r8a77965 = {
1065 	.model = RCAR_GEN3,
1066 	.use_mc = true,
1067 	.max_width = 4096,
1068 	.max_height = 4096,
1069 	.routes = rcar_info_r8a77965_routes,
1070 };
1071 
1072 static const struct rvin_group_route rcar_info_r8a77970_routes[] = {
1073 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1074 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1075 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
1076 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1077 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1078 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1079 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1080 	{ /* Sentinel */ }
1081 };
1082 
1083 static const struct rvin_info rcar_info_r8a77970 = {
1084 	.model = RCAR_GEN3,
1085 	.use_mc = true,
1086 	.max_width = 4096,
1087 	.max_height = 4096,
1088 	.routes = rcar_info_r8a77970_routes,
1089 };
1090 
1091 static const struct rvin_group_route rcar_info_r8a77995_routes[] = {
1092 	{ /* Sentinel */ }
1093 };
1094 
1095 static const struct rvin_info rcar_info_r8a77995 = {
1096 	.model = RCAR_GEN3,
1097 	.use_mc = true,
1098 	.max_width = 4096,
1099 	.max_height = 4096,
1100 	.routes = rcar_info_r8a77995_routes,
1101 };
1102 
1103 static const struct of_device_id rvin_of_id_table[] = {
1104 	{
1105 		.compatible = "renesas,vin-r8a7778",
1106 		.data = &rcar_info_m1,
1107 	},
1108 	{
1109 		.compatible = "renesas,vin-r8a7779",
1110 		.data = &rcar_info_h1,
1111 	},
1112 	{
1113 		.compatible = "renesas,vin-r8a7790",
1114 		.data = &rcar_info_gen2,
1115 	},
1116 	{
1117 		.compatible = "renesas,vin-r8a7791",
1118 		.data = &rcar_info_gen2,
1119 	},
1120 	{
1121 		.compatible = "renesas,vin-r8a7793",
1122 		.data = &rcar_info_gen2,
1123 	},
1124 	{
1125 		.compatible = "renesas,vin-r8a7794",
1126 		.data = &rcar_info_gen2,
1127 	},
1128 	{
1129 		.compatible = "renesas,rcar-gen2-vin",
1130 		.data = &rcar_info_gen2,
1131 	},
1132 	{
1133 		.compatible = "renesas,vin-r8a7795",
1134 		.data = &rcar_info_r8a7795,
1135 	},
1136 	{
1137 		.compatible = "renesas,vin-r8a7796",
1138 		.data = &rcar_info_r8a7796,
1139 	},
1140 	{
1141 		.compatible = "renesas,vin-r8a77965",
1142 		.data = &rcar_info_r8a77965,
1143 	},
1144 	{
1145 		.compatible = "renesas,vin-r8a77970",
1146 		.data = &rcar_info_r8a77970,
1147 	},
1148 	{
1149 		.compatible = "renesas,vin-r8a77995",
1150 		.data = &rcar_info_r8a77995,
1151 	},
1152 	{ /* Sentinel */ },
1153 };
1154 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
1155 
1156 static const struct soc_device_attribute r8a7795es1[] = {
1157 	{
1158 		.soc_id = "r8a7795", .revision = "ES1.*",
1159 		.data = &rcar_info_r8a7795es1,
1160 	},
1161 	{ /* Sentinel */ }
1162 };
1163 
rcar_vin_probe(struct platform_device * pdev)1164 static int rcar_vin_probe(struct platform_device *pdev)
1165 {
1166 	const struct soc_device_attribute *attr;
1167 	struct rvin_dev *vin;
1168 	struct resource *mem;
1169 	int irq, ret;
1170 
1171 	vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
1172 	if (!vin)
1173 		return -ENOMEM;
1174 
1175 	vin->dev = &pdev->dev;
1176 	vin->info = of_device_get_match_data(&pdev->dev);
1177 
1178 	/*
1179 	 * Special care is needed on r8a7795 ES1.x since it
1180 	 * uses different routing than r8a7795 ES2.0.
1181 	 */
1182 	attr = soc_device_match(r8a7795es1);
1183 	if (attr)
1184 		vin->info = attr->data;
1185 
1186 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1187 	if (mem == NULL)
1188 		return -EINVAL;
1189 
1190 	vin->base = devm_ioremap_resource(vin->dev, mem);
1191 	if (IS_ERR(vin->base))
1192 		return PTR_ERR(vin->base);
1193 
1194 	irq = platform_get_irq(pdev, 0);
1195 	if (irq < 0)
1196 		return irq;
1197 
1198 	ret = rvin_dma_register(vin, irq);
1199 	if (ret)
1200 		return ret;
1201 
1202 	platform_set_drvdata(pdev, vin);
1203 
1204 	if (vin->info->use_mc) {
1205 		ret = rvin_mc_init(vin);
1206 		if (ret)
1207 			goto error_dma_unregister;
1208 	}
1209 
1210 	ret = rvin_parallel_init(vin);
1211 	if (ret)
1212 		goto error_group_unregister;
1213 
1214 	pm_suspend_ignore_children(&pdev->dev, true);
1215 	pm_runtime_enable(&pdev->dev);
1216 
1217 	return 0;
1218 
1219 error_group_unregister:
1220 	if (vin->info->use_mc) {
1221 		mutex_lock(&vin->group->lock);
1222 		if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
1223 			v4l2_async_notifier_unregister(&vin->group->notifier);
1224 			v4l2_async_notifier_cleanup(&vin->group->notifier);
1225 		}
1226 		mutex_unlock(&vin->group->lock);
1227 		rvin_group_put(vin);
1228 	}
1229 
1230 error_dma_unregister:
1231 	rvin_dma_unregister(vin);
1232 
1233 	return ret;
1234 }
1235 
rcar_vin_remove(struct platform_device * pdev)1236 static int rcar_vin_remove(struct platform_device *pdev)
1237 {
1238 	struct rvin_dev *vin = platform_get_drvdata(pdev);
1239 
1240 	pm_runtime_disable(&pdev->dev);
1241 
1242 	rvin_v4l2_unregister(vin);
1243 
1244 	v4l2_async_notifier_unregister(&vin->notifier);
1245 	v4l2_async_notifier_cleanup(&vin->notifier);
1246 
1247 	if (vin->info->use_mc) {
1248 		mutex_lock(&vin->group->lock);
1249 		if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
1250 			v4l2_async_notifier_unregister(&vin->group->notifier);
1251 			v4l2_async_notifier_cleanup(&vin->group->notifier);
1252 		}
1253 		mutex_unlock(&vin->group->lock);
1254 		rvin_group_put(vin);
1255 	} else {
1256 		v4l2_ctrl_handler_free(&vin->ctrl_handler);
1257 	}
1258 
1259 	rvin_dma_unregister(vin);
1260 
1261 	return 0;
1262 }
1263 
1264 static struct platform_driver rcar_vin_driver = {
1265 	.driver = {
1266 		.name = "rcar-vin",
1267 		.of_match_table = rvin_of_id_table,
1268 	},
1269 	.probe = rcar_vin_probe,
1270 	.remove = rcar_vin_remove,
1271 };
1272 
1273 module_platform_driver(rcar_vin_driver);
1274 
1275 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
1276 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1277 MODULE_LICENSE("GPL");
1278