]>
Commit | Line | Data |
---|---|---|
4984de2b SG |
1 | /* |
2 | * Copyright (c) 2017 Google, Inc | |
3 | * Written by Simon Glass <sjg@chromium.org> | |
4 | * | |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
8 | #ifndef _DM_OFNODE_H | |
9 | #define _DM_OFNODE_H | |
10 | ||
9e512045 SG |
11 | /* TODO(sjg@chromium.org): Drop fdtdec.h include */ |
12 | #include <fdtdec.h> | |
13 | #include <dm/of.h> | |
14 | ||
15 | /* Enable checks to protect against invalid calls */ | |
16 | #undef OF_CHECKS | |
17 | ||
4984de2b SG |
18 | /** |
19 | * ofnode - reference to a device tree node | |
20 | * | |
21 | * This union can hold either a straightforward pointer to a struct device_node | |
22 | * in the live device tree, or an offset within the flat device tree. In the | |
23 | * latter case, the pointer value is just the integer offset within the flat DT. | |
24 | * | |
25 | * Thus we can reference nodes in both the live tree (once available) and the | |
26 | * flat tree (until then). Functions are available to translate between an | |
27 | * ofnode and either an offset or a struct device_node *. | |
28 | * | |
29 | * The reference can also hold a null offset, in which case the pointer value | |
9e512045 | 30 | * here is NULL. This corresponds to a struct device_node * value of |
4984de2b SG |
31 | * NULL, or an offset of -1. |
32 | * | |
33 | * There is no ambiguity as to whether ofnode holds an offset or a node | |
34 | * pointer: when the live tree is active it holds a node pointer, otherwise it | |
35 | * holds an offset. The value itself does not need to be unique and in theory | |
36 | * the same value could point to a valid device node or a valid offset. We | |
37 | * could arrange for a unique value to be used (e.g. by making the pointer | |
38 | * point to an offset within the flat device tree in the case of an offset) but | |
39 | * this increases code size slightly due to the subtraction. Since it offers no | |
40 | * real benefit, the approach described here seems best. | |
41 | * | |
42 | * For now these points use constant types, since we don't allow writing | |
43 | * the DT. | |
44 | * | |
45 | * @np: Pointer to device node, used for live tree | |
46 | * @flat_ptr: Pointer into flat device tree, used for flat tree. Note that this | |
47 | * is not a really a pointer to a node: it is an offset value. See above. | |
48 | */ | |
49 | typedef union ofnode_union { | |
50 | const struct device_node *np; /* will be used for future live tree */ | |
51 | long of_offset; | |
52 | } ofnode; | |
53 | ||
9e512045 SG |
54 | struct ofnode_phandle_args { |
55 | ofnode node; | |
56 | int args_count; | |
57 | uint32_t args[OF_MAX_PHANDLE_ARGS]; | |
58 | }; | |
59 | ||
60 | /** | |
61 | * _ofnode_to_np() - convert an ofnode to a live DT node pointer | |
62 | * | |
63 | * This cannot be called if the reference contains an offset. | |
64 | * | |
65 | * @node: Reference containing struct device_node * (possibly invalid) | |
66 | * @return pointer to device node (can be NULL) | |
67 | */ | |
68 | static inline const struct device_node *ofnode_to_np(ofnode node) | |
69 | { | |
70 | #ifdef OF_CHECKS | |
71 | if (!of_live_active()) | |
72 | return NULL; | |
73 | #endif | |
74 | return node.np; | |
75 | } | |
76 | ||
4984de2b SG |
77 | /** |
78 | * ofnode_to_offset() - convert an ofnode to a flat DT offset | |
79 | * | |
80 | * This cannot be called if the reference contains a node pointer. | |
81 | * | |
82 | * @node: Reference containing offset (possibly invalid) | |
83 | * @return DT offset (can be -1) | |
84 | */ | |
85 | static inline int ofnode_to_offset(ofnode node) | |
86 | { | |
9e512045 SG |
87 | #ifdef OF_CHECKS |
88 | if (of_live_active()) | |
89 | return -1; | |
90 | #endif | |
4984de2b SG |
91 | return node.of_offset; |
92 | } | |
93 | ||
94 | /** | |
95 | * ofnode_valid() - check if an ofnode is valid | |
96 | * | |
97 | * @return true if the reference contains a valid ofnode, false if it is NULL | |
98 | */ | |
99 | static inline bool ofnode_valid(ofnode node) | |
100 | { | |
9e512045 SG |
101 | if (of_live_active()) |
102 | return node.np != NULL; | |
103 | else | |
104 | return node.of_offset != -1; | |
4984de2b SG |
105 | } |
106 | ||
107 | /** | |
108 | * offset_to_ofnode() - convert a DT offset to an ofnode | |
109 | * | |
110 | * @of_offset: DT offset (either valid, or -1) | |
111 | * @return reference to the associated DT offset | |
112 | */ | |
113 | static inline ofnode offset_to_ofnode(int of_offset) | |
114 | { | |
115 | ofnode node; | |
116 | ||
9e512045 SG |
117 | if (of_live_active()) |
118 | node.np = NULL; | |
119 | else | |
120 | node.of_offset = of_offset; | |
121 | ||
122 | return node; | |
123 | } | |
124 | ||
125 | /** | |
126 | * np_to_ofnode() - convert a node pointer to an ofnode | |
127 | * | |
128 | * @np: Live node pointer (can be NULL) | |
129 | * @return reference to the associated node pointer | |
130 | */ | |
131 | static inline ofnode np_to_ofnode(const struct device_node *np) | |
132 | { | |
133 | ofnode node; | |
134 | ||
135 | node.np = np; | |
4984de2b SG |
136 | |
137 | return node; | |
138 | } | |
139 | ||
9e512045 SG |
140 | /** |
141 | * ofnode_is_np() - check if a reference is a node pointer | |
142 | * | |
143 | * This function associated that if there is a valid live tree then all | |
144 | * references will use it. This is because using the flat DT when the live tree | |
145 | * is valid is not permitted. | |
146 | * | |
147 | * @node: reference to check (possibly invalid) | |
148 | * @return true if the reference is a live node pointer, false if it is a DT | |
149 | * offset | |
150 | */ | |
151 | static inline bool ofnode_is_np(ofnode node) | |
152 | { | |
153 | #ifdef OF_CHECKS | |
154 | /* | |
155 | * Check our assumption that flat tree offsets are not used when a | |
156 | * live tree is in use. | |
157 | */ | |
158 | assert(!ofnode_valid(node) || | |
159 | (of_live_active() ? _ofnode_to_np(node) | |
160 | : _ofnode_to_np(node))); | |
161 | #endif | |
162 | return of_live_active() && ofnode_valid(node); | |
163 | } | |
164 | ||
4984de2b SG |
165 | /** |
166 | * ofnode_equal() - check if two references are equal | |
167 | * | |
168 | * @return true if equal, else false | |
169 | */ | |
170 | static inline bool ofnode_equal(ofnode ref1, ofnode ref2) | |
171 | { | |
172 | /* We only need to compare the contents */ | |
173 | return ref1.of_offset == ref2.of_offset; | |
174 | } | |
175 | ||
9e512045 SG |
176 | /** |
177 | * ofnode_null() - Obtain a null ofnode | |
178 | * | |
179 | * This returns an ofnode which points to no node. It works both with the flat | |
180 | * tree and livetree. | |
181 | */ | |
182 | static inline ofnode ofnode_null(void) | |
183 | { | |
184 | ofnode node; | |
185 | ||
186 | if (of_live_active()) | |
187 | node.np = NULL; | |
188 | else | |
189 | node.of_offset = -1; | |
190 | ||
191 | return node; | |
192 | } | |
193 | ||
194 | /** | |
195 | * ofnode_read_u32() - Read a 32-bit integer from a property | |
196 | * | |
197 | * @ref: valid node reference to read property from | |
198 | * @propname: name of the property to read from | |
199 | * @outp: place to put value (if found) | |
200 | * @return 0 if OK, -ve on error | |
201 | */ | |
202 | int ofnode_read_u32(ofnode node, const char *propname, u32 *outp); | |
203 | ||
204 | /** | |
205 | * ofnode_read_s32() - Read a 32-bit integer from a property | |
206 | * | |
207 | * @ref: valid node reference to read property from | |
208 | * @propname: name of the property to read from | |
209 | * @outp: place to put value (if found) | |
210 | * @return 0 if OK, -ve on error | |
211 | */ | |
212 | static inline int ofnode_read_s32(ofnode node, const char *propname, | |
213 | s32 *out_value) | |
214 | { | |
215 | return ofnode_read_u32(node, propname, (u32 *)out_value); | |
216 | } | |
217 | ||
218 | /** | |
219 | * ofnode_read_u32_default() - Read a 32-bit integer from a property | |
220 | * | |
221 | * @ref: valid node reference to read property from | |
222 | * @propname: name of the property to read from | |
223 | * @def: default value to return if the property has no value | |
224 | * @return property value, or @def if not found | |
225 | */ | |
226 | int ofnode_read_u32_default(ofnode ref, const char *propname, u32 def); | |
227 | ||
228 | /** | |
229 | * ofnode_read_s32_default() - Read a 32-bit integer from a property | |
230 | * | |
231 | * @ref: valid node reference to read property from | |
232 | * @propname: name of the property to read from | |
233 | * @def: default value to return if the property has no value | |
234 | * @return property value, or @def if not found | |
235 | */ | |
236 | int ofnode_read_s32_default(ofnode node, const char *propname, s32 def); | |
237 | ||
238 | /** | |
239 | * ofnode_read_string() - Read a string from a property | |
240 | * | |
241 | * @ref: valid node reference to read property from | |
242 | * @propname: name of the property to read | |
243 | * @return string from property value, or NULL if there is no such property | |
244 | */ | |
245 | const char *ofnode_read_string(ofnode node, const char *propname); | |
246 | ||
247 | /** | |
bed77496 | 248 | * ofnode_read_u32_array() - Find and read an array of 32 bit integers |
9e512045 SG |
249 | * |
250 | * @node: valid node reference to read property from | |
251 | * @propname: name of the property to read | |
252 | * @out_values: pointer to return value, modified only if return value is 0 | |
253 | * @sz: number of array elements to read | |
254 | * | |
255 | * Search for a property in a device node and read 32-bit value(s) from | |
256 | * it. Returns 0 on success, -EINVAL if the property does not exist, | |
257 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | |
258 | * property data isn't large enough. | |
259 | * | |
260 | * The out_values is modified only if a valid u32 value can be decoded. | |
261 | */ | |
262 | int ofnode_read_u32_array(ofnode node, const char *propname, | |
263 | u32 *out_values, size_t sz); | |
264 | ||
265 | /** | |
266 | * ofnode_read_bool() - read a boolean value from a property | |
267 | * | |
268 | * @node: valid node reference to read property from | |
269 | * @propname: name of property to read | |
270 | * @return true if property is present (meaning true), false if not present | |
271 | */ | |
272 | bool ofnode_read_bool(ofnode node, const char *propname); | |
273 | ||
274 | /** | |
275 | * ofnode_find_subnode() - find a named subnode of a parent node | |
276 | * | |
277 | * @node: valid reference to parent node | |
278 | * @subnode_name: name of subnode to find | |
279 | * @return reference to subnode (which can be invalid if there is no such | |
280 | * subnode) | |
281 | */ | |
282 | ofnode ofnode_find_subnode(ofnode node, const char *subnode_name); | |
283 | ||
284 | /** | |
285 | * ofnode_first_subnode() - find the first subnode of a parent node | |
286 | * | |
287 | * @node: valid reference to a valid parent node | |
288 | * @return reference to the first subnode (which can be invalid if the parent | |
289 | * node has no subnodes) | |
290 | */ | |
291 | ofnode ofnode_first_subnode(ofnode node); | |
292 | ||
293 | /** | |
294 | * ofnode_next_subnode() - find the next sibling of a subnode | |
295 | * | |
296 | * @node: valid reference to previous node (sibling) | |
297 | * @return reference to the next subnode (which can be invalid if the node | |
298 | * has no more siblings) | |
299 | */ | |
300 | ofnode ofnode_next_subnode(ofnode node); | |
301 | ||
302 | /** | |
303 | * ofnode_get_name() - get the name of a node | |
304 | * | |
305 | * @node: valid node to look up | |
306 | * @return name or node | |
307 | */ | |
308 | const char *ofnode_get_name(ofnode node); | |
309 | ||
310 | /** | |
311 | * ofnode_read_size() - read the size of a property | |
312 | * | |
313 | * @node: node to check | |
314 | * @propname: property to check | |
315 | * @return size of property if present, or -EINVAL if not | |
316 | */ | |
317 | int ofnode_read_size(ofnode node, const char *propname); | |
318 | ||
bed77496 SG |
319 | /** |
320 | * ofnode_get_addr_index() - get an address from a node | |
321 | * | |
322 | * This reads the register address from a node | |
323 | * | |
324 | * @node: node to read from | |
325 | * @index: Index of address to read (0 for first) | |
326 | * @return address, or FDT_ADDR_T_NONE if not present or invalid | |
327 | */ | |
328 | phys_addr_t ofnode_get_addr_index(ofnode node, int index); | |
329 | ||
330 | /** | |
331 | * ofnode_get_addr() - get an address from a node | |
332 | * | |
333 | * This reads the register address from a node | |
334 | * | |
335 | * @node: node to read from | |
336 | * @return address, or FDT_ADDR_T_NONE if not present or invalid | |
337 | */ | |
338 | phys_addr_t ofnode_get_addr(ofnode node); | |
339 | ||
9e512045 SG |
340 | /** |
341 | * ofnode_stringlist_search() - find a string in a string list and return index | |
342 | * | |
343 | * Note that it is possible for this function to succeed on property values | |
344 | * that are not NUL-terminated. That's because the function will stop after | |
345 | * finding the first occurrence of @string. This can for example happen with | |
346 | * small-valued cell properties, such as #address-cells, when searching for | |
347 | * the empty string. | |
348 | * | |
349 | * @node: node to check | |
350 | * @propname: name of the property containing the string list | |
351 | * @string: string to look up in the string list | |
352 | * | |
353 | * @return: | |
354 | * the index of the string in the list of strings | |
355 | * -ENODATA if the property is not found | |
356 | * -EINVAL on some other error | |
357 | */ | |
358 | int ofnode_stringlist_search(ofnode node, const char *propname, | |
359 | const char *string); | |
360 | ||
361 | /** | |
362 | * fdt_stringlist_get() - obtain the string at a given index in a string list | |
363 | * | |
364 | * Note that this will successfully extract strings from properties with | |
365 | * non-NUL-terminated values. For example on small-valued cell properties | |
366 | * this function will return the empty string. | |
367 | * | |
368 | * If non-NULL, the length of the string (on success) or a negative error-code | |
369 | * (on failure) will be stored in the integer pointer to by lenp. | |
370 | * | |
371 | * @node: node to check | |
372 | * @propname: name of the property containing the string list | |
373 | * @index: index of the string to return | |
374 | * @lenp: return location for the string length or an error code on failure | |
375 | * | |
376 | * @return: | |
377 | * length of string, if found or -ve error value if not found | |
378 | */ | |
379 | int ofnode_read_string_index(ofnode node, const char *propname, int index, | |
380 | const char **outp); | |
381 | ||
382 | /** | |
383 | * ofnode_parse_phandle_with_args() - Find a node pointed by phandle in a list | |
384 | * | |
385 | * This function is useful to parse lists of phandles and their arguments. | |
386 | * Returns 0 on success and fills out_args, on error returns appropriate | |
387 | * errno value. | |
388 | * | |
389 | * Caller is responsible to call of_node_put() on the returned out_args->np | |
390 | * pointer. | |
391 | * | |
392 | * Example: | |
393 | * | |
394 | * phandle1: node1 { | |
395 | * #list-cells = <2>; | |
396 | * } | |
397 | * | |
398 | * phandle2: node2 { | |
399 | * #list-cells = <1>; | |
400 | * } | |
401 | * | |
402 | * node3 { | |
403 | * list = <&phandle1 1 2 &phandle2 3>; | |
404 | * } | |
405 | * | |
406 | * To get a device_node of the `node2' node you may call this: | |
407 | * ofnode_parse_phandle_with_args(node3, "list", "#list-cells", 0, 1, &args); | |
408 | * | |
409 | * @node: device tree node containing a list | |
410 | * @list_name: property name that contains a list | |
411 | * @cells_name: property name that specifies phandles' arguments count | |
412 | * @cells_count: Cell count to use if @cells_name is NULL | |
413 | * @index: index of a phandle to parse out | |
414 | * @out_args: optional pointer to output arguments structure (will be filled) | |
415 | * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if | |
416 | * @list_name does not exist, -EINVAL if a phandle was not found, | |
417 | * @cells_name could not be found, the arguments were truncated or there | |
418 | * were too many arguments. | |
419 | */ | |
420 | int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, | |
421 | const char *cells_name, int cell_count, | |
422 | int index, | |
423 | struct ofnode_phandle_args *out_args); | |
424 | ||
425 | /** | |
426 | * ofnode_path() - find a node by full path | |
427 | * | |
428 | * @path: Full path to node, e.g. "/bus/spi@1" | |
429 | * @return reference to the node found. Use ofnode_valid() to check if it exists | |
430 | */ | |
431 | ofnode ofnode_path(const char *path); | |
432 | ||
433 | /** | |
434 | * ofnode_get_chosen_prop() - get the value of a chosen property | |
435 | * | |
436 | * This looks for a property within the /chosen node and returns its value | |
437 | * | |
438 | * @propname: Property name to look for | |
439 | */ | |
440 | const char *ofnode_get_chosen_prop(const char *propname); | |
441 | ||
442 | /** | |
443 | * ofnode_get_chosen_node() - get the chosen node | |
444 | * | |
445 | * @return the chosen node if present, else ofnode_null() | |
446 | */ | |
447 | ofnode ofnode_get_chosen_node(const char *name); | |
448 | ||
449 | struct display_timing; | |
450 | /** | |
451 | * ofnode_decode_display_timing() - decode display timings | |
452 | * | |
453 | * Decode display timings from the supplied 'display-timings' node. | |
454 | * See doc/device-tree-bindings/video/display-timing.txt for binding | |
455 | * information. | |
456 | * | |
457 | * @node 'display-timing' node containing the timing subnodes | |
458 | * @index Index number to read (0=first timing subnode) | |
459 | * @config Place to put timings | |
460 | * @return 0 if OK, -FDT_ERR_NOTFOUND if not found | |
461 | */ | |
462 | int ofnode_decode_display_timing(ofnode node, int index, | |
463 | struct display_timing *config); | |
464 | ||
465 | /** | |
466 | * ofnode_read_prop()- - read a node property | |
467 | * | |
468 | * @node: node to read | |
469 | * @propname: property to read | |
470 | * @lenp: place to put length on success | |
471 | * @return pointer to property, or NULL if not found | |
472 | */ | |
473 | const u32 *ofnode_read_prop(ofnode node, const char *propname, int *lenp); | |
474 | ||
475 | /** | |
476 | * ofnode_is_available() - check if a node is marked available | |
477 | * | |
478 | * @node: node to check | |
479 | * @return true if node's 'status' property is "okay" (or is missing) | |
480 | */ | |
481 | bool ofnode_is_available(ofnode node); | |
482 | ||
483 | /** | |
484 | * ofnode_get_addr_size() - get address and size from a property | |
485 | * | |
486 | * This does no address translation. It simply reads an property that contains | |
487 | * an address and a size value, one after the other. | |
488 | * | |
489 | * @node: node to read from | |
490 | * @propname: property to read | |
491 | * @sizep: place to put size value (on success) | |
492 | * @return address value, or FDT_ADDR_T_NONE on error | |
493 | */ | |
494 | phys_addr_t ofnode_get_addr_size(ofnode node, const char *propname, | |
495 | phys_size_t *sizep); | |
496 | ||
497 | /** | |
498 | * ofnode_read_u8_array_ptr() - find an 8-bit array | |
499 | * | |
500 | * Look up a property in a node and return a pointer to its contents as a | |
501 | * byte array of given length. The property must have at least enough data | |
502 | * for the array (count bytes). It may have more, but this will be ignored. | |
503 | * The data is not copied. | |
504 | * | |
505 | * @node node to examine | |
506 | * @propname name of property to find | |
507 | * @sz number of array elements | |
508 | * @return pointer to byte array if found, or NULL if the property is not | |
509 | * found or there is not enough data | |
510 | */ | |
511 | const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname, | |
512 | size_t sz); | |
513 | ||
514 | /** | |
515 | * ofnode_read_pci_addr() - look up a PCI address | |
516 | * | |
517 | * Look at an address property in a node and return the PCI address which | |
518 | * corresponds to the given type in the form of fdt_pci_addr. | |
519 | * The property must hold one fdt_pci_addr with a lengh. | |
520 | * | |
521 | * @node node to examine | |
522 | * @type pci address type (FDT_PCI_SPACE_xxx) | |
523 | * @propname name of property to find | |
524 | * @addr returns pci address in the form of fdt_pci_addr | |
525 | * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the | |
526 | * format of the property was invalid, -ENXIO if the requested | |
527 | * address type was not found | |
528 | */ | |
529 | int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type, | |
530 | const char *propname, struct fdt_pci_addr *addr); | |
531 | ||
532 | /** | |
533 | * ofnode_read_addr_cells() - Get the number of address cells for a node | |
534 | * | |
535 | * This walks back up the tree to find the closest #address-cells property | |
536 | * which controls the given node. | |
537 | * | |
538 | * @node: Node to check | |
539 | * @return number of address cells this node uses | |
540 | */ | |
541 | int ofnode_read_addr_cells(ofnode node); | |
542 | ||
543 | /** | |
544 | * ofnode_read_size_cells() - Get the number of size cells for a node | |
545 | * | |
546 | * This walks back up the tree to find the closest #size-cells property | |
547 | * which controls the given node. | |
548 | * | |
549 | * @node: Node to check | |
550 | * @return number of size cells this node uses | |
551 | */ | |
552 | int ofnode_read_size_cells(ofnode node); | |
553 | ||
554 | /** | |
555 | * ofnode_pre_reloc() - check if a node should be bound before relocation | |
556 | * | |
557 | * Device tree nodes can be marked as needing-to-be-bound in the loader stages | |
558 | * via special device tree properties. | |
559 | * | |
560 | * Before relocation this function can be used to check if nodes are required | |
561 | * in either SPL or TPL stages. | |
562 | * | |
563 | * After relocation and jumping into the real U-Boot binary it is possible to | |
564 | * determine if a node was bound in one of SPL/TPL stages. | |
565 | * | |
566 | * There are 3 settings currently in use | |
567 | * - | |
568 | * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL | |
569 | * Existing platforms only use it to indicate nodes needed in | |
570 | * SPL. Should probably be replaced by u-boot,dm-spl for | |
571 | * new platforms. | |
572 | * | |
573 | * @node: node to check | |
574 | * @eturns true if node is needed in SPL/TL, false otherwise | |
575 | */ | |
576 | bool ofnode_pre_reloc(ofnode node); | |
577 | ||
4984de2b | 578 | #endif |