• 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_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