xref: /rk3399_ARM-atf/plat/st/common/stm32mp_dt.c (revision 52a616b48c617fe8721106f29f2910ca4681afea)
1c9d75b3cSYann Gautier /*
2cd4941deSYann Gautier  * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3c9d75b3cSYann Gautier  *
4c9d75b3cSYann Gautier  * SPDX-License-Identifier: BSD-3-Clause
5c9d75b3cSYann Gautier  */
6c9d75b3cSYann Gautier 
7c9d75b3cSYann Gautier #include <assert.h>
8c9d75b3cSYann Gautier #include <errno.h>
9c9d75b3cSYann Gautier 
10c9d75b3cSYann Gautier #include <libfdt.h>
11c9d75b3cSYann Gautier 
12c9d75b3cSYann Gautier #include <platform_def.h>
13c9d75b3cSYann Gautier 
14c9d75b3cSYann Gautier #include <common/debug.h>
15*52a616b4SAndre Przywara #include <common/fdt_wrappers.h>
16c9d75b3cSYann Gautier #include <drivers/st/stm32_gpio.h>
17c9d75b3cSYann Gautier #include <drivers/st/stm32mp1_ddr.h>
18c9d75b3cSYann Gautier #include <drivers/st/stm32mp1_ram.h>
19c9d75b3cSYann Gautier 
20c9d75b3cSYann Gautier #include <stm32mp_dt.h>
21c9d75b3cSYann Gautier 
22c9d75b3cSYann Gautier static int fdt_checked;
23c9d75b3cSYann Gautier 
243f9c9784SYann Gautier static void *fdt = (void *)(uintptr_t)STM32MP_DTB_BASE;
25c9d75b3cSYann Gautier 
26c9d75b3cSYann Gautier /*******************************************************************************
27c9d75b3cSYann Gautier  * This function checks device tree file with its header.
28c9d75b3cSYann Gautier  * Returns 0 on success and a negative FDT error code on failure.
29c9d75b3cSYann Gautier  ******************************************************************************/
30c9d75b3cSYann Gautier int dt_open_and_check(void)
31c9d75b3cSYann Gautier {
32c9d75b3cSYann Gautier 	int ret = fdt_check_header(fdt);
33c9d75b3cSYann Gautier 
34c9d75b3cSYann Gautier 	if (ret == 0) {
35c9d75b3cSYann Gautier 		fdt_checked = 1;
36c9d75b3cSYann Gautier 	}
37c9d75b3cSYann Gautier 
38c9d75b3cSYann Gautier 	return ret;
39c9d75b3cSYann Gautier }
40c9d75b3cSYann Gautier 
41c9d75b3cSYann Gautier /*******************************************************************************
42c9d75b3cSYann Gautier  * This function gets the address of the DT.
43c9d75b3cSYann Gautier  * If DT is OK, fdt_addr is filled with DT address.
44c9d75b3cSYann Gautier  * Returns 1 if success, 0 otherwise.
45c9d75b3cSYann Gautier  ******************************************************************************/
46c9d75b3cSYann Gautier int fdt_get_address(void **fdt_addr)
47c9d75b3cSYann Gautier {
48c9d75b3cSYann Gautier 	if (fdt_checked == 1) {
49c9d75b3cSYann Gautier 		*fdt_addr = fdt;
50c9d75b3cSYann Gautier 	}
51c9d75b3cSYann Gautier 
52c9d75b3cSYann Gautier 	return fdt_checked;
53c9d75b3cSYann Gautier }
54c9d75b3cSYann Gautier 
55c9d75b3cSYann Gautier /*******************************************************************************
56c9d75b3cSYann Gautier  * This function check the presence of a node (generic use of fdt library).
57c9d75b3cSYann Gautier  * Returns true if present, else return false.
58c9d75b3cSYann Gautier  ******************************************************************************/
59c9d75b3cSYann Gautier bool fdt_check_node(int node)
60c9d75b3cSYann Gautier {
61c9d75b3cSYann Gautier 	int len;
62c9d75b3cSYann Gautier 	const char *cchar;
63c9d75b3cSYann Gautier 
64c9d75b3cSYann Gautier 	cchar = fdt_get_name(fdt, node, &len);
65c9d75b3cSYann Gautier 
66c9d75b3cSYann Gautier 	return (cchar != NULL) && (len >= 0);
67c9d75b3cSYann Gautier }
68c9d75b3cSYann Gautier 
69c9d75b3cSYann Gautier /*******************************************************************************
70c9d75b3cSYann Gautier  * This function return global node status (generic use of fdt library).
71c9d75b3cSYann Gautier  ******************************************************************************/
72c9d75b3cSYann Gautier uint8_t fdt_get_status(int node)
73c9d75b3cSYann Gautier {
74c9d75b3cSYann Gautier 	uint8_t status = DT_DISABLED;
75c9d75b3cSYann Gautier 	int len;
76c9d75b3cSYann Gautier 	const char *cchar;
77c9d75b3cSYann Gautier 
78c9d75b3cSYann Gautier 	cchar = fdt_getprop(fdt, node, "status", &len);
79c9d75b3cSYann Gautier 	if ((cchar == NULL) ||
80c9d75b3cSYann Gautier 	    (strncmp(cchar, "okay", (size_t)len) == 0)) {
81c9d75b3cSYann Gautier 		status |= DT_NON_SECURE;
82c9d75b3cSYann Gautier 	}
83c9d75b3cSYann Gautier 
84c9d75b3cSYann Gautier 	cchar = fdt_getprop(fdt, node, "secure-status", &len);
85c9d75b3cSYann Gautier 	if (cchar == NULL) {
86c9d75b3cSYann Gautier 		if (status == DT_NON_SECURE) {
87c9d75b3cSYann Gautier 			status |= DT_SECURE;
88c9d75b3cSYann Gautier 		}
89c9d75b3cSYann Gautier 	} else if (strncmp(cchar, "okay", (size_t)len) == 0) {
90c9d75b3cSYann Gautier 		status |= DT_SECURE;
91c9d75b3cSYann Gautier 	}
92c9d75b3cSYann Gautier 
93c9d75b3cSYann Gautier 	return status;
94c9d75b3cSYann Gautier }
95c9d75b3cSYann Gautier 
96cd4941deSYann Gautier #if ENABLE_ASSERTIONS
97c9d75b3cSYann Gautier /*******************************************************************************
98dd85e572SLionel Debieve  * This function returns the address cells from the node parent.
99dd85e572SLionel Debieve  * Returns:
100dd85e572SLionel Debieve  * - #address-cells value if success.
101dd85e572SLionel Debieve  * - invalid value if error.
102dd85e572SLionel Debieve  * - a default value if undefined #address-cells property as per libfdt
103dd85e572SLionel Debieve  *   implementation.
104dd85e572SLionel Debieve  ******************************************************************************/
105cd4941deSYann Gautier static int fdt_get_node_parent_address_cells(int node)
106dd85e572SLionel Debieve {
107dd85e572SLionel Debieve 	int parent;
108dd85e572SLionel Debieve 
109dd85e572SLionel Debieve 	parent = fdt_parent_offset(fdt, node);
110dd85e572SLionel Debieve 	if (parent < 0) {
111dd85e572SLionel Debieve 		return -FDT_ERR_NOTFOUND;
112dd85e572SLionel Debieve 	}
113dd85e572SLionel Debieve 
114dd85e572SLionel Debieve 	return fdt_address_cells(fdt, parent);
115dd85e572SLionel Debieve }
116dd85e572SLionel Debieve 
117dd85e572SLionel Debieve /*******************************************************************************
118dd85e572SLionel Debieve  * This function returns the size cells from the node parent.
119dd85e572SLionel Debieve  * Returns:
120dd85e572SLionel Debieve  * - #size-cells value if success.
121dd85e572SLionel Debieve  * - invalid value if error.
122dd85e572SLionel Debieve  * - a default value if undefined #size-cells property as per libfdt
123dd85e572SLionel Debieve  *   implementation.
124dd85e572SLionel Debieve  ******************************************************************************/
125cd4941deSYann Gautier static int fdt_get_node_parent_size_cells(int node)
126dd85e572SLionel Debieve {
127dd85e572SLionel Debieve 	int parent;
128dd85e572SLionel Debieve 
129dd85e572SLionel Debieve 	parent = fdt_parent_offset(fdt, node);
130dd85e572SLionel Debieve 	if (parent < 0) {
131dd85e572SLionel Debieve 		return -FDT_ERR_NOTFOUND;
132dd85e572SLionel Debieve 	}
133dd85e572SLionel Debieve 
134dd85e572SLionel Debieve 	return fdt_size_cells(fdt, parent);
135dd85e572SLionel Debieve }
136cd4941deSYann Gautier #endif
137dd85e572SLionel Debieve 
138dd85e572SLionel Debieve /*******************************************************************************
139c9d75b3cSYann Gautier  * This function reads a value of a node property (generic use of fdt
140c9d75b3cSYann Gautier  * library).
141c9d75b3cSYann Gautier  * Returns value if success, and a default value if property not found.
142c9d75b3cSYann Gautier  * Default value is passed as parameter.
143c9d75b3cSYann Gautier  ******************************************************************************/
144c9d75b3cSYann Gautier uint32_t fdt_read_uint32_default(int node, const char *prop_name,
145c9d75b3cSYann Gautier 				 uint32_t dflt_value)
146c9d75b3cSYann Gautier {
147c9d75b3cSYann Gautier 	const fdt32_t *cuint;
148c9d75b3cSYann Gautier 	int lenp;
149c9d75b3cSYann Gautier 
150c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, prop_name, &lenp);
151c9d75b3cSYann Gautier 	if (cuint == NULL) {
152c9d75b3cSYann Gautier 		return dflt_value;
153c9d75b3cSYann Gautier 	}
154c9d75b3cSYann Gautier 
155c9d75b3cSYann Gautier 	return fdt32_to_cpu(*cuint);
156c9d75b3cSYann Gautier }
157c9d75b3cSYann Gautier 
158c9d75b3cSYann Gautier /*******************************************************************************
159dd85e572SLionel Debieve  * This function fills reg node info (base & size) with an index found by
160dd85e572SLionel Debieve  * checking the reg-names node.
161dd85e572SLionel Debieve  * Returns 0 on success and a negative FDT error code on failure.
162dd85e572SLionel Debieve  ******************************************************************************/
163dd85e572SLionel Debieve int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base,
164dd85e572SLionel Debieve 			      size_t *size)
165dd85e572SLionel Debieve {
166dd85e572SLionel Debieve 	const fdt32_t *cuint;
167dd85e572SLionel Debieve 	int index, len;
168dd85e572SLionel Debieve 
169dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
170dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
171dd85e572SLionel Debieve 
172dd85e572SLionel Debieve 	index = fdt_stringlist_search(fdt, node, "reg-names", name);
173dd85e572SLionel Debieve 	if (index < 0) {
174dd85e572SLionel Debieve 		return index;
175dd85e572SLionel Debieve 	}
176dd85e572SLionel Debieve 
177dd85e572SLionel Debieve 	cuint = fdt_getprop(fdt, node, "reg", &len);
178dd85e572SLionel Debieve 	if (cuint == NULL) {
179dd85e572SLionel Debieve 		return -FDT_ERR_NOTFOUND;
180dd85e572SLionel Debieve 	}
181dd85e572SLionel Debieve 
182dd85e572SLionel Debieve 	if ((index * (int)sizeof(uint32_t)) > len) {
183dd85e572SLionel Debieve 		return -FDT_ERR_BADVALUE;
184dd85e572SLionel Debieve 	}
185dd85e572SLionel Debieve 
186dd85e572SLionel Debieve 	cuint += index << 1;
187dd85e572SLionel Debieve 	if (base != NULL) {
188dd85e572SLionel Debieve 		*base = fdt32_to_cpu(*cuint);
189dd85e572SLionel Debieve 	}
190dd85e572SLionel Debieve 	cuint++;
191dd85e572SLionel Debieve 	if (size != NULL) {
192dd85e572SLionel Debieve 		*size = fdt32_to_cpu(*cuint);
193dd85e572SLionel Debieve 	}
194dd85e572SLionel Debieve 
195dd85e572SLionel Debieve 	return 0;
196dd85e572SLionel Debieve }
197dd85e572SLionel Debieve 
198dd85e572SLionel Debieve /*******************************************************************************
199f805594dSYann Gautier  * This function gets the stdout path node.
200f805594dSYann Gautier  * It reads the value indicated inside the device tree.
201f805594dSYann Gautier  * Returns node offset on success and a negative FDT error code on failure.
202f805594dSYann Gautier  ******************************************************************************/
203f805594dSYann Gautier static int dt_get_stdout_node_offset(void)
204f805594dSYann Gautier {
205f805594dSYann Gautier 	int node;
206f805594dSYann Gautier 	const char *cchar;
207f805594dSYann Gautier 
208f805594dSYann Gautier 	node = fdt_path_offset(fdt, "/secure-chosen");
209f805594dSYann Gautier 	if (node < 0) {
210f805594dSYann Gautier 		node = fdt_path_offset(fdt, "/chosen");
211f805594dSYann Gautier 		if (node < 0) {
212f805594dSYann Gautier 			return -FDT_ERR_NOTFOUND;
213f805594dSYann Gautier 		}
214f805594dSYann Gautier 	}
215f805594dSYann Gautier 
216f805594dSYann Gautier 	cchar = fdt_getprop(fdt, node, "stdout-path", NULL);
217f805594dSYann Gautier 	if (cchar == NULL) {
218f805594dSYann Gautier 		return -FDT_ERR_NOTFOUND;
219f805594dSYann Gautier 	}
220f805594dSYann Gautier 
221f805594dSYann Gautier 	node = -FDT_ERR_NOTFOUND;
222f805594dSYann Gautier 	if (strchr(cchar, (int)':') != NULL) {
223f805594dSYann Gautier 		const char *name;
224f805594dSYann Gautier 		char *str = (char *)cchar;
225f805594dSYann Gautier 		int len = 0;
226f805594dSYann Gautier 
227f805594dSYann Gautier 		while (strncmp(":", str, 1)) {
228f805594dSYann Gautier 			len++;
229f805594dSYann Gautier 			str++;
230f805594dSYann Gautier 		}
231f805594dSYann Gautier 
232f805594dSYann Gautier 		name = fdt_get_alias_namelen(fdt, cchar, len);
233f805594dSYann Gautier 
234f805594dSYann Gautier 		if (name != NULL) {
235f805594dSYann Gautier 			node = fdt_path_offset(fdt, name);
236f805594dSYann Gautier 		}
237f805594dSYann Gautier 	} else {
238f805594dSYann Gautier 		node = fdt_path_offset(fdt, cchar);
239f805594dSYann Gautier 	}
240f805594dSYann Gautier 
241f805594dSYann Gautier 	return node;
242f805594dSYann Gautier }
243f805594dSYann Gautier 
244f805594dSYann Gautier /*******************************************************************************
245c9d75b3cSYann Gautier  * This function gets the stdout pin configuration information from the DT.
246c9d75b3cSYann Gautier  * And then calls the sub-function to treat it and set GPIO registers.
247c9d75b3cSYann Gautier  * Returns 0 on success and a negative FDT error code on failure.
248c9d75b3cSYann Gautier  ******************************************************************************/
249c9d75b3cSYann Gautier int dt_set_stdout_pinctrl(void)
250c9d75b3cSYann Gautier {
251c9d75b3cSYann Gautier 	int node;
252c9d75b3cSYann Gautier 
253c9d75b3cSYann Gautier 	node = dt_get_stdout_node_offset();
254c9d75b3cSYann Gautier 	if (node < 0) {
255c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
256c9d75b3cSYann Gautier 	}
257c9d75b3cSYann Gautier 
258c9d75b3cSYann Gautier 	return dt_set_pinctrl_config(node);
259c9d75b3cSYann Gautier }
260c9d75b3cSYann Gautier 
261c9d75b3cSYann Gautier /*******************************************************************************
262c9d75b3cSYann Gautier  * This function fills the generic information from a given node.
263c9d75b3cSYann Gautier  ******************************************************************************/
264c9d75b3cSYann Gautier void dt_fill_device_info(struct dt_node_info *info, int node)
265c9d75b3cSYann Gautier {
266c9d75b3cSYann Gautier 	const fdt32_t *cuint;
267c9d75b3cSYann Gautier 
268dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
269dd85e572SLionel Debieve 
270c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
271c9d75b3cSYann Gautier 	if (cuint != NULL) {
272c9d75b3cSYann Gautier 		info->base = fdt32_to_cpu(*cuint);
273c9d75b3cSYann Gautier 	} else {
274c9d75b3cSYann Gautier 		info->base = 0;
275c9d75b3cSYann Gautier 	}
276c9d75b3cSYann Gautier 
277c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "clocks", NULL);
278c9d75b3cSYann Gautier 	if (cuint != NULL) {
279c9d75b3cSYann Gautier 		cuint++;
280c9d75b3cSYann Gautier 		info->clock = (int)fdt32_to_cpu(*cuint);
281c9d75b3cSYann Gautier 	} else {
282c9d75b3cSYann Gautier 		info->clock = -1;
283c9d75b3cSYann Gautier 	}
284c9d75b3cSYann Gautier 
285c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "resets", NULL);
286c9d75b3cSYann Gautier 	if (cuint != NULL) {
287c9d75b3cSYann Gautier 		cuint++;
288c9d75b3cSYann Gautier 		info->reset = (int)fdt32_to_cpu(*cuint);
289c9d75b3cSYann Gautier 	} else {
290c9d75b3cSYann Gautier 		info->reset = -1;
291c9d75b3cSYann Gautier 	}
292c9d75b3cSYann Gautier 
293c9d75b3cSYann Gautier 	info->status = fdt_get_status(node);
294c9d75b3cSYann Gautier }
295c9d75b3cSYann Gautier 
296c9d75b3cSYann Gautier /*******************************************************************************
297c9d75b3cSYann Gautier  * This function retrieve the generic information from DT.
298c9d75b3cSYann Gautier  * Returns node on success and a negative FDT error code on failure.
299c9d75b3cSYann Gautier  ******************************************************************************/
300c9d75b3cSYann Gautier int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
301c9d75b3cSYann Gautier {
302c9d75b3cSYann Gautier 	int node;
303c9d75b3cSYann Gautier 
304c9d75b3cSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, offset, compat);
305c9d75b3cSYann Gautier 	if (node < 0) {
306c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
307c9d75b3cSYann Gautier 	}
308c9d75b3cSYann Gautier 
309c9d75b3cSYann Gautier 	dt_fill_device_info(info, node);
310c9d75b3cSYann Gautier 
311c9d75b3cSYann Gautier 	return node;
312c9d75b3cSYann Gautier }
313c9d75b3cSYann Gautier 
314c9d75b3cSYann Gautier /*******************************************************************************
315c9d75b3cSYann Gautier  * This function gets the UART instance info of stdout from the DT.
316c9d75b3cSYann Gautier  * Returns node on success and a negative FDT error code on failure.
317c9d75b3cSYann Gautier  ******************************************************************************/
318c9d75b3cSYann Gautier int dt_get_stdout_uart_info(struct dt_node_info *info)
319c9d75b3cSYann Gautier {
320c9d75b3cSYann Gautier 	int node;
321c9d75b3cSYann Gautier 
322c9d75b3cSYann Gautier 	node = dt_get_stdout_node_offset();
323c9d75b3cSYann Gautier 	if (node < 0) {
324c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
325c9d75b3cSYann Gautier 	}
326c9d75b3cSYann Gautier 
327c9d75b3cSYann Gautier 	dt_fill_device_info(info, node);
328c9d75b3cSYann Gautier 
329c9d75b3cSYann Gautier 	return node;
330c9d75b3cSYann Gautier }
331c9d75b3cSYann Gautier 
332c9d75b3cSYann Gautier /*******************************************************************************
333c9d75b3cSYann Gautier  * This function gets DDR size information from the DT.
334c9d75b3cSYann Gautier  * Returns value in bytes on success, and 0 on failure.
335c9d75b3cSYann Gautier  ******************************************************************************/
336c9d75b3cSYann Gautier uint32_t dt_get_ddr_size(void)
337c9d75b3cSYann Gautier {
338c9d75b3cSYann Gautier 	int node;
339c9d75b3cSYann Gautier 
340c9d75b3cSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
341c9d75b3cSYann Gautier 	if (node < 0) {
342c9d75b3cSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
343c9d75b3cSYann Gautier 		return 0;
344c9d75b3cSYann Gautier 	}
345c9d75b3cSYann Gautier 
346c9d75b3cSYann Gautier 	return fdt_read_uint32_default(node, "st,mem-size", 0);
347c9d75b3cSYann Gautier }
348c9d75b3cSYann Gautier 
349c9d75b3cSYann Gautier /*******************************************************************************
3507ae58c6bSYann Gautier  * This function gets DDRCTRL base address information from the DT.
3517ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
3527ae58c6bSYann Gautier  ******************************************************************************/
3537ae58c6bSYann Gautier uintptr_t dt_get_ddrctrl_base(void)
3547ae58c6bSYann Gautier {
3557ae58c6bSYann Gautier 	int node;
3567ae58c6bSYann Gautier 	uint32_t array[4];
3577ae58c6bSYann Gautier 
3587ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
3597ae58c6bSYann Gautier 	if (node < 0) {
3607ae58c6bSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
3617ae58c6bSYann Gautier 		return 0;
3627ae58c6bSYann Gautier 	}
3637ae58c6bSYann Gautier 
364dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
365dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
366dd85e572SLionel Debieve 
367*52a616b4SAndre Przywara 	if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) {
3687ae58c6bSYann Gautier 		return 0;
3697ae58c6bSYann Gautier 	}
3707ae58c6bSYann Gautier 
3717ae58c6bSYann Gautier 	return array[0];
3727ae58c6bSYann Gautier }
3737ae58c6bSYann Gautier 
3747ae58c6bSYann Gautier /*******************************************************************************
3757ae58c6bSYann Gautier  * This function gets DDRPHYC base address information from the DT.
3767ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
3777ae58c6bSYann Gautier  ******************************************************************************/
3787ae58c6bSYann Gautier uintptr_t dt_get_ddrphyc_base(void)
3797ae58c6bSYann Gautier {
3807ae58c6bSYann Gautier 	int node;
3817ae58c6bSYann Gautier 	uint32_t array[4];
3827ae58c6bSYann Gautier 
3837ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
3847ae58c6bSYann Gautier 	if (node < 0) {
3857ae58c6bSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
3867ae58c6bSYann Gautier 		return 0;
3877ae58c6bSYann Gautier 	}
3887ae58c6bSYann Gautier 
389dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
390dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
391dd85e572SLionel Debieve 
392*52a616b4SAndre Przywara 	if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) {
3937ae58c6bSYann Gautier 		return 0;
3947ae58c6bSYann Gautier 	}
3957ae58c6bSYann Gautier 
3967ae58c6bSYann Gautier 	return array[2];
3977ae58c6bSYann Gautier }
3987ae58c6bSYann Gautier 
3997ae58c6bSYann Gautier /*******************************************************************************
4007ae58c6bSYann Gautier  * This function gets PWR base address information from the DT.
4017ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
4027ae58c6bSYann Gautier  ******************************************************************************/
4037ae58c6bSYann Gautier uintptr_t dt_get_pwr_base(void)
4047ae58c6bSYann Gautier {
4057ae58c6bSYann Gautier 	int node;
4067ae58c6bSYann Gautier 	const fdt32_t *cuint;
4077ae58c6bSYann Gautier 
4087ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT);
4097ae58c6bSYann Gautier 	if (node < 0) {
4107ae58c6bSYann Gautier 		INFO("%s: Cannot read PWR node in DT\n", __func__);
4117ae58c6bSYann Gautier 		return 0;
4127ae58c6bSYann Gautier 	}
4137ae58c6bSYann Gautier 
414dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
415dd85e572SLionel Debieve 
4167ae58c6bSYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
4177ae58c6bSYann Gautier 	if (cuint == NULL) {
4187ae58c6bSYann Gautier 		return 0;
4197ae58c6bSYann Gautier 	}
4207ae58c6bSYann Gautier 
4217ae58c6bSYann Gautier 	return fdt32_to_cpu(*cuint);
4227ae58c6bSYann Gautier }
4237ae58c6bSYann Gautier 
4247ae58c6bSYann Gautier /*******************************************************************************
425f33b2433SYann Gautier  * This function gets PWR VDD regulator voltage information from the DT.
426f33b2433SYann Gautier  * Returns value in microvolts on success, and 0 on failure.
427f33b2433SYann Gautier  ******************************************************************************/
428f33b2433SYann Gautier uint32_t dt_get_pwr_vdd_voltage(void)
429f33b2433SYann Gautier {
430f33b2433SYann Gautier 	int node, pwr_regulators_node;
431f33b2433SYann Gautier 	const fdt32_t *cuint;
432f33b2433SYann Gautier 
433f33b2433SYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT);
434f33b2433SYann Gautier 	if (node < 0) {
435f33b2433SYann Gautier 		INFO("%s: Cannot read PWR node in DT\n", __func__);
436f33b2433SYann Gautier 		return 0;
437f33b2433SYann Gautier 	}
438f33b2433SYann Gautier 
439f33b2433SYann Gautier 	pwr_regulators_node = fdt_subnode_offset(fdt, node, "pwr-regulators");
440e9d1e5afSYann Gautier 	if (pwr_regulators_node < 0) {
441f33b2433SYann Gautier 		INFO("%s: Cannot read pwr-regulators node in DT\n", __func__);
442f33b2433SYann Gautier 		return 0;
443f33b2433SYann Gautier 	}
444f33b2433SYann Gautier 
445f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, pwr_regulators_node, "vdd-supply", NULL);
446f33b2433SYann Gautier 	if (cuint == NULL) {
447f33b2433SYann Gautier 		return 0;
448f33b2433SYann Gautier 	}
449f33b2433SYann Gautier 
450f33b2433SYann Gautier 	node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
451f33b2433SYann Gautier 	if (node < 0) {
452f33b2433SYann Gautier 		return 0;
453f33b2433SYann Gautier 	}
454f33b2433SYann Gautier 
455f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
456f33b2433SYann Gautier 	if (cuint == NULL) {
457f33b2433SYann Gautier 		return 0;
458f33b2433SYann Gautier 	}
459f33b2433SYann Gautier 
460f33b2433SYann Gautier 	return fdt32_to_cpu(*cuint);
461f33b2433SYann Gautier }
462f33b2433SYann Gautier 
463f33b2433SYann Gautier /*******************************************************************************
464f33b2433SYann Gautier  * This function gets SYSCFG base address information from the DT.
465f33b2433SYann Gautier  * Returns value on success, and 0 on failure.
466f33b2433SYann Gautier  ******************************************************************************/
467f33b2433SYann Gautier uintptr_t dt_get_syscfg_base(void)
468f33b2433SYann Gautier {
469f33b2433SYann Gautier 	int node;
470f33b2433SYann Gautier 	const fdt32_t *cuint;
471f33b2433SYann Gautier 
472f33b2433SYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_SYSCFG_COMPAT);
473f33b2433SYann Gautier 	if (node < 0) {
474f33b2433SYann Gautier 		INFO("%s: Cannot read SYSCFG node in DT\n", __func__);
475f33b2433SYann Gautier 		return 0;
476f33b2433SYann Gautier 	}
477f33b2433SYann Gautier 
478dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
479dd85e572SLionel Debieve 
480f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
481f33b2433SYann Gautier 	if (cuint == NULL) {
482f33b2433SYann Gautier 		return 0;
483f33b2433SYann Gautier 	}
484f33b2433SYann Gautier 
485f33b2433SYann Gautier 	return fdt32_to_cpu(*cuint);
486f33b2433SYann Gautier }
487f33b2433SYann Gautier 
488f33b2433SYann Gautier /*******************************************************************************
489c9d75b3cSYann Gautier  * This function retrieves board model from DT
490c9d75b3cSYann Gautier  * Returns string taken from model node, NULL otherwise
491c9d75b3cSYann Gautier  ******************************************************************************/
492c9d75b3cSYann Gautier const char *dt_get_board_model(void)
493c9d75b3cSYann Gautier {
494c9d75b3cSYann Gautier 	int node = fdt_path_offset(fdt, "/");
495c9d75b3cSYann Gautier 
496c9d75b3cSYann Gautier 	if (node < 0) {
497c9d75b3cSYann Gautier 		return NULL;
498c9d75b3cSYann Gautier 	}
499c9d75b3cSYann Gautier 
500c9d75b3cSYann Gautier 	return (const char *)fdt_getprop(fdt, node, "model", NULL);
501c9d75b3cSYann Gautier }
502