From ccc199eddaa6f5545e5c375be258b6ba686205ff Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sat, 25 Apr 2020 11:14:45 +0200 Subject: [PATCH] plat/stm32mp1: fdt helpers for secure aware gpio bank New helper functions to get GPIO banks configuration from the FDT. stm32_get_gpio_bank_pinctrl_node() allows stm32mp platforms to differentiate specific GPIO banks when these are defined with a specific path in the FDT. fdt_get_gpio_bank_pin_count() returns the number of pins in a GPIO bank as it depends on the SoC variant. Change-Id: I4481774152b3c6bf35bf986f58e357c2f9c19176 Signed-off-by: Etienne Carriere --- plat/st/common/include/stm32mp_common.h | 3 ++ plat/st/common/include/stm32mp_dt.h | 2 ++ plat/st/common/stm32mp_dt.c | 48 +++++++++++++++++++++++++ plat/st/stm32mp1/stm32mp1_private.c | 22 ++++++++++++ 4 files changed, 75 insertions(+) diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 27ddab0c8..feeb4a790 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -61,6 +61,9 @@ uintptr_t stm32_get_gpio_bank_base(unsigned int bank); 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 e79551a31..44ad820dc 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 @@ uintptr_t dt_get_pwr_base(void); 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 155f78404..4b8b2db90 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -393,3 +393,51 @@ const char *dt_get_board_model(void) 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 284ec9f9f..779228d4a 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -109,6 +109,28 @@ unsigned long stm32_get_gpio_bank_clock(unsigned int bank) 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;