xref: /rk3399_ARM-atf/plat/st/common/stm32mp_dt.c (revision e9d1e5afbd0d95ffc0f8da0eafe5edbb84c30943)
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>
15c9d75b3cSYann Gautier #include <drivers/st/stm32_gpio.h>
16c9d75b3cSYann Gautier #include <drivers/st/stm32mp1_ddr.h>
17c9d75b3cSYann Gautier #include <drivers/st/stm32mp1_ram.h>
18c9d75b3cSYann Gautier 
19c9d75b3cSYann Gautier #include <stm32mp_dt.h>
20c9d75b3cSYann Gautier 
21c9d75b3cSYann Gautier static int fdt_checked;
22c9d75b3cSYann Gautier 
233f9c9784SYann Gautier static void *fdt = (void *)(uintptr_t)STM32MP_DTB_BASE;
24c9d75b3cSYann Gautier 
25c9d75b3cSYann Gautier /*******************************************************************************
26c9d75b3cSYann Gautier  * This function checks device tree file with its header.
27c9d75b3cSYann Gautier  * Returns 0 on success and a negative FDT error code on failure.
28c9d75b3cSYann Gautier  ******************************************************************************/
29c9d75b3cSYann Gautier int dt_open_and_check(void)
30c9d75b3cSYann Gautier {
31c9d75b3cSYann Gautier 	int ret = fdt_check_header(fdt);
32c9d75b3cSYann Gautier 
33c9d75b3cSYann Gautier 	if (ret == 0) {
34c9d75b3cSYann Gautier 		fdt_checked = 1;
35c9d75b3cSYann Gautier 	}
36c9d75b3cSYann Gautier 
37c9d75b3cSYann Gautier 	return ret;
38c9d75b3cSYann Gautier }
39c9d75b3cSYann Gautier 
40c9d75b3cSYann Gautier /*******************************************************************************
41c9d75b3cSYann Gautier  * This function gets the address of the DT.
42c9d75b3cSYann Gautier  * If DT is OK, fdt_addr is filled with DT address.
43c9d75b3cSYann Gautier  * Returns 1 if success, 0 otherwise.
44c9d75b3cSYann Gautier  ******************************************************************************/
45c9d75b3cSYann Gautier int fdt_get_address(void **fdt_addr)
46c9d75b3cSYann Gautier {
47c9d75b3cSYann Gautier 	if (fdt_checked == 1) {
48c9d75b3cSYann Gautier 		*fdt_addr = fdt;
49c9d75b3cSYann Gautier 	}
50c9d75b3cSYann Gautier 
51c9d75b3cSYann Gautier 	return fdt_checked;
52c9d75b3cSYann Gautier }
53c9d75b3cSYann Gautier 
54c9d75b3cSYann Gautier /*******************************************************************************
55c9d75b3cSYann Gautier  * This function check the presence of a node (generic use of fdt library).
56c9d75b3cSYann Gautier  * Returns true if present, else return false.
57c9d75b3cSYann Gautier  ******************************************************************************/
58c9d75b3cSYann Gautier bool fdt_check_node(int node)
59c9d75b3cSYann Gautier {
60c9d75b3cSYann Gautier 	int len;
61c9d75b3cSYann Gautier 	const char *cchar;
62c9d75b3cSYann Gautier 
63c9d75b3cSYann Gautier 	cchar = fdt_get_name(fdt, node, &len);
64c9d75b3cSYann Gautier 
65c9d75b3cSYann Gautier 	return (cchar != NULL) && (len >= 0);
66c9d75b3cSYann Gautier }
67c9d75b3cSYann Gautier 
68c9d75b3cSYann Gautier /*******************************************************************************
69c9d75b3cSYann Gautier  * This function return global node status (generic use of fdt library).
70c9d75b3cSYann Gautier  ******************************************************************************/
71c9d75b3cSYann Gautier uint8_t fdt_get_status(int node)
72c9d75b3cSYann Gautier {
73c9d75b3cSYann Gautier 	uint8_t status = DT_DISABLED;
74c9d75b3cSYann Gautier 	int len;
75c9d75b3cSYann Gautier 	const char *cchar;
76c9d75b3cSYann Gautier 
77c9d75b3cSYann Gautier 	cchar = fdt_getprop(fdt, node, "status", &len);
78c9d75b3cSYann Gautier 	if ((cchar == NULL) ||
79c9d75b3cSYann Gautier 	    (strncmp(cchar, "okay", (size_t)len) == 0)) {
80c9d75b3cSYann Gautier 		status |= DT_NON_SECURE;
81c9d75b3cSYann Gautier 	}
82c9d75b3cSYann Gautier 
83c9d75b3cSYann Gautier 	cchar = fdt_getprop(fdt, node, "secure-status", &len);
84c9d75b3cSYann Gautier 	if (cchar == NULL) {
85c9d75b3cSYann Gautier 		if (status == DT_NON_SECURE) {
86c9d75b3cSYann Gautier 			status |= DT_SECURE;
87c9d75b3cSYann Gautier 		}
88c9d75b3cSYann Gautier 	} else if (strncmp(cchar, "okay", (size_t)len) == 0) {
89c9d75b3cSYann Gautier 		status |= DT_SECURE;
90c9d75b3cSYann Gautier 	}
91c9d75b3cSYann Gautier 
92c9d75b3cSYann Gautier 	return status;
93c9d75b3cSYann Gautier }
94c9d75b3cSYann Gautier 
95cd4941deSYann Gautier #if ENABLE_ASSERTIONS
96c9d75b3cSYann Gautier /*******************************************************************************
97dd85e572SLionel Debieve  * This function returns the address cells from the node parent.
98dd85e572SLionel Debieve  * Returns:
99dd85e572SLionel Debieve  * - #address-cells value if success.
100dd85e572SLionel Debieve  * - invalid value if error.
101dd85e572SLionel Debieve  * - a default value if undefined #address-cells property as per libfdt
102dd85e572SLionel Debieve  *   implementation.
103dd85e572SLionel Debieve  ******************************************************************************/
104cd4941deSYann Gautier static int fdt_get_node_parent_address_cells(int node)
105dd85e572SLionel Debieve {
106dd85e572SLionel Debieve 	int parent;
107dd85e572SLionel Debieve 
108dd85e572SLionel Debieve 	parent = fdt_parent_offset(fdt, node);
109dd85e572SLionel Debieve 	if (parent < 0) {
110dd85e572SLionel Debieve 		return -FDT_ERR_NOTFOUND;
111dd85e572SLionel Debieve 	}
112dd85e572SLionel Debieve 
113dd85e572SLionel Debieve 	return fdt_address_cells(fdt, parent);
114dd85e572SLionel Debieve }
115dd85e572SLionel Debieve 
116dd85e572SLionel Debieve /*******************************************************************************
117dd85e572SLionel Debieve  * This function returns the size cells from the node parent.
118dd85e572SLionel Debieve  * Returns:
119dd85e572SLionel Debieve  * - #size-cells value if success.
120dd85e572SLionel Debieve  * - invalid value if error.
121dd85e572SLionel Debieve  * - a default value if undefined #size-cells property as per libfdt
122dd85e572SLionel Debieve  *   implementation.
123dd85e572SLionel Debieve  ******************************************************************************/
124cd4941deSYann Gautier static int fdt_get_node_parent_size_cells(int node)
125dd85e572SLionel Debieve {
126dd85e572SLionel Debieve 	int parent;
127dd85e572SLionel Debieve 
128dd85e572SLionel Debieve 	parent = fdt_parent_offset(fdt, node);
129dd85e572SLionel Debieve 	if (parent < 0) {
130dd85e572SLionel Debieve 		return -FDT_ERR_NOTFOUND;
131dd85e572SLionel Debieve 	}
132dd85e572SLionel Debieve 
133dd85e572SLionel Debieve 	return fdt_size_cells(fdt, parent);
134dd85e572SLionel Debieve }
135cd4941deSYann Gautier #endif
136dd85e572SLionel Debieve 
137dd85e572SLionel Debieve /*******************************************************************************
138c9d75b3cSYann Gautier  * This function reads a value of a node property (generic use of fdt
139c9d75b3cSYann Gautier  * library).
140c9d75b3cSYann Gautier  * Returns value if success, and a default value if property not found.
141c9d75b3cSYann Gautier  * Default value is passed as parameter.
142c9d75b3cSYann Gautier  ******************************************************************************/
143c9d75b3cSYann Gautier uint32_t fdt_read_uint32_default(int node, const char *prop_name,
144c9d75b3cSYann Gautier 				 uint32_t dflt_value)
145c9d75b3cSYann Gautier {
146c9d75b3cSYann Gautier 	const fdt32_t *cuint;
147c9d75b3cSYann Gautier 	int lenp;
148c9d75b3cSYann Gautier 
149c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, prop_name, &lenp);
150c9d75b3cSYann Gautier 	if (cuint == NULL) {
151c9d75b3cSYann Gautier 		return dflt_value;
152c9d75b3cSYann Gautier 	}
153c9d75b3cSYann Gautier 
154c9d75b3cSYann Gautier 	return fdt32_to_cpu(*cuint);
155c9d75b3cSYann Gautier }
156c9d75b3cSYann Gautier 
157c9d75b3cSYann Gautier /*******************************************************************************
158c9d75b3cSYann Gautier  * This function reads a series of parameters in a node property
159c9d75b3cSYann Gautier  * (generic use of fdt library).
160c9d75b3cSYann Gautier  * It reads the values inside the device tree, from property name and node.
161c9d75b3cSYann Gautier  * The number of parameters is also indicated as entry parameter.
162c9d75b3cSYann Gautier  * Returns 0 on success and a negative FDT error code on failure.
163c9d75b3cSYann Gautier  * If success, values are stored at the third parameter address.
164c9d75b3cSYann Gautier  ******************************************************************************/
165c9d75b3cSYann Gautier int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
166c9d75b3cSYann Gautier 			  uint32_t count)
167c9d75b3cSYann Gautier {
168c9d75b3cSYann Gautier 	const fdt32_t *cuint;
169c9d75b3cSYann Gautier 	int len;
170c9d75b3cSYann Gautier 	uint32_t i;
171c9d75b3cSYann Gautier 
172c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, prop_name, &len);
173c9d75b3cSYann Gautier 	if (cuint == NULL) {
174c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
175c9d75b3cSYann Gautier 	}
176c9d75b3cSYann Gautier 
177c9d75b3cSYann Gautier 	if ((uint32_t)len != (count * sizeof(uint32_t))) {
178c9d75b3cSYann Gautier 		return -FDT_ERR_BADLAYOUT;
179c9d75b3cSYann Gautier 	}
180c9d75b3cSYann Gautier 
181c9d75b3cSYann Gautier 	for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
182c9d75b3cSYann Gautier 		*array = fdt32_to_cpu(*cuint);
183c9d75b3cSYann Gautier 		array++;
184c9d75b3cSYann Gautier 		cuint++;
185c9d75b3cSYann Gautier 	}
186c9d75b3cSYann Gautier 
187c9d75b3cSYann Gautier 	return 0;
188c9d75b3cSYann Gautier }
189c9d75b3cSYann Gautier 
190c9d75b3cSYann Gautier /*******************************************************************************
191dd85e572SLionel Debieve  * This function fills reg node info (base & size) with an index found by
192dd85e572SLionel Debieve  * checking the reg-names node.
193dd85e572SLionel Debieve  * Returns 0 on success and a negative FDT error code on failure.
194dd85e572SLionel Debieve  ******************************************************************************/
195dd85e572SLionel Debieve int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base,
196dd85e572SLionel Debieve 			      size_t *size)
197dd85e572SLionel Debieve {
198dd85e572SLionel Debieve 	const fdt32_t *cuint;
199dd85e572SLionel Debieve 	int index, len;
200dd85e572SLionel Debieve 
201dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
202dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
203dd85e572SLionel Debieve 
204dd85e572SLionel Debieve 	index = fdt_stringlist_search(fdt, node, "reg-names", name);
205dd85e572SLionel Debieve 	if (index < 0) {
206dd85e572SLionel Debieve 		return index;
207dd85e572SLionel Debieve 	}
208dd85e572SLionel Debieve 
209dd85e572SLionel Debieve 	cuint = fdt_getprop(fdt, node, "reg", &len);
210dd85e572SLionel Debieve 	if (cuint == NULL) {
211dd85e572SLionel Debieve 		return -FDT_ERR_NOTFOUND;
212dd85e572SLionel Debieve 	}
213dd85e572SLionel Debieve 
214dd85e572SLionel Debieve 	if ((index * (int)sizeof(uint32_t)) > len) {
215dd85e572SLionel Debieve 		return -FDT_ERR_BADVALUE;
216dd85e572SLionel Debieve 	}
217dd85e572SLionel Debieve 
218dd85e572SLionel Debieve 	cuint += index << 1;
219dd85e572SLionel Debieve 	if (base != NULL) {
220dd85e572SLionel Debieve 		*base = fdt32_to_cpu(*cuint);
221dd85e572SLionel Debieve 	}
222dd85e572SLionel Debieve 	cuint++;
223dd85e572SLionel Debieve 	if (size != NULL) {
224dd85e572SLionel Debieve 		*size = fdt32_to_cpu(*cuint);
225dd85e572SLionel Debieve 	}
226dd85e572SLionel Debieve 
227dd85e572SLionel Debieve 	return 0;
228dd85e572SLionel Debieve }
229dd85e572SLionel Debieve 
230dd85e572SLionel Debieve /*******************************************************************************
231f805594dSYann Gautier  * This function gets the stdout path node.
232f805594dSYann Gautier  * It reads the value indicated inside the device tree.
233f805594dSYann Gautier  * Returns node offset on success and a negative FDT error code on failure.
234f805594dSYann Gautier  ******************************************************************************/
235f805594dSYann Gautier static int dt_get_stdout_node_offset(void)
236f805594dSYann Gautier {
237f805594dSYann Gautier 	int node;
238f805594dSYann Gautier 	const char *cchar;
239f805594dSYann Gautier 
240f805594dSYann Gautier 	node = fdt_path_offset(fdt, "/secure-chosen");
241f805594dSYann Gautier 	if (node < 0) {
242f805594dSYann Gautier 		node = fdt_path_offset(fdt, "/chosen");
243f805594dSYann Gautier 		if (node < 0) {
244f805594dSYann Gautier 			return -FDT_ERR_NOTFOUND;
245f805594dSYann Gautier 		}
246f805594dSYann Gautier 	}
247f805594dSYann Gautier 
248f805594dSYann Gautier 	cchar = fdt_getprop(fdt, node, "stdout-path", NULL);
249f805594dSYann Gautier 	if (cchar == NULL) {
250f805594dSYann Gautier 		return -FDT_ERR_NOTFOUND;
251f805594dSYann Gautier 	}
252f805594dSYann Gautier 
253f805594dSYann Gautier 	node = -FDT_ERR_NOTFOUND;
254f805594dSYann Gautier 	if (strchr(cchar, (int)':') != NULL) {
255f805594dSYann Gautier 		const char *name;
256f805594dSYann Gautier 		char *str = (char *)cchar;
257f805594dSYann Gautier 		int len = 0;
258f805594dSYann Gautier 
259f805594dSYann Gautier 		while (strncmp(":", str, 1)) {
260f805594dSYann Gautier 			len++;
261f805594dSYann Gautier 			str++;
262f805594dSYann Gautier 		}
263f805594dSYann Gautier 
264f805594dSYann Gautier 		name = fdt_get_alias_namelen(fdt, cchar, len);
265f805594dSYann Gautier 
266f805594dSYann Gautier 		if (name != NULL) {
267f805594dSYann Gautier 			node = fdt_path_offset(fdt, name);
268f805594dSYann Gautier 		}
269f805594dSYann Gautier 	} else {
270f805594dSYann Gautier 		node = fdt_path_offset(fdt, cchar);
271f805594dSYann Gautier 	}
272f805594dSYann Gautier 
273f805594dSYann Gautier 	return node;
274f805594dSYann Gautier }
275f805594dSYann Gautier 
276f805594dSYann Gautier /*******************************************************************************
277c9d75b3cSYann Gautier  * This function gets the stdout pin configuration information from the DT.
278c9d75b3cSYann Gautier  * And then calls the sub-function to treat it and set GPIO registers.
279c9d75b3cSYann Gautier  * Returns 0 on success and a negative FDT error code on failure.
280c9d75b3cSYann Gautier  ******************************************************************************/
281c9d75b3cSYann Gautier int dt_set_stdout_pinctrl(void)
282c9d75b3cSYann Gautier {
283c9d75b3cSYann Gautier 	int node;
284c9d75b3cSYann Gautier 
285c9d75b3cSYann Gautier 	node = dt_get_stdout_node_offset();
286c9d75b3cSYann Gautier 	if (node < 0) {
287c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
288c9d75b3cSYann Gautier 	}
289c9d75b3cSYann Gautier 
290c9d75b3cSYann Gautier 	return dt_set_pinctrl_config(node);
291c9d75b3cSYann Gautier }
292c9d75b3cSYann Gautier 
293c9d75b3cSYann Gautier /*******************************************************************************
294c9d75b3cSYann Gautier  * This function fills the generic information from a given node.
295c9d75b3cSYann Gautier  ******************************************************************************/
296c9d75b3cSYann Gautier void dt_fill_device_info(struct dt_node_info *info, int node)
297c9d75b3cSYann Gautier {
298c9d75b3cSYann Gautier 	const fdt32_t *cuint;
299c9d75b3cSYann Gautier 
300dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
301dd85e572SLionel Debieve 
302c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
303c9d75b3cSYann Gautier 	if (cuint != NULL) {
304c9d75b3cSYann Gautier 		info->base = fdt32_to_cpu(*cuint);
305c9d75b3cSYann Gautier 	} else {
306c9d75b3cSYann Gautier 		info->base = 0;
307c9d75b3cSYann Gautier 	}
308c9d75b3cSYann Gautier 
309c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "clocks", NULL);
310c9d75b3cSYann Gautier 	if (cuint != NULL) {
311c9d75b3cSYann Gautier 		cuint++;
312c9d75b3cSYann Gautier 		info->clock = (int)fdt32_to_cpu(*cuint);
313c9d75b3cSYann Gautier 	} else {
314c9d75b3cSYann Gautier 		info->clock = -1;
315c9d75b3cSYann Gautier 	}
316c9d75b3cSYann Gautier 
317c9d75b3cSYann Gautier 	cuint = fdt_getprop(fdt, node, "resets", NULL);
318c9d75b3cSYann Gautier 	if (cuint != NULL) {
319c9d75b3cSYann Gautier 		cuint++;
320c9d75b3cSYann Gautier 		info->reset = (int)fdt32_to_cpu(*cuint);
321c9d75b3cSYann Gautier 	} else {
322c9d75b3cSYann Gautier 		info->reset = -1;
323c9d75b3cSYann Gautier 	}
324c9d75b3cSYann Gautier 
325c9d75b3cSYann Gautier 	info->status = fdt_get_status(node);
326c9d75b3cSYann Gautier }
327c9d75b3cSYann Gautier 
328c9d75b3cSYann Gautier /*******************************************************************************
329c9d75b3cSYann Gautier  * This function retrieve the generic information from DT.
330c9d75b3cSYann Gautier  * Returns node on success and a negative FDT error code on failure.
331c9d75b3cSYann Gautier  ******************************************************************************/
332c9d75b3cSYann Gautier int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
333c9d75b3cSYann Gautier {
334c9d75b3cSYann Gautier 	int node;
335c9d75b3cSYann Gautier 
336c9d75b3cSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, offset, compat);
337c9d75b3cSYann Gautier 	if (node < 0) {
338c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
339c9d75b3cSYann Gautier 	}
340c9d75b3cSYann Gautier 
341c9d75b3cSYann Gautier 	dt_fill_device_info(info, node);
342c9d75b3cSYann Gautier 
343c9d75b3cSYann Gautier 	return node;
344c9d75b3cSYann Gautier }
345c9d75b3cSYann Gautier 
346c9d75b3cSYann Gautier /*******************************************************************************
347c9d75b3cSYann Gautier  * This function gets the UART instance info of stdout from the DT.
348c9d75b3cSYann Gautier  * Returns node on success and a negative FDT error code on failure.
349c9d75b3cSYann Gautier  ******************************************************************************/
350c9d75b3cSYann Gautier int dt_get_stdout_uart_info(struct dt_node_info *info)
351c9d75b3cSYann Gautier {
352c9d75b3cSYann Gautier 	int node;
353c9d75b3cSYann Gautier 
354c9d75b3cSYann Gautier 	node = dt_get_stdout_node_offset();
355c9d75b3cSYann Gautier 	if (node < 0) {
356c9d75b3cSYann Gautier 		return -FDT_ERR_NOTFOUND;
357c9d75b3cSYann Gautier 	}
358c9d75b3cSYann Gautier 
359c9d75b3cSYann Gautier 	dt_fill_device_info(info, node);
360c9d75b3cSYann Gautier 
361c9d75b3cSYann Gautier 	return node;
362c9d75b3cSYann Gautier }
363c9d75b3cSYann Gautier 
364c9d75b3cSYann Gautier /*******************************************************************************
365c9d75b3cSYann Gautier  * This function gets DDR size information from the DT.
366c9d75b3cSYann Gautier  * Returns value in bytes on success, and 0 on failure.
367c9d75b3cSYann Gautier  ******************************************************************************/
368c9d75b3cSYann Gautier uint32_t dt_get_ddr_size(void)
369c9d75b3cSYann Gautier {
370c9d75b3cSYann Gautier 	int node;
371c9d75b3cSYann Gautier 
372c9d75b3cSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
373c9d75b3cSYann Gautier 	if (node < 0) {
374c9d75b3cSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
375c9d75b3cSYann Gautier 		return 0;
376c9d75b3cSYann Gautier 	}
377c9d75b3cSYann Gautier 
378c9d75b3cSYann Gautier 	return fdt_read_uint32_default(node, "st,mem-size", 0);
379c9d75b3cSYann Gautier }
380c9d75b3cSYann Gautier 
381c9d75b3cSYann Gautier /*******************************************************************************
3827ae58c6bSYann Gautier  * This function gets DDRCTRL base address information from the DT.
3837ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
3847ae58c6bSYann Gautier  ******************************************************************************/
3857ae58c6bSYann Gautier uintptr_t dt_get_ddrctrl_base(void)
3867ae58c6bSYann Gautier {
3877ae58c6bSYann Gautier 	int node;
3887ae58c6bSYann Gautier 	uint32_t array[4];
3897ae58c6bSYann Gautier 
3907ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
3917ae58c6bSYann Gautier 	if (node < 0) {
3927ae58c6bSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
3937ae58c6bSYann Gautier 		return 0;
3947ae58c6bSYann Gautier 	}
3957ae58c6bSYann Gautier 
396dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
397dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
398dd85e572SLionel Debieve 
3997ae58c6bSYann Gautier 	if (fdt_read_uint32_array(node, "reg", array, 4) < 0) {
4007ae58c6bSYann Gautier 		return 0;
4017ae58c6bSYann Gautier 	}
4027ae58c6bSYann Gautier 
4037ae58c6bSYann Gautier 	return array[0];
4047ae58c6bSYann Gautier }
4057ae58c6bSYann Gautier 
4067ae58c6bSYann Gautier /*******************************************************************************
4077ae58c6bSYann Gautier  * This function gets DDRPHYC base address information from the DT.
4087ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
4097ae58c6bSYann Gautier  ******************************************************************************/
4107ae58c6bSYann Gautier uintptr_t dt_get_ddrphyc_base(void)
4117ae58c6bSYann Gautier {
4127ae58c6bSYann Gautier 	int node;
4137ae58c6bSYann Gautier 	uint32_t array[4];
4147ae58c6bSYann Gautier 
4157ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
4167ae58c6bSYann Gautier 	if (node < 0) {
4177ae58c6bSYann Gautier 		INFO("%s: Cannot read DDR node in DT\n", __func__);
4187ae58c6bSYann Gautier 		return 0;
4197ae58c6bSYann Gautier 	}
4207ae58c6bSYann Gautier 
421dd85e572SLionel Debieve 	assert((fdt_get_node_parent_address_cells(node) == 1) &&
422dd85e572SLionel Debieve 	       (fdt_get_node_parent_size_cells(node) == 1));
423dd85e572SLionel Debieve 
4247ae58c6bSYann Gautier 	if (fdt_read_uint32_array(node, "reg", array, 4) < 0) {
4257ae58c6bSYann Gautier 		return 0;
4267ae58c6bSYann Gautier 	}
4277ae58c6bSYann Gautier 
4287ae58c6bSYann Gautier 	return array[2];
4297ae58c6bSYann Gautier }
4307ae58c6bSYann Gautier 
4317ae58c6bSYann Gautier /*******************************************************************************
4327ae58c6bSYann Gautier  * This function gets PWR base address information from the DT.
4337ae58c6bSYann Gautier  * Returns value on success, and 0 on failure.
4347ae58c6bSYann Gautier  ******************************************************************************/
4357ae58c6bSYann Gautier uintptr_t dt_get_pwr_base(void)
4367ae58c6bSYann Gautier {
4377ae58c6bSYann Gautier 	int node;
4387ae58c6bSYann Gautier 	const fdt32_t *cuint;
4397ae58c6bSYann Gautier 
4407ae58c6bSYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT);
4417ae58c6bSYann Gautier 	if (node < 0) {
4427ae58c6bSYann Gautier 		INFO("%s: Cannot read PWR node in DT\n", __func__);
4437ae58c6bSYann Gautier 		return 0;
4447ae58c6bSYann Gautier 	}
4457ae58c6bSYann Gautier 
446dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
447dd85e572SLionel Debieve 
4487ae58c6bSYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
4497ae58c6bSYann Gautier 	if (cuint == NULL) {
4507ae58c6bSYann Gautier 		return 0;
4517ae58c6bSYann Gautier 	}
4527ae58c6bSYann Gautier 
4537ae58c6bSYann Gautier 	return fdt32_to_cpu(*cuint);
4547ae58c6bSYann Gautier }
4557ae58c6bSYann Gautier 
4567ae58c6bSYann Gautier /*******************************************************************************
457f33b2433SYann Gautier  * This function gets PWR VDD regulator voltage information from the DT.
458f33b2433SYann Gautier  * Returns value in microvolts on success, and 0 on failure.
459f33b2433SYann Gautier  ******************************************************************************/
460f33b2433SYann Gautier uint32_t dt_get_pwr_vdd_voltage(void)
461f33b2433SYann Gautier {
462f33b2433SYann Gautier 	int node, pwr_regulators_node;
463f33b2433SYann Gautier 	const fdt32_t *cuint;
464f33b2433SYann Gautier 
465f33b2433SYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT);
466f33b2433SYann Gautier 	if (node < 0) {
467f33b2433SYann Gautier 		INFO("%s: Cannot read PWR node in DT\n", __func__);
468f33b2433SYann Gautier 		return 0;
469f33b2433SYann Gautier 	}
470f33b2433SYann Gautier 
471f33b2433SYann Gautier 	pwr_regulators_node = fdt_subnode_offset(fdt, node, "pwr-regulators");
472*e9d1e5afSYann Gautier 	if (pwr_regulators_node < 0) {
473f33b2433SYann Gautier 		INFO("%s: Cannot read pwr-regulators node in DT\n", __func__);
474f33b2433SYann Gautier 		return 0;
475f33b2433SYann Gautier 	}
476f33b2433SYann Gautier 
477f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, pwr_regulators_node, "vdd-supply", NULL);
478f33b2433SYann Gautier 	if (cuint == NULL) {
479f33b2433SYann Gautier 		return 0;
480f33b2433SYann Gautier 	}
481f33b2433SYann Gautier 
482f33b2433SYann Gautier 	node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
483f33b2433SYann Gautier 	if (node < 0) {
484f33b2433SYann Gautier 		return 0;
485f33b2433SYann Gautier 	}
486f33b2433SYann Gautier 
487f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
488f33b2433SYann Gautier 	if (cuint == NULL) {
489f33b2433SYann Gautier 		return 0;
490f33b2433SYann Gautier 	}
491f33b2433SYann Gautier 
492f33b2433SYann Gautier 	return fdt32_to_cpu(*cuint);
493f33b2433SYann Gautier }
494f33b2433SYann Gautier 
495f33b2433SYann Gautier /*******************************************************************************
496f33b2433SYann Gautier  * This function gets SYSCFG base address information from the DT.
497f33b2433SYann Gautier  * Returns value on success, and 0 on failure.
498f33b2433SYann Gautier  ******************************************************************************/
499f33b2433SYann Gautier uintptr_t dt_get_syscfg_base(void)
500f33b2433SYann Gautier {
501f33b2433SYann Gautier 	int node;
502f33b2433SYann Gautier 	const fdt32_t *cuint;
503f33b2433SYann Gautier 
504f33b2433SYann Gautier 	node = fdt_node_offset_by_compatible(fdt, -1, DT_SYSCFG_COMPAT);
505f33b2433SYann Gautier 	if (node < 0) {
506f33b2433SYann Gautier 		INFO("%s: Cannot read SYSCFG node in DT\n", __func__);
507f33b2433SYann Gautier 		return 0;
508f33b2433SYann Gautier 	}
509f33b2433SYann Gautier 
510dd85e572SLionel Debieve 	assert(fdt_get_node_parent_address_cells(node) == 1);
511dd85e572SLionel Debieve 
512f33b2433SYann Gautier 	cuint = fdt_getprop(fdt, node, "reg", NULL);
513f33b2433SYann Gautier 	if (cuint == NULL) {
514f33b2433SYann Gautier 		return 0;
515f33b2433SYann Gautier 	}
516f33b2433SYann Gautier 
517f33b2433SYann Gautier 	return fdt32_to_cpu(*cuint);
518f33b2433SYann Gautier }
519f33b2433SYann Gautier 
520f33b2433SYann Gautier /*******************************************************************************
521c9d75b3cSYann Gautier  * This function retrieves board model from DT
522c9d75b3cSYann Gautier  * Returns string taken from model node, NULL otherwise
523c9d75b3cSYann Gautier  ******************************************************************************/
524c9d75b3cSYann Gautier const char *dt_get_board_model(void)
525c9d75b3cSYann Gautier {
526c9d75b3cSYann Gautier 	int node = fdt_path_offset(fdt, "/");
527c9d75b3cSYann Gautier 
528c9d75b3cSYann Gautier 	if (node < 0) {
529c9d75b3cSYann Gautier 		return NULL;
530c9d75b3cSYann Gautier 	}
531c9d75b3cSYann Gautier 
532c9d75b3cSYann Gautier 	return (const char *)fdt_getprop(fdt, node, "model", NULL);
533c9d75b3cSYann Gautier }
534