xref: /rk3399_ARM-atf/plat/st/common/stm32mp_dt.c (revision be858cffa91fbcd5b8657200fbec1667c65bb1b7)
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>
1552a616b4SAndre 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 /*******************************************************************************
139dd85e572SLionel Debieve  * This function fills reg node info (base & size) with an index found by
140dd85e572SLionel Debieve  * checking the reg-names node.
141dd85e572SLionel Debieve  * Returns 0 on success and a negative FDT error code on failure.
142dd85e572SLionel Debieve  ******************************************************************************/
143dd85e572SLionel Debieve int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base,
144dd85e572SLionel Debieve 			      size_t *size)
145dd85e572SLionel Debieve {
146dd85e572SLionel Debieve 	const fdt32_t *cuint;
147dd85e572SLionel Debieve 	int index, len;
148dd85e572SLionel Debieve 
149dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
150dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
151dd85e572SLionel Debieve 
152dd85e572SLionel Debieve 	index = fdt_stringlist_search(fdt, node, "reg-names", name);
153dd85e572SLionel Debieve 	if (index < 0) {
154dd85e572SLionel Debieve 		return index;
155dd85e572SLionel Debieve 	}
156dd85e572SLionel Debieve 
157dd85e572SLionel Debieve 	cuint = fdt_getprop(fdt, node, "reg", &len);
158dd85e572SLionel Debieve 	if (cuint == NULL) {
159dd85e572SLionel Debieve 		return -FDT_ERR_NOTFOUND;
160dd85e572SLionel Debieve 	}
161dd85e572SLionel Debieve 
162dd85e572SLionel Debieve 	if ((index * (int)sizeof(uint32_t)) > len) {
163dd85e572SLionel Debieve 		return -FDT_ERR_BADVALUE;
164dd85e572SLionel Debieve 	}
165dd85e572SLionel Debieve 
166dd85e572SLionel Debieve 	cuint += index << 1;
167dd85e572SLionel Debieve 	if (base != NULL) {
168dd85e572SLionel Debieve 		*base = fdt32_to_cpu(*cuint);
169dd85e572SLionel Debieve 	}
170dd85e572SLionel Debieve 	cuint++;
171dd85e572SLionel Debieve 	if (size != NULL) {
172dd85e572SLionel Debieve 		*size = fdt32_to_cpu(*cuint);
173dd85e572SLionel Debieve 	}
174dd85e572SLionel Debieve 
175dd85e572SLionel Debieve 	return 0;
176dd85e572SLionel Debieve }
177dd85e572SLionel Debieve 
178dd85e572SLionel Debieve /*******************************************************************************
179f805594dSYann Gautier  * This function gets the stdout path node.
180f805594dSYann Gautier  * It reads the value indicated inside the device tree.
181f805594dSYann Gautier  * Returns node offset on success and a negative FDT error code on failure.
182f805594dSYann Gautier  ******************************************************************************/
183f805594dSYann Gautier static int dt_get_stdout_node_offset(void)
184f805594dSYann Gautier {
185f805594dSYann Gautier 	int node;
186f805594dSYann Gautier 	const char *cchar;
187f805594dSYann Gautier 
188f805594dSYann Gautier 	node = fdt_path_offset(fdt, "/secure-chosen");
189f805594dSYann Gautier 	if (node < 0) {
190f805594dSYann Gautier 		node = fdt_path_offset(fdt, "/chosen");
191f805594dSYann Gautier 		if (node < 0) {
192f805594dSYann Gautier 			return -FDT_ERR_NOTFOUND;
193f805594dSYann Gautier 		}
194f805594dSYann Gautier 	}
195f805594dSYann Gautier 
196f805594dSYann Gautier 	cchar = fdt_getprop(fdt, node, "stdout-path", NULL);
197f805594dSYann Gautier 	if (cchar == NULL) {
198f805594dSYann Gautier 		return -FDT_ERR_NOTFOUND;
199f805594dSYann Gautier 	}
200f805594dSYann Gautier 
201f805594dSYann Gautier 	node = -FDT_ERR_NOTFOUND;
202f805594dSYann Gautier 	if (strchr(cchar, (int)':') != NULL) {
203f805594dSYann Gautier 		const char *name;
204f805594dSYann Gautier 		char *str = (char *)cchar;
205f805594dSYann Gautier 		int len = 0;
206f805594dSYann Gautier 
207f805594dSYann Gautier 		while (strncmp(":", str, 1)) {
208f805594dSYann Gautier 			len++;
209f805594dSYann Gautier 			str++;
210f805594dSYann Gautier 		}
211f805594dSYann Gautier 
212f805594dSYann Gautier 		name = fdt_get_alias_namelen(fdt, cchar, len);
213f805594dSYann Gautier 
214f805594dSYann Gautier 		if (name != NULL) {
215f805594dSYann Gautier 			node = fdt_path_offset(fdt, name);
216f805594dSYann Gautier 		}
217f805594dSYann Gautier 	} else {
218f805594dSYann Gautier 		node = fdt_path_offset(fdt, cchar);
219f805594dSYann Gautier 	}
220f805594dSYann Gautier 
221f805594dSYann Gautier 	return node;
222f805594dSYann Gautier }
223f805594dSYann Gautier 
224f805594dSYann Gautier /*******************************************************************************
225c9d75b3cSYann Gautier  * This function gets the stdout pin configuration information from the DT.
226c9d75b3cSYann Gautier  * And then calls the sub-function to treat it and set GPIO registers.
227c9d75b3cSYann Gautier  * Returns 0 on success and a negative FDT error code on failure.
228c9d75b3cSYann Gautier  ******************************************************************************/
229c9d75b3cSYann Gautier int dt_set_stdout_pinctrl(void)
230c9d75b3cSYann Gautier {
231c9d75b3cSYann Gautier 	int node;
232c9d75b3cSYann Gautier 
233c9d75b3cSYann Gautier 	node = dt_get_stdout_node_offset();
234c9d75b3cSYann Gautier 	if (node < 0) {
235c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
236c9d75b3cSYann Gautier 	}
237c9d75b3cSYann Gautier 
238c9d75b3cSYann Gautier 	return dt_set_pinctrl_config(node);
239c9d75b3cSYann Gautier }
240c9d75b3cSYann Gautier 
241c9d75b3cSYann Gautier /*******************************************************************************
242c9d75b3cSYann Gautier  * This function fills the generic information from a given node.
243c9d75b3cSYann Gautier  ******************************************************************************/
244c9d75b3cSYann Gautier void dt_fill_device_info(struct dt_node_info *info, int node)
245c9d75b3cSYann Gautier {
246c9d75b3cSYann Gautier 	const fdt32_t *cuint;
247c9d75b3cSYann Gautier 
248dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
249dd85e572SLionel Debieve 
250c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
251c9d75b3cSYann Gautier 	if (cuint != NULL) {
252c9d75b3cSYann Gautier 		info->base = fdt32_to_cpu(*cuint);
253c9d75b3cSYann Gautier 	} else {
254c9d75b3cSYann Gautier 		info->base = 0;
255c9d75b3cSYann Gautier 	}
256c9d75b3cSYann Gautier 
257c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "clocks", NULL);
258c9d75b3cSYann Gautier 	if (cuint != NULL) {
259c9d75b3cSYann Gautier 		cuint++;
260c9d75b3cSYann Gautier 		info->clock = (int)fdt32_to_cpu(*cuint);
261c9d75b3cSYann Gautier 	} else {
262c9d75b3cSYann Gautier 		info->clock = -1;
263c9d75b3cSYann Gautier 	}
264c9d75b3cSYann Gautier 
265c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "resets", NULL);
266c9d75b3cSYann Gautier 	if (cuint != NULL) {
267c9d75b3cSYann Gautier 		cuint++;
268c9d75b3cSYann Gautier 		info->reset = (int)fdt32_to_cpu(*cuint);
269c9d75b3cSYann Gautier 	} else {
270c9d75b3cSYann Gautier 		info->reset = -1;
271c9d75b3cSYann Gautier 	}
272c9d75b3cSYann Gautier 
273c9d75b3cSYann Gautier 	info->status = fdt_get_status(node);
274c9d75b3cSYann Gautier }
275c9d75b3cSYann Gautier 
276c9d75b3cSYann Gautier /*******************************************************************************
277c9d75b3cSYann Gautier  * This function retrieve the generic information from DT.
278c9d75b3cSYann Gautier  * Returns node on success and a negative FDT error code on failure.
279c9d75b3cSYann Gautier  ******************************************************************************/
280c9d75b3cSYann Gautier int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
281c9d75b3cSYann Gautier {
282c9d75b3cSYann Gautier 	int node;
283c9d75b3cSYann Gautier 
284c9d75b3cSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, offset, compat);
285c9d75b3cSYann Gautier 	if (node < 0) {
286c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
287c9d75b3cSYann Gautier 	}
288c9d75b3cSYann Gautier 
289c9d75b3cSYann Gautier 	dt_fill_device_info(info, node);
290c9d75b3cSYann Gautier 
291c9d75b3cSYann Gautier 	return node;
292c9d75b3cSYann Gautier }
293c9d75b3cSYann Gautier 
294c9d75b3cSYann Gautier /*******************************************************************************
295c9d75b3cSYann Gautier  * This function gets the UART instance info of stdout from the DT.
296c9d75b3cSYann Gautier  * Returns node on success and a negative FDT error code on failure.
297c9d75b3cSYann Gautier  ******************************************************************************/
298c9d75b3cSYann Gautier int dt_get_stdout_uart_info(struct dt_node_info *info)
299c9d75b3cSYann Gautier {
300c9d75b3cSYann Gautier 	int node;
301c9d75b3cSYann Gautier 
302c9d75b3cSYann Gautier 	node = dt_get_stdout_node_offset();
303c9d75b3cSYann Gautier 	if (node < 0) {
304c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
305c9d75b3cSYann Gautier 	}
306c9d75b3cSYann Gautier 
307c9d75b3cSYann Gautier 	dt_fill_device_info(info, node);
308c9d75b3cSYann Gautier 
309c9d75b3cSYann Gautier 	return node;
310c9d75b3cSYann Gautier }
311c9d75b3cSYann Gautier 
312c9d75b3cSYann Gautier /*******************************************************************************
313c9d75b3cSYann Gautier  * This function gets DDR size information from the DT.
314c9d75b3cSYann Gautier  * Returns value in bytes on success, and 0 on failure.
315c9d75b3cSYann Gautier  ******************************************************************************/
316c9d75b3cSYann Gautier uint32_t dt_get_ddr_size(void)
317c9d75b3cSYann Gautier {
318c9d75b3cSYann Gautier 	int node;
319c9d75b3cSYann Gautier 
320c9d75b3cSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
321c9d75b3cSYann Gautier 	if (node < 0) {
322c9d75b3cSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
323c9d75b3cSYann Gautier 		return 0;
324c9d75b3cSYann Gautier 	}
325c9d75b3cSYann Gautier 
326*be858cffSAndre Przywara 	return fdt_read_uint32_default(fdt, node, "st,mem-size", 0);
327c9d75b3cSYann Gautier }
328c9d75b3cSYann Gautier 
329c9d75b3cSYann Gautier /*******************************************************************************
3307ae58c6bSYann Gautier  * This function gets DDRCTRL base address information from the DT.
3317ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
3327ae58c6bSYann Gautier  ******************************************************************************/
3337ae58c6bSYann Gautier uintptr_t dt_get_ddrctrl_base(void)
3347ae58c6bSYann Gautier {
3357ae58c6bSYann Gautier 	int node;
3367ae58c6bSYann Gautier 	uint32_t array[4];
3377ae58c6bSYann Gautier 
3387ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
3397ae58c6bSYann Gautier 	if (node < 0) {
3407ae58c6bSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
3417ae58c6bSYann Gautier 		return 0;
3427ae58c6bSYann Gautier 	}
3437ae58c6bSYann Gautier 
344dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
345dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
346dd85e572SLionel Debieve 
34752a616b4SAndre Przywara 	if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) {
3487ae58c6bSYann Gautier 		return 0;
3497ae58c6bSYann Gautier 	}
3507ae58c6bSYann Gautier 
3517ae58c6bSYann Gautier 	return array[0];
3527ae58c6bSYann Gautier }
3537ae58c6bSYann Gautier 
3547ae58c6bSYann Gautier /*******************************************************************************
3557ae58c6bSYann Gautier  * This function gets DDRPHYC base address information from the DT.
3567ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
3577ae58c6bSYann Gautier  ******************************************************************************/
3587ae58c6bSYann Gautier uintptr_t dt_get_ddrphyc_base(void)
3597ae58c6bSYann Gautier {
3607ae58c6bSYann Gautier 	int node;
3617ae58c6bSYann Gautier 	uint32_t array[4];
3627ae58c6bSYann Gautier 
3637ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
3647ae58c6bSYann Gautier 	if (node < 0) {
3657ae58c6bSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
3667ae58c6bSYann Gautier 		return 0;
3677ae58c6bSYann Gautier 	}
3687ae58c6bSYann Gautier 
369dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
370dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
371dd85e572SLionel Debieve 
37252a616b4SAndre Przywara 	if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) {
3737ae58c6bSYann Gautier 		return 0;
3747ae58c6bSYann Gautier 	}
3757ae58c6bSYann Gautier 
3767ae58c6bSYann Gautier 	return array[2];
3777ae58c6bSYann Gautier }
3787ae58c6bSYann Gautier 
3797ae58c6bSYann Gautier /*******************************************************************************
3807ae58c6bSYann Gautier  * This function gets PWR base address information from the DT.
3817ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
3827ae58c6bSYann Gautier  ******************************************************************************/
3837ae58c6bSYann Gautier uintptr_t dt_get_pwr_base(void)
3847ae58c6bSYann Gautier {
3857ae58c6bSYann Gautier 	int node;
3867ae58c6bSYann Gautier 	const fdt32_t *cuint;
3877ae58c6bSYann Gautier 
3887ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT);
3897ae58c6bSYann Gautier 	if (node < 0) {
3907ae58c6bSYann Gautier 		INFO("%s: Cannot read PWR node in DT\n", __func__);
3917ae58c6bSYann Gautier 		return 0;
3927ae58c6bSYann Gautier 	}
3937ae58c6bSYann Gautier 
394dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
395dd85e572SLionel Debieve 
3967ae58c6bSYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
3977ae58c6bSYann Gautier 	if (cuint == NULL) {
3987ae58c6bSYann Gautier 		return 0;
3997ae58c6bSYann Gautier 	}
4007ae58c6bSYann Gautier 
4017ae58c6bSYann Gautier 	return fdt32_to_cpu(*cuint);
4027ae58c6bSYann Gautier }
4037ae58c6bSYann Gautier 
4047ae58c6bSYann Gautier /*******************************************************************************
405f33b2433SYann Gautier  * This function gets PWR VDD regulator voltage information from the DT.
406f33b2433SYann Gautier  * Returns value in microvolts on success, and 0 on failure.
407f33b2433SYann Gautier  ******************************************************************************/
408f33b2433SYann Gautier uint32_t dt_get_pwr_vdd_voltage(void)
409f33b2433SYann Gautier {
410f33b2433SYann Gautier 	int node, pwr_regulators_node;
411f33b2433SYann Gautier 	const fdt32_t *cuint;
412f33b2433SYann Gautier 
413f33b2433SYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT);
414f33b2433SYann Gautier 	if (node < 0) {
415f33b2433SYann Gautier 		INFO("%s: Cannot read PWR node in DT\n", __func__);
416f33b2433SYann Gautier 		return 0;
417f33b2433SYann Gautier 	}
418f33b2433SYann Gautier 
419f33b2433SYann Gautier 	pwr_regulators_node = fdt_subnode_offset(fdt, node, "pwr-regulators");
420e9d1e5afSYann Gautier 	if (pwr_regulators_node < 0) {
421f33b2433SYann Gautier 		INFO("%s: Cannot read pwr-regulators node in DT\n", __func__);
422f33b2433SYann Gautier 		return 0;
423f33b2433SYann Gautier 	}
424f33b2433SYann Gautier 
425f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, pwr_regulators_node, "vdd-supply", NULL);
426f33b2433SYann Gautier 	if (cuint == NULL) {
427f33b2433SYann Gautier 		return 0;
428f33b2433SYann Gautier 	}
429f33b2433SYann Gautier 
430f33b2433SYann Gautier 	node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
431f33b2433SYann Gautier 	if (node < 0) {
432f33b2433SYann Gautier 		return 0;
433f33b2433SYann Gautier 	}
434f33b2433SYann Gautier 
435f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
436f33b2433SYann Gautier 	if (cuint == NULL) {
437f33b2433SYann Gautier 		return 0;
438f33b2433SYann Gautier 	}
439f33b2433SYann Gautier 
440f33b2433SYann Gautier 	return fdt32_to_cpu(*cuint);
441f33b2433SYann Gautier }
442f33b2433SYann Gautier 
443f33b2433SYann Gautier /*******************************************************************************
444f33b2433SYann Gautier  * This function gets SYSCFG base address information from the DT.
445f33b2433SYann Gautier  * Returns value on success, and 0 on failure.
446f33b2433SYann Gautier  ******************************************************************************/
447f33b2433SYann Gautier uintptr_t dt_get_syscfg_base(void)
448f33b2433SYann Gautier {
449f33b2433SYann Gautier 	int node;
450f33b2433SYann Gautier 	const fdt32_t *cuint;
451f33b2433SYann Gautier 
452f33b2433SYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_SYSCFG_COMPAT);
453f33b2433SYann Gautier 	if (node < 0) {
454f33b2433SYann Gautier 		INFO("%s: Cannot read SYSCFG node in DT\n", __func__);
455f33b2433SYann Gautier 		return 0;
456f33b2433SYann Gautier 	}
457f33b2433SYann Gautier 
458dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
459dd85e572SLionel Debieve 
460f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
461f33b2433SYann Gautier 	if (cuint == NULL) {
462f33b2433SYann Gautier 		return 0;
463f33b2433SYann Gautier 	}
464f33b2433SYann Gautier 
465f33b2433SYann Gautier 	return fdt32_to_cpu(*cuint);
466f33b2433SYann Gautier }
467f33b2433SYann Gautier 
468f33b2433SYann Gautier /*******************************************************************************
469c9d75b3cSYann Gautier  * This function retrieves board model from DT
470c9d75b3cSYann Gautier  * Returns string taken from model node, NULL otherwise
471c9d75b3cSYann Gautier  ******************************************************************************/
472c9d75b3cSYann Gautier const char *dt_get_board_model(void)
473c9d75b3cSYann Gautier {
474c9d75b3cSYann Gautier 	int node = fdt_path_offset(fdt, "/");
475c9d75b3cSYann Gautier 
476c9d75b3cSYann Gautier 	if (node < 0) {
477c9d75b3cSYann Gautier 		return NULL;
478c9d75b3cSYann Gautier 	}
479c9d75b3cSYann Gautier 
480c9d75b3cSYann Gautier 	return (const char *)fdt_getprop(fdt, node, "model", NULL);
481c9d75b3cSYann Gautier }
482