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