1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2017 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
10 #include <fdt_support.h>
13 #include <linux/libfdt.h>
14 #include <dm/of_access.h>
15 #include <dm/of_addr.h>
16 #include <dm/ofnode.h>
17 #include <linux/err.h>
18 #include <linux/ioport.h>
19 #include <asm/global_data.h>
22 * ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree)
24 * Looks up the tree and returns an ofnode with the correct of_offset
26 * If @offset is < 0 then this returns an ofnode with that offset
28 * @tree: tree to check
29 * @offset: offset within that tree (can be < 0)
30 * @return node for that offset
32 static ofnode ofnode_from_tree_offset(oftree tree, int offset)
36 node.of_offset = offset;
41 bool ofnode_name_eq(ofnode node, const char *name)
43 const char *node_name;
46 assert(ofnode_valid(node));
48 node_name = ofnode_get_name(node);
49 len = strchrnul(node_name, '@') - node_name;
51 return (strlen(name) == len) && !strncmp(node_name, name, len);
54 int ofnode_read_u8(ofnode node, const char *propname, u8 *outp)
59 assert(ofnode_valid(node));
60 debug("%s: %s: ", __func__, propname);
62 if (ofnode_is_np(node))
63 return of_read_u8(ofnode_to_np(node), propname, outp);
65 cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
67 if (!cell || len < sizeof(*cell)) {
68 debug("(not found)\n");
72 debug("%#x (%d)\n", *outp, *outp);
77 u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def)
79 assert(ofnode_valid(node));
80 ofnode_read_u8(node, propname, &def);
85 int ofnode_read_u16(ofnode node, const char *propname, u16 *outp)
90 assert(ofnode_valid(node));
91 debug("%s: %s: ", __func__, propname);
93 if (ofnode_is_np(node))
94 return of_read_u16(ofnode_to_np(node), propname, outp);
96 cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
98 if (!cell || len < sizeof(*cell)) {
99 debug("(not found)\n");
102 *outp = be16_to_cpup(cell);
103 debug("%#x (%d)\n", *outp, *outp);
108 u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def)
110 assert(ofnode_valid(node));
111 ofnode_read_u16(node, propname, &def);
116 int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
118 return ofnode_read_u32_index(node, propname, 0, outp);
121 u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def)
123 assert(ofnode_valid(node));
124 ofnode_read_u32_index(node, propname, 0, &def);
129 int ofnode_read_u32_index(ofnode node, const char *propname, int index,
135 assert(ofnode_valid(node));
136 debug("%s: %s: ", __func__, propname);
138 if (ofnode_is_np(node))
139 return of_read_u32_index(ofnode_to_np(node), propname, index,
142 cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
145 debug("(not found)\n");
149 if (len < (sizeof(int) * (index + 1))) {
150 debug("(not large enough)\n");
154 *outp = fdt32_to_cpu(cell[index]);
155 debug("%#x (%d)\n", *outp, *outp);
160 u32 ofnode_read_u32_index_default(ofnode node, const char *propname, int index,
163 assert(ofnode_valid(node));
164 ofnode_read_u32_index(node, propname, index, &def);
169 int ofnode_read_s32_default(ofnode node, const char *propname, s32 def)
171 assert(ofnode_valid(node));
172 ofnode_read_u32(node, propname, (u32 *)&def);
177 int ofnode_read_u64(ofnode node, const char *propname, u64 *outp)
179 const unaligned_fdt64_t *cell;
182 assert(ofnode_valid(node));
183 debug("%s: %s: ", __func__, propname);
185 if (ofnode_is_np(node))
186 return of_read_u64(ofnode_to_np(node), propname, outp);
188 cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
190 if (!cell || len < sizeof(*cell)) {
191 debug("(not found)\n");
194 *outp = fdt64_to_cpu(cell[0]);
195 debug("%#llx (%lld)\n", (unsigned long long)*outp,
196 (unsigned long long)*outp);
201 u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def)
203 assert(ofnode_valid(node));
204 ofnode_read_u64(node, propname, &def);
209 bool ofnode_read_bool(ofnode node, const char *propname)
213 assert(ofnode_valid(node));
214 debug("%s: %s: ", __func__, propname);
216 prop = ofnode_get_property(node, propname, NULL);
218 debug("%s\n", prop ? "true" : "false");
220 return prop ? true : false;
223 const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep)
225 const char *val = NULL;
228 assert(ofnode_valid(node));
229 debug("%s: %s: ", __func__, propname);
231 if (ofnode_is_np(node)) {
232 struct property *prop = of_find_property(
233 ofnode_to_np(node), propname, &len);
240 val = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
244 debug("<not found>\n");
246 *sizep = -FDT_ERR_NOTFOUND;
255 const char *ofnode_read_string(ofnode node, const char *propname)
260 str = ofnode_read_prop(node, propname, &len);
264 if (strnlen(str, len) >= len) {
265 debug("<invalid>\n");
273 int ofnode_read_size(ofnode node, const char *propname)
277 if (!ofnode_read_prop(node, propname, &len))
283 ofnode ofnode_find_subnode(ofnode node, const char *subnode_name)
287 assert(ofnode_valid(node));
288 debug("%s: %s: ", __func__, subnode_name);
290 if (ofnode_is_np(node)) {
291 struct device_node *np = ofnode_to_np(node);
293 for (np = np->child; np; np = np->sibling) {
294 if (!strcmp(subnode_name, np->name))
297 subnode = np_to_ofnode(np);
299 int ooffset = fdt_subnode_offset(ofnode_to_fdt(node),
300 ofnode_to_offset(node), subnode_name);
301 subnode = noffset_to_ofnode(node, ooffset);
303 debug("%s\n", ofnode_valid(subnode) ?
304 ofnode_get_name(subnode) : "<none>");
309 int ofnode_read_u32_array(ofnode node, const char *propname,
310 u32 *out_values, size_t sz)
312 assert(ofnode_valid(node));
313 debug("%s: %s: ", __func__, propname);
315 if (ofnode_is_np(node)) {
316 return of_read_u32_array(ofnode_to_np(node), propname,
321 ret = fdtdec_get_int_array(ofnode_to_fdt(node),
322 ofnode_to_offset(node), propname,
325 /* get the error right, but space is more important in SPL */
326 if (!IS_ENABLED(CONFIG_SPL_BUILD)) {
327 if (ret == -FDT_ERR_NOTFOUND)
329 else if (ret == -FDT_ERR_BADLAYOUT)
336 #if !CONFIG_IS_ENABLED(DM_INLINE_OFNODE)
337 bool ofnode_is_enabled(ofnode node)
339 if (ofnode_is_np(node)) {
340 return of_device_is_available(ofnode_to_np(node));
342 return fdtdec_get_is_enabled(ofnode_to_fdt(node),
343 ofnode_to_offset(node));
347 ofnode ofnode_first_subnode(ofnode node)
349 assert(ofnode_valid(node));
350 if (ofnode_is_np(node))
351 return np_to_ofnode(node.np->child);
353 return noffset_to_ofnode(node,
354 fdt_first_subnode(ofnode_to_fdt(node), ofnode_to_offset(node)));
357 ofnode ofnode_next_subnode(ofnode node)
359 assert(ofnode_valid(node));
360 if (ofnode_is_np(node))
361 return np_to_ofnode(node.np->sibling);
363 return noffset_to_ofnode(node,
364 fdt_next_subnode(ofnode_to_fdt(node), ofnode_to_offset(node)));
366 #endif /* !DM_INLINE_OFNODE */
368 ofnode ofnode_get_parent(ofnode node)
372 assert(ofnode_valid(node));
373 if (ofnode_is_np(node))
374 parent = np_to_ofnode(of_get_parent(ofnode_to_np(node)));
376 parent.of_offset = fdt_parent_offset(ofnode_to_fdt(node),
377 ofnode_to_offset(node));
382 const char *ofnode_get_name(ofnode node)
384 if (!ofnode_valid(node)) {
385 debug("%s node not valid\n", __func__);
389 if (ofnode_is_np(node))
390 return node.np->name;
392 return fdt_get_name(ofnode_to_fdt(node), ofnode_to_offset(node), NULL);
395 int ofnode_get_path(ofnode node, char *buf, int buflen)
397 assert(ofnode_valid(node));
399 if (ofnode_is_np(node)) {
400 if (strlen(node.np->full_name) >= buflen)
403 strcpy(buf, node.np->full_name);
409 res = fdt_get_path(ofnode_to_fdt(node), ofnode_to_offset(node), buf,
413 else if (res == -FDT_ERR_NOSPACE)
420 ofnode ofnode_get_by_phandle(uint phandle)
424 if (of_live_active())
425 node = np_to_ofnode(of_find_node_by_phandle(NULL, phandle));
427 node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob,
433 ofnode oftree_get_by_phandle(oftree tree, uint phandle)
437 if (of_live_active())
438 node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle));
441 fdt_node_offset_by_phandle(oftree_lookup_fdt(tree),
447 static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index,
448 fdt_size_t *size, bool translate)
453 *size = FDT_SIZE_T_NONE;
455 if (ofnode_is_np(node)) {
456 const __be32 *prop_val;
460 prop_val = of_get_address(ofnode_to_np(node), index, &size64,
463 return FDT_ADDR_T_NONE;
468 ns = of_n_size_cells(ofnode_to_np(node));
470 if (translate && IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
471 return of_translate_address(ofnode_to_np(node), prop_val);
473 na = of_n_addr_cells(ofnode_to_np(node));
474 return of_read_number(prop_val, na);
477 na = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
478 ns = ofnode_read_simple_size_cells(ofnode_get_parent(node));
479 return fdtdec_get_addr_size_fixed(ofnode_to_fdt(node),
480 ofnode_to_offset(node), "reg",
486 fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
488 return __ofnode_get_addr_size_index(node, index, size, true);
491 fdt_addr_t ofnode_get_addr_size_index_notrans(ofnode node, int index,
494 return __ofnode_get_addr_size_index(node, index, size, false);
497 fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
501 return ofnode_get_addr_size_index(node, index, &size);
504 fdt_addr_t ofnode_get_addr(ofnode node)
506 return ofnode_get_addr_index(node, 0);
509 fdt_size_t ofnode_get_size(ofnode node)
513 ofnode_get_addr_size_index(node, 0, &size);
518 int ofnode_stringlist_search(ofnode node, const char *property,
521 if (ofnode_is_np(node)) {
522 return of_property_match_string(ofnode_to_np(node),
527 ret = fdt_stringlist_search(ofnode_to_fdt(node),
528 ofnode_to_offset(node), property,
530 if (ret == -FDT_ERR_NOTFOUND)
539 int ofnode_read_string_index(ofnode node, const char *property, int index,
542 if (ofnode_is_np(node)) {
543 return of_property_read_string_index(ofnode_to_np(node),
544 property, index, outp);
548 *outp = fdt_stringlist_get(ofnode_to_fdt(node),
549 ofnode_to_offset(node),
550 property, index, &len);
557 int ofnode_read_string_count(ofnode node, const char *property)
559 if (ofnode_is_np(node)) {
560 return of_property_count_strings(ofnode_to_np(node), property);
562 return fdt_stringlist_count(ofnode_to_fdt(node),
563 ofnode_to_offset(node), property);
567 int ofnode_read_string_list(ofnode node, const char *property,
575 count = ofnode_read_string_count(node, property);
581 prop = calloc(count + 1, sizeof(char *));
585 for (i = 0; i < count; i++)
586 ofnode_read_string_index(node, property, i, &prop[i]);
593 static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in,
594 struct ofnode_phandle_args *out)
596 assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
597 out->node = offset_to_ofnode(in->node);
598 out->args_count = in->args_count;
599 memcpy(out->args, in->args, sizeof(out->args));
602 static void ofnode_from_of_phandle_args(struct of_phandle_args *in,
603 struct ofnode_phandle_args *out)
605 assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
606 out->node = np_to_ofnode(in->np);
607 out->args_count = in->args_count;
608 memcpy(out->args, in->args, sizeof(out->args));
611 int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
612 const char *cells_name, int cell_count,
614 struct ofnode_phandle_args *out_args)
616 if (ofnode_is_np(node)) {
617 struct of_phandle_args args;
620 ret = of_parse_phandle_with_args(ofnode_to_np(node),
621 list_name, cells_name,
626 ofnode_from_of_phandle_args(&args, out_args);
628 struct fdtdec_phandle_args args;
631 ret = fdtdec_parse_phandle_with_args(ofnode_to_fdt(node),
632 ofnode_to_offset(node),
633 list_name, cells_name,
634 cell_count, index, &args);
637 ofnode_from_fdtdec_phandle_args(&args, out_args);
643 int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
644 const char *cells_name, int cell_count)
646 if (ofnode_is_np(node))
647 return of_count_phandle_with_args(ofnode_to_np(node),
648 list_name, cells_name, cell_count);
650 return fdtdec_parse_phandle_with_args(ofnode_to_fdt(node),
651 ofnode_to_offset(node), list_name, cells_name,
652 cell_count, -1, NULL);
655 ofnode ofnode_path(const char *path)
657 if (of_live_active())
658 return np_to_ofnode(of_find_node_by_path(path));
660 return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path));
663 ofnode oftree_root(oftree tree)
665 if (of_live_active()) {
666 return np_to_ofnode(tree.np);
668 return ofnode_from_tree_offset(tree, 0);
672 ofnode oftree_path(oftree tree, const char *path)
674 if (of_live_active()) {
675 return np_to_ofnode(of_find_node_opts_by_path(tree.np, path,
677 } else if (*path != '/' && tree.fdt != gd->fdt_blob) {
678 return ofnode_null(); /* Aliases only on control FDT */
680 int offset = fdt_path_offset(tree.fdt, path);
682 return ofnode_from_tree_offset(tree, offset);
686 const void *ofnode_read_chosen_prop(const char *propname, int *sizep)
690 chosen_node = ofnode_path("/chosen");
692 return ofnode_read_prop(chosen_node, propname, sizep);
695 const char *ofnode_read_chosen_string(const char *propname)
697 return ofnode_read_chosen_prop(propname, NULL);
700 ofnode ofnode_get_chosen_node(const char *name)
704 prop = ofnode_read_chosen_prop(name, NULL);
706 return ofnode_null();
708 return ofnode_path(prop);
711 const void *ofnode_read_aliases_prop(const char *propname, int *sizep)
715 node = ofnode_path("/aliases");
717 return ofnode_read_prop(node, propname, sizep);
720 ofnode ofnode_get_aliases_node(const char *name)
724 prop = ofnode_read_aliases_prop(name, NULL);
726 return ofnode_null();
728 debug("%s: node_path: %s\n", __func__, prop);
730 return ofnode_path(prop);
733 int ofnode_get_child_count(ofnode parent)
738 ofnode_for_each_subnode(child, parent)
744 static int decode_timing_property(ofnode node, const char *name,
745 struct timing_entry *result)
749 length = ofnode_read_size(node, name);
751 debug("%s: could not find property %s\n",
752 ofnode_get_name(node), name);
756 if (length == sizeof(u32)) {
757 result->typ = ofnode_read_u32_default(node, name, 0);
758 result->min = result->typ;
759 result->max = result->typ;
761 ret = ofnode_read_u32_array(node, name, &result->min, 3);
767 int ofnode_decode_display_timing(ofnode parent, int index,
768 struct display_timing *dt)
771 ofnode timings, node;
775 timings = ofnode_find_subnode(parent, "display-timings");
776 if (!ofnode_valid(timings))
780 ofnode_for_each_subnode(node, timings) {
785 if (!ofnode_valid(node))
788 memset(dt, 0, sizeof(*dt));
790 ret |= decode_timing_property(node, "hback-porch", &dt->hback_porch);
791 ret |= decode_timing_property(node, "hfront-porch", &dt->hfront_porch);
792 ret |= decode_timing_property(node, "hactive", &dt->hactive);
793 ret |= decode_timing_property(node, "hsync-len", &dt->hsync_len);
794 ret |= decode_timing_property(node, "vback-porch", &dt->vback_porch);
795 ret |= decode_timing_property(node, "vfront-porch", &dt->vfront_porch);
796 ret |= decode_timing_property(node, "vactive", &dt->vactive);
797 ret |= decode_timing_property(node, "vsync-len", &dt->vsync_len);
798 ret |= decode_timing_property(node, "clock-frequency", &dt->pixelclock);
801 val = ofnode_read_u32_default(node, "vsync-active", -1);
803 dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
804 DISPLAY_FLAGS_VSYNC_LOW;
806 val = ofnode_read_u32_default(node, "hsync-active", -1);
808 dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
809 DISPLAY_FLAGS_HSYNC_LOW;
811 val = ofnode_read_u32_default(node, "de-active", -1);
813 dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
814 DISPLAY_FLAGS_DE_LOW;
816 val = ofnode_read_u32_default(node, "pixelclk-active", -1);
818 dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
819 DISPLAY_FLAGS_PIXDATA_NEGEDGE;
822 if (ofnode_read_bool(node, "interlaced"))
823 dt->flags |= DISPLAY_FLAGS_INTERLACED;
824 if (ofnode_read_bool(node, "doublescan"))
825 dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
826 if (ofnode_read_bool(node, "doubleclk"))
827 dt->flags |= DISPLAY_FLAGS_DOUBLECLK;
832 const void *ofnode_get_property(ofnode node, const char *propname, int *lenp)
834 if (ofnode_is_np(node))
835 return of_get_property(ofnode_to_np(node), propname, lenp);
837 return fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
841 int ofnode_first_property(ofnode node, struct ofprop *prop)
845 if (ofnode_is_np(node)) {
846 prop->prop = of_get_first_property(ofnode_to_np(prop->node));
848 return -FDT_ERR_NOTFOUND;
851 fdt_first_property_offset(ofnode_to_fdt(node),
852 ofnode_to_offset(prop->node));
853 if (prop->offset < 0)
860 int ofnode_next_property(struct ofprop *prop)
862 if (ofnode_is_np(prop->node)) {
863 prop->prop = of_get_next_property(ofnode_to_np(prop->node),
866 return -FDT_ERR_NOTFOUND;
869 fdt_next_property_offset(ofnode_to_fdt(prop->node),
871 if (prop->offset < 0)
878 const void *ofprop_get_property(const struct ofprop *prop,
879 const char **propname, int *lenp)
881 if (ofnode_is_np(prop->node))
882 return of_get_property_by_prop(ofnode_to_np(prop->node),
883 prop->prop, propname, lenp);
885 return fdt_getprop_by_offset(ofnode_to_fdt(prop->node),
890 fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
893 if (ofnode_is_np(node)) {
896 const struct device_node *np = ofnode_to_np(node);
897 const __be32 *prop = of_get_property(np, property, &psize);
900 return FDT_ADDR_T_NONE;
901 na = of_n_addr_cells(np);
902 ns = of_n_size_cells(np);
903 *sizep = of_read_number(prop + na, ns);
905 if (CONFIG_IS_ENABLED(OF_TRANSLATE) && ns > 0)
906 return of_translate_address(np, prop);
908 return of_read_number(prop, na);
910 return fdtdec_get_addr_size(ofnode_to_fdt(node),
911 ofnode_to_offset(node), property,
916 const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
919 if (ofnode_is_np(node)) {
920 const struct device_node *np = ofnode_to_np(node);
922 const __be32 *prop = of_get_property(np, propname, &psize);
924 if (!prop || sz != psize)
926 return (uint8_t *)prop;
929 return fdtdec_locate_byte_array(ofnode_to_fdt(node),
930 ofnode_to_offset(node), propname, sz);
934 int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
935 const char *propname, struct fdt_pci_addr *addr)
941 debug("%s: %s: ", __func__, propname);
944 * If we follow the pci bus bindings strictly, we should check
945 * the value of the node's parent node's #address-cells and
946 * #size-cells. They need to be 3 and 2 accordingly. However,
947 * for simplicity we skip the check here.
949 cell = ofnode_get_property(node, propname, &len);
953 if ((len % FDT_PCI_REG_SIZE) == 0) {
954 int num = len / FDT_PCI_REG_SIZE;
957 for (i = 0; i < num; i++) {
958 debug("pci address #%d: %08lx %08lx %08lx\n", i,
959 (ulong)fdt32_to_cpu(cell[0]),
960 (ulong)fdt32_to_cpu(cell[1]),
961 (ulong)fdt32_to_cpu(cell[2]));
962 if ((fdt32_to_cpu(*cell) & type) == type) {
963 addr->phys_hi = fdt32_to_cpu(cell[0]);
964 addr->phys_mid = fdt32_to_cpu(cell[1]);
965 addr->phys_lo = fdt32_to_cpu(cell[2]);
969 cell += (FDT_PCI_ADDR_CELLS +
984 debug("(not found)\n");
988 int ofnode_read_pci_vendev(ofnode node, u16 *vendor, u16 *device)
990 const char *list, *end;
993 list = ofnode_get_property(node, "compatible", &len);
1000 if (len >= strlen("pciVVVV,DDDD")) {
1001 char *s = strstr(list, "pci");
1004 * check if the string is something like pciVVVV,DDDD.RR
1005 * or just pciVVVV,DDDD
1007 if (s && s[7] == ',' &&
1008 (s[12] == '.' || s[12] == 0)) {
1010 *vendor = simple_strtol(s, NULL, 16);
1013 *device = simple_strtol(s, NULL, 16);
1024 int ofnode_read_eth_phy_id(ofnode node, u16 *vendor, u16 *device)
1026 const char *list, *end;
1029 list = ofnode_get_property(node, "compatible", &len);
1035 while (list < end) {
1038 if (len >= strlen("ethernet-phy-idVVVV,DDDD")) {
1039 char *s = strstr(list, "ethernet-phy-id");
1042 * check if the string is something like
1043 * ethernet-phy-idVVVV,DDDD
1045 if (s && s[19] == '.') {
1046 s += strlen("ethernet-phy-id");
1047 *vendor = simple_strtol(s, NULL, 16);
1049 *device = simple_strtol(s, NULL, 16);
1060 int ofnode_read_addr_cells(ofnode node)
1062 if (ofnode_is_np(node)) {
1063 return of_n_addr_cells(ofnode_to_np(node));
1065 int parent = fdt_parent_offset(ofnode_to_fdt(node),
1066 ofnode_to_offset(node));
1068 return fdt_address_cells(ofnode_to_fdt(node), parent);
1072 int ofnode_read_size_cells(ofnode node)
1074 if (ofnode_is_np(node)) {
1075 return of_n_size_cells(ofnode_to_np(node));
1077 int parent = fdt_parent_offset(ofnode_to_fdt(node),
1078 ofnode_to_offset(node));
1080 return fdt_size_cells(ofnode_to_fdt(node), parent);
1084 int ofnode_read_simple_addr_cells(ofnode node)
1086 if (ofnode_is_np(node))
1087 return of_simple_addr_cells(ofnode_to_np(node));
1089 return fdt_address_cells(ofnode_to_fdt(node),
1090 ofnode_to_offset(node));
1093 int ofnode_read_simple_size_cells(ofnode node)
1095 if (ofnode_is_np(node))
1096 return of_simple_size_cells(ofnode_to_np(node));
1098 return fdt_size_cells(ofnode_to_fdt(node),
1099 ofnode_to_offset(node));
1102 bool ofnode_pre_reloc(ofnode node)
1104 #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD)
1105 /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass
1106 * had property dm-pre-reloc or u-boot,dm-spl/tpl.
1107 * They are removed in final dtb (fdtgrep 2nd pass)
1111 if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
1113 if (ofnode_read_bool(node, "u-boot,dm-pre-proper"))
1117 * In regular builds individual spl and tpl handling both
1118 * count as handled pre-relocation for later second init.
1120 if (ofnode_read_bool(node, "u-boot,dm-spl") ||
1121 ofnode_read_bool(node, "u-boot,dm-tpl"))
1128 int ofnode_read_resource(ofnode node, uint index, struct resource *res)
1130 if (ofnode_is_np(node)) {
1131 return of_address_to_resource(ofnode_to_np(node), index, res);
1133 struct fdt_resource fres;
1136 ret = fdt_get_resource(ofnode_to_fdt(node),
1137 ofnode_to_offset(node),
1138 "reg", index, &fres);
1141 memset(res, '\0', sizeof(*res));
1142 res->start = fres.start;
1143 res->end = fres.end;
1149 int ofnode_read_resource_byname(ofnode node, const char *name,
1150 struct resource *res)
1154 index = ofnode_stringlist_search(node, "reg-names", name);
1158 return ofnode_read_resource(node, index, res);
1161 u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr)
1163 if (ofnode_is_np(node))
1164 return of_translate_address(ofnode_to_np(node), in_addr);
1166 return fdt_translate_address(ofnode_to_fdt(node),
1167 ofnode_to_offset(node), in_addr);
1170 u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr)
1172 if (ofnode_is_np(node))
1173 return of_translate_dma_address(ofnode_to_np(node), in_addr);
1175 return fdt_translate_dma_address(ofnode_to_fdt(node),
1176 ofnode_to_offset(node), in_addr);
1179 int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *size)
1181 if (ofnode_is_np(node))
1182 return of_get_dma_range(ofnode_to_np(node), cpu, bus, size);
1184 return fdt_get_dma_range(ofnode_to_fdt(node),
1185 ofnode_to_offset(node),
1189 int ofnode_device_is_compatible(ofnode node, const char *compat)
1191 if (ofnode_is_np(node))
1192 return of_device_is_compatible(ofnode_to_np(node), compat,
1195 return !fdt_node_check_compatible(ofnode_to_fdt(node),
1196 ofnode_to_offset(node),
1200 ofnode ofnode_by_compatible(ofnode from, const char *compat)
1202 if (of_live_active()) {
1203 return np_to_ofnode(of_find_compatible_node(
1204 (struct device_node *)ofnode_to_np(from), NULL,
1207 return noffset_to_ofnode(from,
1208 fdt_node_offset_by_compatible(ofnode_to_fdt(from),
1209 ofnode_to_offset(from), compat));
1213 ofnode ofnode_by_prop_value(ofnode from, const char *propname,
1214 const void *propval, int proplen)
1216 if (of_live_active()) {
1217 return np_to_ofnode(of_find_node_by_prop_value(
1218 (struct device_node *)ofnode_to_np(from), propname,
1221 return noffset_to_ofnode(from,
1222 fdt_node_offset_by_prop_value(ofnode_to_fdt(from),
1223 ofnode_to_offset(from), propname, propval,
1228 int ofnode_write_prop(ofnode node, const char *propname, const void *value,
1231 if (of_live_active())
1232 return of_write_prop(ofnode_to_np(node), propname, len, value);
1234 return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node),
1235 propname, value, len);
1240 int ofnode_write_string(ofnode node, const char *propname, const char *value)
1242 assert(ofnode_valid(node));
1244 debug("%s: %s = %s", __func__, propname, value);
1246 return ofnode_write_prop(node, propname, value, strlen(value) + 1);
1249 int ofnode_write_u32(ofnode node, const char *propname, u32 value)
1253 assert(ofnode_valid(node));
1255 log_debug("%s = %x", propname, value);
1256 val = malloc(sizeof(*val));
1259 *val = cpu_to_fdt32(value);
1261 return ofnode_write_prop(node, propname, val, sizeof(value));
1264 int ofnode_set_enabled(ofnode node, bool value)
1266 assert(ofnode_valid(node));
1269 return ofnode_write_string(node, "status", "okay");
1271 return ofnode_write_string(node, "status", "disabled");
1274 bool ofnode_conf_read_bool(const char *prop_name)
1278 node = ofnode_path("/config");
1279 if (!ofnode_valid(node))
1282 return ofnode_read_bool(node, prop_name);
1285 int ofnode_conf_read_int(const char *prop_name, int default_val)
1289 node = ofnode_path("/config");
1290 if (!ofnode_valid(node))
1293 return ofnode_read_u32_default(node, prop_name, default_val);
1296 const char *ofnode_conf_read_str(const char *prop_name)
1300 node = ofnode_path("/config");
1301 if (!ofnode_valid(node))
1304 return ofnode_read_string(node, prop_name);
1307 ofnode ofnode_get_phy_node(ofnode node)
1309 /* DT node properties that reference a PHY node */
1310 static const char * const phy_handle_str[] = {
1311 "phy-handle", "phy", "phy-device",
1313 struct ofnode_phandle_args args = {
1314 .node = ofnode_null()
1318 assert(ofnode_valid(node));
1320 for (i = 0; i < ARRAY_SIZE(phy_handle_str); i++)
1321 if (!ofnode_parse_phandle_with_args(node, phy_handle_str[i],
1328 phy_interface_t ofnode_read_phy_mode(ofnode node)
1333 assert(ofnode_valid(node));
1335 mode = ofnode_read_string(node, "phy-mode");
1337 mode = ofnode_read_string(node, "phy-connection-type");
1340 return PHY_INTERFACE_MODE_NA;
1342 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
1343 if (!strcmp(mode, phy_interface_strings[i]))
1346 debug("%s: Invalid PHY interface '%s'\n", __func__, mode);
1348 return PHY_INTERFACE_MODE_NA;
1351 int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep)
1356 assert(ofnode_valid(node));
1358 if (ofnode_is_np(node)) {
1359 struct device_node *np, *child;
1361 np = (struct device_node *)ofnode_to_np(node);
1362 ret = of_add_subnode(np, name, -1, &child);
1363 if (ret && ret != -EEXIST)
1365 subnode = np_to_ofnode(child);
1367 void *fdt = ofnode_to_fdt(node);
1368 int poffset = ofnode_to_offset(node);
1371 offset = fdt_add_subnode(fdt, poffset, name);
1372 if (offset == -FDT_ERR_EXISTS) {
1373 offset = fdt_subnode_offset(fdt, poffset, name);
1378 subnode = noffset_to_ofnode(node, offset);
1381 *subnodep = subnode;
1383 return ret; /* 0 or -EEXIST */