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