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