blob: 59ce9174ad076bff7795c108c06620b026e6688f [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass0fbf66b2017-05-18 20:09:02 -06002/*
3 * Copyright (c) 2017 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glass0fbf66b2017-05-18 20:09:02 -06005 */
6
7#include <common.h>
Simon Glass0f2af882020-05-10 11:40:05 -06008#include <log.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +09009#include <linux/libfdt.h>
Simon Glass0fbf66b2017-05-18 20:09:02 -060010#include <dm/of_access.h>
11#include <dm/of_extra.h>
12#include <dm/ofnode.h>
13
Simon Glass4b580932018-06-11 13:07:17 -060014int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry)
Simon Glass0fbf66b2017-05-18 20:09:02 -060015{
16 const char *prop;
Simon Glassbf0a6922021-01-21 13:57:14 -070017 ofnode subnode;
Simon Glass0fbf66b2017-05-18 20:09:02 -060018
Simon Glass699c9ca2018-10-01 12:22:08 -060019 if (ofnode_read_u32(node, "image-pos", &entry->offset)) {
20 debug("Node '%s' has bad/missing 'image-pos' property\n",
Simon Glass4b580932018-06-11 13:07:17 -060021 ofnode_get_name(node));
Simon Glassbf0a6922021-01-21 13:57:14 -070022 return log_msg_ret("image-pos", -ENOENT);
Simon Glass0fbf66b2017-05-18 20:09:02 -060023 }
Simon Glass699c9ca2018-10-01 12:22:08 -060024 if (ofnode_read_u32(node, "size", &entry->length)) {
25 debug("Node '%s' has bad/missing 'size' property\n",
26 ofnode_get_name(node));
Simon Glassbf0a6922021-01-21 13:57:14 -070027 return log_msg_ret("size", -ENOENT);
Simon Glass699c9ca2018-10-01 12:22:08 -060028 }
Simon Glass0fbf66b2017-05-18 20:09:02 -060029 entry->used = ofnode_read_s32_default(node, "used", entry->length);
30 prop = ofnode_read_string(node, "compress");
Simon Glass699c9ca2018-10-01 12:22:08 -060031 if (prop) {
32 if (!strcmp(prop, "lz4"))
33 entry->compress_algo = FMAP_COMPRESS_LZ4;
Simon Glass49775172021-07-05 16:32:40 -060034 else if (!strcmp(prop, "lzma"))
35 entry->compress_algo = FMAP_COMPRESS_LZMA;
Simon Glass699c9ca2018-10-01 12:22:08 -060036 else
Simon Glassbf0a6922021-01-21 13:57:14 -070037 return log_msg_ret("compression algo", -EINVAL);
Simon Glass699c9ca2018-10-01 12:22:08 -060038 } else {
39 entry->compress_algo = FMAP_COMPRESS_NONE;
40 }
41 entry->unc_length = ofnode_read_s32_default(node, "uncomp-size",
42 entry->length);
Simon Glassbf0a6922021-01-21 13:57:14 -070043 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 }
Simon Glass0fbf66b2017-05-18 20:09:02 -060051
52 return 0;
53}
Simon Glass2e4d8722018-06-11 13:07:18 -060054
55int 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
76int 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}
Bin Meng72deec02021-03-14 20:14:46 +0800135
136bool 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}
Vladimir Olteanc0c35a02021-09-29 18:04:39 +0300158
159bool 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}