]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
b7e0d73b SG |
2 | /* |
3 | * Copyright (c) 2017 Google, Inc | |
4 | * Written by Simon Glass <[email protected]> | |
b7e0d73b SG |
5 | */ |
6 | ||
7 | #include <common.h> | |
f7ae49fc | 8 | #include <log.h> |
b08c8c48 | 9 | #include <linux/libfdt.h> |
b7e0d73b SG |
10 | #include <dm/of_access.h> |
11 | #include <dm/of_extra.h> | |
12 | #include <dm/ofnode.h> | |
13 | ||
5e0a7341 | 14 | int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry) |
b7e0d73b SG |
15 | { |
16 | const char *prop; | |
ff5fa7d6 | 17 | ofnode subnode; |
b7e0d73b | 18 | |
e6c5c94a SG |
19 | if (ofnode_read_u32(node, "image-pos", &entry->offset)) { |
20 | debug("Node '%s' has bad/missing 'image-pos' property\n", | |
5e0a7341 | 21 | ofnode_get_name(node)); |
ff5fa7d6 | 22 | return log_msg_ret("image-pos", -ENOENT); |
e6c5c94a SG |
23 | } |
24 | if (ofnode_read_u32(node, "size", &entry->length)) { | |
25 | debug("Node '%s' has bad/missing 'size' property\n", | |
26 | ofnode_get_name(node)); | |
ff5fa7d6 | 27 | return log_msg_ret("size", -ENOENT); |
b7e0d73b | 28 | } |
b7e0d73b SG |
29 | entry->used = ofnode_read_s32_default(node, "used", entry->length); |
30 | prop = ofnode_read_string(node, "compress"); | |
e6c5c94a SG |
31 | if (prop) { |
32 | if (!strcmp(prop, "lz4")) | |
33 | entry->compress_algo = FMAP_COMPRESS_LZ4; | |
504fb669 SG |
34 | else if (!strcmp(prop, "lzma")) |
35 | entry->compress_algo = FMAP_COMPRESS_LZMA; | |
e6c5c94a | 36 | else |
ff5fa7d6 | 37 | return log_msg_ret("compression algo", -EINVAL); |
e6c5c94a SG |
38 | } else { |
39 | entry->compress_algo = FMAP_COMPRESS_NONE; | |
40 | } | |
41 | entry->unc_length = ofnode_read_s32_default(node, "uncomp-size", | |
42 | entry->length); | |
ff5fa7d6 SG |
43 | subnode = ofnode_find_subnode(node, "hash"); |
44 | if (ofnode_valid(subnode)) { | |
45 | prop = ofnode_read_prop(subnode, "value", &entry->hash_size); | |
46 | ||
47 | /* Assume it is sha256 */ | |
48 | entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE; | |
49 | entry->hash = (uint8_t *)prop; | |
50 | } | |
b7e0d73b SG |
51 | |
52 | return 0; | |
53 | } | |
964cadc4 SG |
54 | |
55 | int ofnode_decode_region(ofnode node, const char *prop_name, fdt_addr_t *basep, | |
56 | fdt_size_t *sizep) | |
57 | { | |
58 | const fdt_addr_t *cell; | |
59 | int len; | |
60 | ||
61 | debug("%s: %s: %s\n", __func__, ofnode_get_name(node), prop_name); | |
62 | cell = ofnode_get_property(node, prop_name, &len); | |
63 | if (!cell || (len < sizeof(fdt_addr_t) * 2)) { | |
64 | debug("cell=%p, len=%d\n", cell, len); | |
65 | return -1; | |
66 | } | |
67 | ||
68 | *basep = fdt_addr_to_cpu(*cell); | |
69 | *sizep = fdt_size_to_cpu(cell[1]); | |
70 | debug("%s: base=%08lx, size=%lx\n", __func__, (ulong)*basep, | |
71 | (ulong)*sizep); | |
72 | ||
73 | return 0; | |
74 | } | |
75 | ||
76 | int ofnode_decode_memory_region(ofnode config_node, const char *mem_type, | |
77 | const char *suffix, fdt_addr_t *basep, | |
78 | fdt_size_t *sizep) | |
79 | { | |
80 | char prop_name[50]; | |
81 | const char *mem; | |
82 | fdt_size_t size, offset_size; | |
83 | fdt_addr_t base, offset; | |
84 | ofnode node; | |
85 | ||
86 | if (!ofnode_valid(config_node)) { | |
87 | config_node = ofnode_path("/config"); | |
88 | if (!ofnode_valid(config_node)) { | |
89 | debug("%s: Cannot find /config node\n", __func__); | |
90 | return -ENOENT; | |
91 | } | |
92 | } | |
93 | if (!suffix) | |
94 | suffix = ""; | |
95 | ||
96 | snprintf(prop_name, sizeof(prop_name), "%s-memory%s", mem_type, | |
97 | suffix); | |
98 | mem = ofnode_read_string(config_node, prop_name); | |
99 | if (!mem) { | |
100 | debug("%s: No memory type for '%s', using /memory\n", __func__, | |
101 | prop_name); | |
102 | mem = "/memory"; | |
103 | } | |
104 | ||
105 | node = ofnode_path(mem); | |
106 | if (!ofnode_valid(node)) { | |
107 | debug("%s: Failed to find node '%s'\n", __func__, mem); | |
108 | return -ENOENT; | |
109 | } | |
110 | ||
111 | /* | |
112 | * Not strictly correct - the memory may have multiple banks. We just | |
113 | * use the first | |
114 | */ | |
115 | if (ofnode_decode_region(node, "reg", &base, &size)) { | |
116 | debug("%s: Failed to decode memory region %s\n", __func__, | |
117 | mem); | |
118 | return -EINVAL; | |
119 | } | |
120 | ||
121 | snprintf(prop_name, sizeof(prop_name), "%s-offset%s", mem_type, | |
122 | suffix); | |
123 | if (ofnode_decode_region(config_node, prop_name, &offset, | |
124 | &offset_size)) { | |
125 | debug("%s: Failed to decode memory region '%s'\n", __func__, | |
126 | prop_name); | |
127 | return -EINVAL; | |
128 | } | |
129 | ||
130 | *basep = base + offset; | |
131 | *sizep = offset_size; | |
132 | ||
133 | return 0; | |
134 | } | |
173c66bf BM |
135 | |
136 | bool ofnode_phy_is_fixed_link(ofnode eth_node, ofnode *phy_node) | |
137 | { | |
138 | ofnode node, subnode; | |
139 | int len; | |
140 | ||
141 | subnode = ofnode_find_subnode(eth_node, "fixed-link"); | |
142 | if (ofnode_valid(subnode)) { | |
143 | /* new binding */ | |
144 | node = subnode; | |
145 | } else if (ofnode_get_property(eth_node, "fixed-link", &len) && | |
146 | len == (5 * sizeof(__be32))) { | |
147 | /* old binding */ | |
148 | node = eth_node; | |
149 | } else { | |
150 | return false; | |
151 | } | |
152 | ||
153 | if (phy_node) | |
154 | *phy_node = node; | |
155 | ||
156 | return true; | |
157 | } | |
2dd6acb7 VO |
158 | |
159 | bool ofnode_eth_uses_inband_aneg(ofnode eth_node) | |
160 | { | |
161 | bool inband_aneg = false; | |
162 | const char *managed; | |
163 | ||
164 | managed = ofnode_read_string(eth_node, "managed"); | |
165 | if (managed && !strcmp(managed, "in-band-status")) | |
166 | inband_aneg = true; | |
167 | ||
168 | return inband_aneg; | |
169 | } |