diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 27ddab0..feeb4a7 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -61,6 +61,9 @@ unsigned long stm32_get_gpio_bank_clock(unsigned int bank); uint32_t stm32_get_gpio_bank_offset(unsigned int bank); +/* Return node offset for target GPIO bank ID @bank or a FDT error code */ +int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank); + /* Print CPU information */ void stm32mp_print_cpuinfo(void); diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index e79551a..44ad820 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2020, STMicroelectronics - All Rights Reserved * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -39,5 +40,6 @@ uint32_t dt_get_pwr_vdd_voltage(void); uintptr_t dt_get_syscfg_base(void); const char *dt_get_board_model(void); +int fdt_get_gpio_bank_pin_count(unsigned int bank); #endif /* STM32MP_DT_H */ diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 155f784..4b8b2db 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -393,3 +393,51 @@ return (const char *)fdt_getprop(fdt, node, "model", NULL); } + +/******************************************************************************* + * This function gets the pin count for a GPIO bank based from the FDT. + * It also checks node consistency. + ******************************************************************************/ +int fdt_get_gpio_bank_pin_count(unsigned int bank) +{ + int pinctrl_node; + int node; + uint32_t bank_offset; + + pinctrl_node = stm32_get_gpio_bank_pinctrl_node(fdt, bank); + if (pinctrl_node < 0) { + return -FDT_ERR_NOTFOUND; + } + + bank_offset = stm32_get_gpio_bank_offset(bank); + + fdt_for_each_subnode(node, fdt, pinctrl_node) { + const fdt32_t *cuint; + + if (fdt_getprop(fdt, node, "gpio-controller", NULL) == NULL) { + continue; + } + + cuint = fdt_getprop(fdt, node, "reg", NULL); + if (cuint == NULL) { + continue; + } + + if (fdt32_to_cpu(*cuint) != bank_offset) { + continue; + } + + if (fdt_get_status(node) == DT_DISABLED) { + return 0; + } + + cuint = fdt_getprop(fdt, node, "ngpios", NULL); + if (cuint == NULL) { + return -FDT_ERR_NOTFOUND; + } + + return (int)fdt32_to_cpu(*cuint); + } + + return 0; +} diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 284ec9f..779228d 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -109,6 +109,28 @@ return GPIOA + (bank - GPIO_BANK_A); } +int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank) +{ + switch (bank) { + case GPIO_BANK_A: + case GPIO_BANK_B: + case GPIO_BANK_C: + case GPIO_BANK_D: + case GPIO_BANK_E: + case GPIO_BANK_F: + case GPIO_BANK_G: + case GPIO_BANK_H: + case GPIO_BANK_I: + case GPIO_BANK_J: + case GPIO_BANK_K: + return fdt_path_offset(fdt, "/soc/pin-controller"); + case GPIO_BANK_Z: + return fdt_path_offset(fdt, "/soc/pin-controller-z"); + default: + panic(); + } +} + static int get_part_number(uint32_t *part_nb) { uint32_t part_number;