2 * NVIDIA Media controller graph management
4 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
6 * Author: Bryan Wu <pengw@nvidia.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/clk.h>
14 #include <linux/list.h>
15 #include <linux/module.h>
17 #include <linux/of_graph.h>
18 #include <linux/of_device.h>
19 #include <linux/platform_device.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/reset.h>
22 #include <linux/slab.h>
23 #include <linux/tegra-soc.h>
24 #include <linux/tegra_pm_domains.h>
26 #include <media/media-device.h>
27 #include <media/v4l2-async.h>
28 #include <media/v4l2-common.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-of.h>
31 #include <media/tegra_v4l2_camera.h>
33 #include "mc_common.h"
36 /* -----------------------------------------------------------------------------
40 static struct tegra_vi_graph_entity *
41 tegra_vi_graph_find_entity(struct tegra_mc_vi *vi,
42 const struct device_node *node)
44 struct tegra_vi_graph_entity *entity;
46 list_for_each_entry(entity, &vi->entities, list) {
47 if (entity->node == node)
54 static int tegra_vi_graph_build_one(struct tegra_mc_vi *vi,
55 struct tegra_vi_graph_entity *entity)
57 u32 link_flags = MEDIA_LNK_FL_ENABLED;
58 struct media_entity *local = entity->entity;
59 struct media_entity *remote;
60 struct media_pad *local_pad;
61 struct media_pad *remote_pad;
62 struct tegra_vi_graph_entity *ent;
63 struct v4l2_of_link link;
64 struct device_node *ep = NULL;
65 struct device_node *next;
68 dev_dbg(vi->dev, "creating links for entity %s\n", local->name);
71 /* Get the next endpoint and parse its link. */
72 next = of_graph_get_next_endpoint(entity->node, ep);
79 dev_dbg(vi->dev, "processing endpoint %s\n", ep->full_name);
81 ret = v4l2_of_parse_link(ep, &link);
83 dev_err(vi->dev, "failed to parse link for %s\n",
88 /* Skip sink ports, they will be processed from the other end of
91 if (link.local_port >= local->num_pads) {
92 dev_err(vi->dev, "invalid port number %u on %s\n",
93 link.local_port, link.local_node->full_name);
94 v4l2_of_put_link(&link);
99 local_pad = &local->pads[link.local_port];
101 if (local_pad->flags & MEDIA_PAD_FL_SINK) {
102 dev_dbg(vi->dev, "skipping sink port %s:%u\n",
103 link.local_node->full_name, link.local_port);
104 v4l2_of_put_link(&link);
108 /* Skip channel entity , they will be processed separately. */
109 if (link.remote_node == vi->dev->of_node) {
110 dev_dbg(vi->dev, "skipping channel port %s:%u\n",
111 link.local_node->full_name, link.local_port);
112 v4l2_of_put_link(&link);
116 /* Find the remote entity. */
117 ent = tegra_vi_graph_find_entity(vi, link.remote_node);
119 dev_err(vi->dev, "no entity found for %s\n",
120 link.remote_node->full_name);
121 v4l2_of_put_link(&link);
126 remote = ent->entity;
128 if (link.remote_port >= remote->num_pads) {
129 dev_err(vi->dev, "invalid port number %u on %s\n",
130 link.remote_port, link.remote_node->full_name);
131 v4l2_of_put_link(&link);
136 remote_pad = &remote->pads[link.remote_port];
138 v4l2_of_put_link(&link);
140 /* Create the media link. */
141 dev_dbg(vi->dev, "creating %s:%u -> %s:%u link\n",
142 local->name, local_pad->index,
143 remote->name, remote_pad->index);
145 ret = media_entity_create_link(local, local_pad->index,
146 remote, remote_pad->index,
150 "failed to create %s:%u -> %s:%u link\n",
151 local->name, local_pad->index,
152 remote->name, remote_pad->index);
161 static int tegra_vi_graph_build_links(struct tegra_mc_vi *vi)
163 u32 link_flags = MEDIA_LNK_FL_ENABLED;
164 struct device_node *node = vi->dev->of_node;
165 struct media_entity *source;
166 struct media_entity *sink;
167 struct media_pad *source_pad;
168 struct media_pad *sink_pad;
169 struct tegra_vi_graph_entity *ent;
170 struct v4l2_of_link link;
171 struct device_node *ep = NULL;
172 struct device_node *next;
173 struct tegra_channel *chan;
176 dev_dbg(vi->dev, "creating links for channels\n");
179 /* Get the next endpoint and parse its link. */
180 next = of_graph_get_next_endpoint(node, ep);
181 if (next == NULL || !of_device_is_available(next))
187 dev_dbg(vi->dev, "processing endpoint %s\n", ep->full_name);
189 ret = v4l2_of_parse_link(ep, &link);
191 dev_err(vi->dev, "failed to parse link for %s\n",
196 if (link.local_port >= vi->num_channels) {
197 dev_err(vi->dev, "wrong channel number for port %u\n",
199 v4l2_of_put_link(&link);
204 chan = &vi->chans[link.local_port];
206 dev_dbg(vi->dev, "creating link for channel %s\n",
209 /* Find the remote entity. */
210 ent = tegra_vi_graph_find_entity(vi, link.remote_node);
212 dev_err(vi->dev, "no entity found for %s\n",
213 link.remote_node->full_name);
214 v4l2_of_put_link(&link);
219 source = ent->entity;
220 source_pad = &source->pads[link.remote_port];
221 sink = &chan->video.entity;
222 sink_pad = &chan->pad;
224 v4l2_of_put_link(&link);
226 /* Create the media link. */
227 dev_dbg(vi->dev, "creating %s:%u -> %s:%u link\n",
228 source->name, source_pad->index,
229 sink->name, sink_pad->index);
231 ret = media_entity_create_link(source, source_pad->index,
232 sink, sink_pad->index,
236 "failed to create %s:%u -> %s:%u link\n",
237 source->name, source_pad->index,
238 sink->name, sink_pad->index);
241 } while (next != NULL);
247 static int tegra_vi_graph_notify_complete(struct v4l2_async_notifier *notifier)
249 struct tegra_mc_vi *vi =
250 container_of(notifier, struct tegra_mc_vi, notifier);
251 struct tegra_vi_graph_entity *entity;
254 dev_dbg(vi->dev, "notify complete, all subdevs registered\n");
256 /* Create links for every entity. */
257 list_for_each_entry(entity, &vi->entities, list) {
258 ret = tegra_vi_graph_build_one(vi, entity);
263 /* Create links for channels */
264 ret = tegra_vi_graph_build_links(vi);
268 ret = v4l2_device_register_subdev_nodes(&vi->v4l2_dev);
270 dev_err(vi->dev, "failed to register subdev nodes\n");
275 static int tegra_vi_graph_notify_bound(struct v4l2_async_notifier *notifier,
276 struct v4l2_subdev *subdev,
277 struct v4l2_async_subdev *asd)
279 struct tegra_mc_vi *vi =
280 container_of(notifier, struct tegra_mc_vi, notifier);
281 struct tegra_vi_graph_entity *entity;
283 /* Locate the entity corresponding to the bound subdev and store the
286 list_for_each_entry(entity, &vi->entities, list) {
287 if (entity->node != subdev->dev->of_node)
290 if (entity->subdev) {
291 dev_err(vi->dev, "duplicate subdev for node %s\n",
292 entity->node->full_name);
296 dev_dbg(vi->dev, "subdev %s bound\n", subdev->name);
297 entity->entity = &subdev->entity;
298 entity->subdev = subdev;
302 dev_err(vi->dev, "no entity for subdev %s\n", subdev->name);
306 void tegra_vi_graph_cleanup(struct tegra_mc_vi *vi)
308 struct tegra_vi_graph_entity *entityp;
309 struct tegra_vi_graph_entity *entity;
311 v4l2_async_notifier_unregister(&vi->notifier);
313 list_for_each_entry_safe(entity, entityp, &vi->entities, list) {
314 of_node_put(entity->node);
315 list_del(&entity->list);
319 int tegra_vi_get_port_info(struct tegra_channel *chan,
320 struct device_node *node, unsigned int index)
322 struct device_node *ep = NULL;
323 struct device_node *ports;
324 struct device_node *port;
328 ports = of_get_child_by_name(node, "ports");
332 for_each_child_of_node(ports, port) {
333 if (!port->name || of_node_cmp(port->name, "port"))
336 ret = of_property_read_u32(port, "reg", &value);
343 for_each_child_of_node(port, ep) {
344 if (!ep->name || of_node_cmp(ep->name, "endpoint"))
348 ret = of_property_read_u32(ep, "csi-port", &value);
350 pr_info("csi port error\n");
353 /* Get number of data lanes for the endpoint */
354 ret = of_property_read_u32(ep, "bus-width", &value);
356 pr_info("num of lanes error\n");
357 chan->numlanes = value;
365 static int tegra_vi_graph_parse_one(struct tegra_mc_vi *vi,
366 struct device_node *node)
368 struct device_node *ep = NULL;
369 struct device_node *next;
370 struct device_node *remote = NULL;
371 struct tegra_vi_graph_entity *entity;
374 dev_dbg(vi->dev, "parsing node %s\n", node->full_name);
377 /* Parse all the remote entities and put them into the list */
378 next = of_graph_get_next_endpoint(node, ep);
385 dev_dbg(vi->dev, "handling endpoint %s\n", ep->full_name);
387 remote = of_graph_get_remote_port_parent(ep);
393 /* Skip entities that we have already processed. */
394 if (remote == vi->dev->of_node ||
395 tegra_vi_graph_find_entity(vi, remote) ||
396 !of_device_is_available(remote)) {
401 entity = devm_kzalloc(vi->dev, sizeof(*entity),
403 if (entity == NULL) {
409 entity->node = remote;
410 entity->asd.match_type = V4L2_ASYNC_MATCH_OF;
411 entity->asd.match.of.node = remote;
412 list_add_tail(&entity->list, &vi->entities);
420 int tegra_vi_graph_init(struct tegra_mc_vi *vi)
422 struct tegra_vi_graph_entity *entity;
423 struct v4l2_async_subdev **subdevs = NULL;
424 unsigned int num_subdevs = 0;
428 * Walk the links to parse the full graph. Start by parsing the
429 * composite node and then parse entities in turn. The list_for_each
430 * loop will handle entities added at the end of the list while walking
433 ret = tegra_vi_graph_parse_one(vi, vi->dev->of_node);
437 list_for_each_entry(entity, &vi->entities, list) {
438 ret = tegra_vi_graph_parse_one(vi, entity->node);
443 if (!vi->num_subdevs) {
444 dev_dbg(vi->dev, "warning: no subdev found in graph\n");
448 /* Register the subdevices notifier. */
449 num_subdevs = vi->num_subdevs;
450 subdevs = devm_kzalloc(vi->dev, sizeof(*subdevs) * num_subdevs,
452 if (subdevs == NULL) {
458 * Add code to check for sensors and
459 * set TPG mode for VI if no sensors found
460 * logic varies for different platforms
463 list_for_each_entry(entity, &vi->entities, list)
464 subdevs[i++] = &entity->asd;
466 vi->notifier.subdevs = subdevs;
467 vi->notifier.num_subdevs = num_subdevs;
468 vi->notifier.bound = tegra_vi_graph_notify_bound;
469 vi->notifier.complete = tegra_vi_graph_notify_complete;
471 ret = v4l2_async_notifier_register(&vi->v4l2_dev, &vi->notifier);
473 dev_err(vi->dev, "notifier registration failed\n");
481 tegra_vi_graph_cleanup(vi);