diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index 74b01b3..a29d914 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -32,6 +32,8 @@ uint32_t dflt_value); int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array, uint32_t count); +int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, + size_t *size); int dt_set_stdout_pinctrl(void); void dt_fill_device_info(struct dt_node_info *info, int node); int dt_get_node(struct dt_node_info *info, int offset, const char *compat); diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 17da490..4fa796f 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -93,6 +93,46 @@ } /******************************************************************************* + * This function returns the address cells from the node parent. + * Returns: + * - #address-cells value if success. + * - invalid value if error. + * - a default value if undefined #address-cells property as per libfdt + * implementation. + ******************************************************************************/ +int fdt_get_node_parent_address_cells(int node) +{ + int parent; + + parent = fdt_parent_offset(fdt, node); + if (parent < 0) { + return -FDT_ERR_NOTFOUND; + } + + return fdt_address_cells(fdt, parent); +} + +/******************************************************************************* + * This function returns the size cells from the node parent. + * Returns: + * - #size-cells value if success. + * - invalid value if error. + * - a default value if undefined #size-cells property as per libfdt + * implementation. + ******************************************************************************/ +int fdt_get_node_parent_size_cells(int node) +{ + int parent; + + parent = fdt_parent_offset(fdt, node); + if (parent < 0) { + return -FDT_ERR_NOTFOUND; + } + + return fdt_size_cells(fdt, parent); +} + +/******************************************************************************* * This function reads a value of a node property (generic use of fdt * library). * Returns value if success, and a default value if property not found. @@ -146,6 +186,46 @@ } /******************************************************************************* + * This function fills reg node info (base & size) with an index found by + * checking the reg-names node. + * Returns 0 on success and a negative FDT error code on failure. + ******************************************************************************/ +int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, + size_t *size) +{ + const fdt32_t *cuint; + int index, len; + + assert((fdt_get_node_parent_address_cells(node) == 1) && + (fdt_get_node_parent_size_cells(node) == 1)); + + index = fdt_stringlist_search(fdt, node, "reg-names", name); + if (index < 0) { + return index; + } + + cuint = fdt_getprop(fdt, node, "reg", &len); + if (cuint == NULL) { + return -FDT_ERR_NOTFOUND; + } + + if ((index * (int)sizeof(uint32_t)) > len) { + return -FDT_ERR_BADVALUE; + } + + cuint += index << 1; + if (base != NULL) { + *base = fdt32_to_cpu(*cuint); + } + cuint++; + if (size != NULL) { + *size = fdt32_to_cpu(*cuint); + } + + return 0; +} + +/******************************************************************************* * This function gets the stdout path node. * It reads the value indicated inside the device tree. * Returns node offset on success and a negative FDT error code on failure. @@ -215,6 +295,8 @@ { const fdt32_t *cuint; + assert(fdt_get_node_parent_address_cells(node) == 1); + cuint = fdt_getprop(fdt, node, "reg", NULL); if (cuint != NULL) { info->base = fdt32_to_cpu(*cuint); @@ -309,6 +391,9 @@ return 0; } + assert((fdt_get_node_parent_address_cells(node) == 1) && + (fdt_get_node_parent_size_cells(node) == 1)); + if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { return 0; } @@ -331,6 +416,9 @@ return 0; } + assert((fdt_get_node_parent_address_cells(node) == 1) && + (fdt_get_node_parent_size_cells(node) == 1)); + if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { return 0; } @@ -353,6 +441,8 @@ return 0; } + assert(fdt_get_node_parent_address_cells(node) == 1); + cuint = fdt_getprop(fdt, node, "reg", NULL); if (cuint == NULL) { return 0; @@ -415,6 +505,8 @@ return 0; } + assert(fdt_get_node_parent_address_cells(node) == 1); + cuint = fdt_getprop(fdt, node, "reg", NULL); if (cuint == NULL) { return 0;