]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/media/platform/tegra/camera/graph.c
drivers: media: platform: tegra: VI mode
[sojka/nv-tegra/linux-3.10.git] / drivers / media / platform / tegra / camera / graph.c
1 /*
2  * NVIDIA Media controller graph management
3  *
4  * Copyright (c) 2015-2016, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * Author: Bryan Wu <pengw@nvidia.com>
7  *
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.
11  */
12
13 #include <linux/clk.h>
14 #include <linux/list.h>
15 #include <linux/module.h>
16 #include <linux/of.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>
25
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>
32
33 #include "mc_common.h"
34
35
36 /* -----------------------------------------------------------------------------
37  * Graph Management
38  */
39
40 static struct tegra_vi_graph_entity *
41 tegra_vi_graph_find_entity(struct tegra_mc_vi *vi,
42                        const struct device_node *node)
43 {
44         struct tegra_vi_graph_entity *entity;
45
46         list_for_each_entry(entity, &vi->entities, list) {
47                 if (entity->node == node)
48                         return entity;
49         }
50
51         return NULL;
52 }
53
54 static int tegra_vi_graph_build_one(struct tegra_mc_vi *vi,
55                                     struct tegra_vi_graph_entity *entity)
56 {
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;
66         int ret = 0;
67
68         dev_dbg(vi->dev, "creating links for entity %s\n", local->name);
69
70         do {
71                 /* Get the next endpoint and parse its link. */
72                 next = of_graph_get_next_endpoint(entity->node, ep);
73                 if (next == NULL)
74                         break;
75
76                 of_node_put(ep);
77                 ep = next;
78
79                 dev_dbg(vi->dev, "processing endpoint %s\n", ep->full_name);
80
81                 ret = v4l2_of_parse_link(ep, &link);
82                 if (ret < 0) {
83                         dev_err(vi->dev, "failed to parse link for %s\n",
84                                 ep->full_name);
85                         continue;
86                 }
87
88                 /* Skip sink ports, they will be processed from the other end of
89                  * the link.
90                  */
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);
95                         ret = -EINVAL;
96                         break;
97                 }
98
99                 local_pad = &local->pads[link.local_port];
100
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);
105                         continue;
106                 }
107
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);
113                         continue;
114                 }
115
116                 /* Find the remote entity. */
117                 ent = tegra_vi_graph_find_entity(vi, link.remote_node);
118                 if (ent == NULL) {
119                         dev_err(vi->dev, "no entity found for %s\n",
120                                 link.remote_node->full_name);
121                         v4l2_of_put_link(&link);
122                         ret = -ENODEV;
123                         break;
124                 }
125
126                 remote = ent->entity;
127
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);
132                         ret = -EINVAL;
133                         break;
134                 }
135
136                 remote_pad = &remote->pads[link.remote_port];
137
138                 v4l2_of_put_link(&link);
139
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);
144
145                 ret = media_entity_create_link(local, local_pad->index,
146                                                remote, remote_pad->index,
147                                                link_flags);
148                 if (ret < 0) {
149                         dev_err(vi->dev,
150                                 "failed to create %s:%u -> %s:%u link\n",
151                                 local->name, local_pad->index,
152                                 remote->name, remote_pad->index);
153                         break;
154                 }
155         } while (next);
156
157         of_node_put(ep);
158         return ret;
159 }
160
161 static int tegra_vi_graph_build_links(struct tegra_mc_vi *vi)
162 {
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;
174         int ret = 0;
175
176         dev_dbg(vi->dev, "creating links for channels\n");
177
178         do {
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))
182                         break;
183
184                 of_node_put(ep);
185                 ep = next;
186
187                 dev_dbg(vi->dev, "processing endpoint %s\n", ep->full_name);
188
189                 ret = v4l2_of_parse_link(ep, &link);
190                 if (ret < 0) {
191                         dev_err(vi->dev, "failed to parse link for %s\n",
192                                 ep->full_name);
193                         continue;
194                 }
195
196                 if (link.local_port >= vi->num_channels) {
197                         dev_err(vi->dev, "wrong channel number for port %u\n",
198                                 link.local_port);
199                         v4l2_of_put_link(&link);
200                         ret = -EINVAL;
201                         break;
202                 }
203
204                 chan = &vi->chans[link.local_port];
205
206                 dev_dbg(vi->dev, "creating link for channel %s\n",
207                         chan->video.name);
208
209                 /* Find the remote entity. */
210                 ent = tegra_vi_graph_find_entity(vi, link.remote_node);
211                 if (ent == NULL) {
212                         dev_err(vi->dev, "no entity found for %s\n",
213                                 link.remote_node->full_name);
214                         v4l2_of_put_link(&link);
215                         ret = -ENODEV;
216                         break;
217                 }
218
219                 source = ent->entity;
220                 source_pad = &source->pads[link.remote_port];
221                 sink = &chan->video.entity;
222                 sink_pad = &chan->pad;
223
224                 v4l2_of_put_link(&link);
225
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);
230
231                 ret = media_entity_create_link(source, source_pad->index,
232                                                sink, sink_pad->index,
233                                                link_flags);
234                 if (ret < 0) {
235                         dev_err(vi->dev,
236                                 "failed to create %s:%u -> %s:%u link\n",
237                                 source->name, source_pad->index,
238                                 sink->name, sink_pad->index);
239                         break;
240                 }
241         } while (next != NULL);
242
243         of_node_put(ep);
244         return ret;
245 }
246
247 static int tegra_vi_graph_notify_complete(struct v4l2_async_notifier *notifier)
248 {
249         struct tegra_mc_vi *vi =
250                 container_of(notifier, struct tegra_mc_vi, notifier);
251         struct tegra_vi_graph_entity *entity;
252         int ret;
253
254         dev_dbg(vi->dev, "notify complete, all subdevs registered\n");
255
256         /* Create links for every entity. */
257         list_for_each_entry(entity, &vi->entities, list) {
258                 ret = tegra_vi_graph_build_one(vi, entity);
259                 if (ret < 0)
260                         return ret;
261         }
262
263         /* Create links for channels */
264         ret = tegra_vi_graph_build_links(vi);
265         if (ret < 0)
266                 return ret;
267
268         ret = v4l2_device_register_subdev_nodes(&vi->v4l2_dev);
269         if (ret < 0)
270                 dev_err(vi->dev, "failed to register subdev nodes\n");
271
272         return ret;
273 }
274
275 static int tegra_vi_graph_notify_bound(struct v4l2_async_notifier *notifier,
276                                    struct v4l2_subdev *subdev,
277                                    struct v4l2_async_subdev *asd)
278 {
279         struct tegra_mc_vi *vi =
280                 container_of(notifier, struct tegra_mc_vi, notifier);
281         struct tegra_vi_graph_entity *entity;
282
283         /* Locate the entity corresponding to the bound subdev and store the
284          * subdev pointer.
285          */
286         list_for_each_entry(entity, &vi->entities, list) {
287                 if (entity->node != subdev->dev->of_node)
288                         continue;
289
290                 if (entity->subdev) {
291                         dev_err(vi->dev, "duplicate subdev for node %s\n",
292                                 entity->node->full_name);
293                         return -EINVAL;
294                 }
295
296                 dev_dbg(vi->dev, "subdev %s bound\n", subdev->name);
297                 entity->entity = &subdev->entity;
298                 entity->subdev = subdev;
299                 return 0;
300         }
301
302         dev_err(vi->dev, "no entity for subdev %s\n", subdev->name);
303         return -EINVAL;
304 }
305
306 void tegra_vi_graph_cleanup(struct tegra_mc_vi *vi)
307 {
308         struct tegra_vi_graph_entity *entityp;
309         struct tegra_vi_graph_entity *entity;
310
311         v4l2_async_notifier_unregister(&vi->notifier);
312
313         list_for_each_entry_safe(entity, entityp, &vi->entities, list) {
314                 of_node_put(entity->node);
315                 list_del(&entity->list);
316         }
317 }
318
319 int tegra_vi_get_port_info(struct tegra_channel *chan,
320                         struct device_node *node, unsigned int index)
321 {
322         struct device_node *ep = NULL;
323         struct device_node *ports;
324         struct device_node *port;
325         int value = 0xFFFF;
326         int ret = 0;
327
328         ports = of_get_child_by_name(node, "ports");
329         if (ports == NULL)
330                 ports = node;
331
332         for_each_child_of_node(ports, port) {
333                 if (!port->name || of_node_cmp(port->name, "port"))
334                         continue;
335
336                 ret = of_property_read_u32(port, "reg", &value);
337                 if (ret < 0)
338                         continue;
339
340                 if (value != index)
341                         continue;
342
343                 for_each_child_of_node(port, ep) {
344                         if (!ep->name || of_node_cmp(ep->name, "endpoint"))
345                                 continue;
346
347                         /* Get CSI port */
348                         ret = of_property_read_u32(ep, "csi-port", &value);
349                         if (ret < 0)
350                                 pr_info("csi port error\n");
351                         chan->port = value;
352
353                         /* Get number of data lanes for the endpoint */
354                         ret = of_property_read_u32(ep, "bus-width", &value);
355                         if (ret < 0)
356                                 pr_info("num of lanes error\n");
357                         chan->numlanes = value;
358
359                 }
360         }
361
362         return ret;
363 }
364
365 static int tegra_vi_graph_parse_one(struct tegra_mc_vi *vi,
366                                 struct device_node *node)
367 {
368         struct device_node *ep = NULL;
369         struct device_node *next;
370         struct device_node *remote = NULL;
371         struct tegra_vi_graph_entity *entity;
372         int ret = 0;
373
374         dev_dbg(vi->dev, "parsing node %s\n", node->full_name);
375
376         do {
377                 /* Parse all the remote entities and put them into the list */
378                 next = of_graph_get_next_endpoint(node, ep);
379                 if (next == NULL)
380                         break;
381
382                 of_node_put(ep);
383                 ep = next;
384
385                 dev_dbg(vi->dev, "handling endpoint %s\n", ep->full_name);
386
387                 remote = of_graph_get_remote_port_parent(ep);
388                 if (!remote) {
389                         ret = -EINVAL;
390                         break;
391                 }
392
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)) {
397                         of_node_put(remote);
398                         continue;
399                 }
400
401                 entity = devm_kzalloc(vi->dev, sizeof(*entity),
402                                 GFP_KERNEL);
403                 if (entity == NULL) {
404                         of_node_put(remote);
405                         ret = -ENOMEM;
406                         break;
407                 }
408
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);
413                 vi->num_subdevs++;
414         } while (next);
415
416         of_node_put(ep);
417         return ret;
418 }
419
420 int tegra_vi_graph_init(struct tegra_mc_vi *vi)
421 {
422         struct tegra_vi_graph_entity *entity;
423         struct v4l2_async_subdev **subdevs = NULL;
424         unsigned int num_subdevs = 0;
425         int ret = 0, i;
426
427         /*
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
431          * the links.
432          */
433         ret = tegra_vi_graph_parse_one(vi, vi->dev->of_node);
434         if (ret < 0)
435                 return 0;
436
437         list_for_each_entry(entity, &vi->entities, list) {
438                 ret = tegra_vi_graph_parse_one(vi, entity->node);
439                 if (ret < 0)
440                         break;
441         }
442
443         if (!vi->num_subdevs) {
444                 dev_dbg(vi->dev, "warning: no subdev found in graph\n");
445                 goto done;
446         }
447
448         /* Register the subdevices notifier. */
449         num_subdevs = vi->num_subdevs;
450         subdevs = devm_kzalloc(vi->dev, sizeof(*subdevs) * num_subdevs,
451                                GFP_KERNEL);
452         if (subdevs == NULL) {
453                 ret = -ENOMEM;
454                 goto done;
455         }
456
457         /*
458          * Add code to check for sensors and
459          * set TPG mode for VI if no sensors found
460          * logic varies for different platforms
461          */
462         i = 0;
463         list_for_each_entry(entity, &vi->entities, list)
464                 subdevs[i++] = &entity->asd;
465
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;
470
471         ret = v4l2_async_notifier_register(&vi->v4l2_dev, &vi->notifier);
472         if (ret < 0) {
473                 dev_err(vi->dev, "notifier registration failed\n");
474                 goto done;
475         }
476
477         return 0;
478
479 done:
480         if (ret < 0)
481                 tegra_vi_graph_cleanup(vi);
482
483         return ret;
484 }