From deb9c864eac86b4c7a57ec5bf90d301f7f741bd0 Mon Sep 17 00:00:00 2001 From: Pascal Paillet Date: Tue, 15 Mar 2022 15:20:00 +0100 Subject: [PATCH 1/5] feat(dt-bindings): describe ST GPIO banks and config Describe GPIO banks configs so that it can be used in an STM32MP device-tree file. Signed-off-by: Pascal Paillet Change-Id: If5dd05aae314cbb3189eb02c9fe555b832ac2bdb --- include/dt-bindings/gpio/stm32-gpio.h | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 include/dt-bindings/gpio/stm32-gpio.h diff --git a/include/dt-bindings/gpio/stm32-gpio.h b/include/dt-bindings/gpio/stm32-gpio.h new file mode 100644 index 000000000..2c7a0f154 --- /dev/null +++ b/include/dt-bindings/gpio/stm32-gpio.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * Copyright (C) 2024 STMicroelectronics - All Rights Reserved + * Author: Paillet Pascal for STMicroelectronics. + */ + +#ifndef DT_BINDINGS_STM32_GPIO_H +#define DT_BINDINGS_STM32_GPIO_H + +/* Bank IDs used in GPIO driver API */ +#define GPIO_BANK_A 0U +#define GPIO_BANK_B 1U +#define GPIO_BANK_C 2U +#define GPIO_BANK_D 3U +#define GPIO_BANK_E 4U +#define GPIO_BANK_F 5U +#define GPIO_BANK_G 6U +#define GPIO_BANK_H 7U +#define GPIO_BANK_I 8U +#define GPIO_BANK_J 9U +#define GPIO_BANK_K 10U +#define GPIO_BANK_Z 25U + +/* Bit 0 is used to set GPIO in input mode */ +#define GPIOF_DIR_OUT 0x0 +#define GPIOF_DIR_IN 0x1 + +/* Bit 1 is used to set GPIO high level during init */ +#define GPIOF_INIT_LOW 0x0 +#define GPIOF_INIT_HIGH 0x2 + +#define GPIOF_IN (GPIOF_DIR_IN) +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) + +/* Bit 2 is used to set GPIO pull up */ +#define GPIOF_PULL_UP 0x4 +/* Bit 3 is used to set GPIO pull down */ +#define GPIOF_PULL_DOWN 0x8 + +#endif /* DT_BINDINGS_STM32_GPIO_H */ From e04a9ef5eae676dedd9e31ff6f6c5dbb9fd3091c Mon Sep 17 00:00:00 2001 From: Pascal Paillet Date: Wed, 16 Mar 2022 17:25:57 +0100 Subject: [PATCH 2/5] refactor(st): use GPIO banks definition from bindings Use GPIO banks definition from bindings. Change-Id: I4dcf321345e319af78285e940b72a1369569b996 Signed-off-by: Pascal Paillet --- plat/st/stm32mp1/stm32mp1_def.h | 15 +-------------- plat/st/stm32mp2/stm32mp2_def.h | 1 + 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 8a1d76d19..824563fe9 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -231,21 +232,7 @@ enum ddr_type { #endif #define GPIO_BANK_OFFSET U(0x1000) -/* Bank IDs used in GPIO driver API */ -#define GPIO_BANK_A U(0) -#define GPIO_BANK_B U(1) -#define GPIO_BANK_C U(2) -#define GPIO_BANK_D U(3) -#define GPIO_BANK_E U(4) -#define GPIO_BANK_F U(5) -#define GPIO_BANK_G U(6) -#define GPIO_BANK_H U(7) -#define GPIO_BANK_I U(8) #if STM32MP15 -#define GPIO_BANK_J U(9) -#define GPIO_BANK_K U(10) -#define GPIO_BANK_Z U(25) - #define STM32MP_GPIOZ_PIN_MAX_COUNT 8 #endif diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h index 56c62e12b..e3662ad3d 100644 --- a/plat/st/stm32mp2/stm32mp2_def.h +++ b/plat/st/stm32mp2/stm32mp2_def.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #ifndef __ASSEMBLER__ From 5c457689b283437cbf1ba87c48bae9e03a579aa8 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 28 Nov 2023 11:35:51 +0100 Subject: [PATCH 3/5] fix(stm32mp1): remove unnecessary assert on GPIO_BANK_A value Remove assert for unexpected value of the define GPIO_BANK_A. This check is not required as GPIO_BANK_A = 0, it can be limited to have bank <= GPIO_BANK_K as bank is unsigned int. Signed-off-by: Patrick Delaunay Change-Id: I0345d56f106fcacd6a6f93281c2d9279980cd152 --- plat/st/stm32mp1/stm32mp1_private.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index f098eb37e..509bb11de 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -115,14 +115,14 @@ void configure_mmu(void) uintptr_t stm32_get_gpio_bank_base(unsigned int bank) { #if STM32MP13 - assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I)); + assert(bank <= GPIO_BANK_I); #endif #if STM32MP15 if (bank == GPIO_BANK_Z) { return GPIOZ_BASE; } - assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K)); + assert(bank <= GPIO_BANK_K); #endif return GPIOA_BASE + (bank * GPIO_BANK_OFFSET); @@ -131,14 +131,14 @@ uintptr_t stm32_get_gpio_bank_base(unsigned int bank) uint32_t stm32_get_gpio_bank_offset(unsigned int bank) { #if STM32MP13 - assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I)); + assert(bank <= GPIO_BANK_I); #endif #if STM32MP15 if (bank == GPIO_BANK_Z) { return 0; } - assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K)); + assert(bank <= GPIO_BANK_K); #endif return bank * GPIO_BANK_OFFSET; @@ -161,14 +161,14 @@ bool stm32_gpio_is_secure_at_reset(unsigned int bank) unsigned long stm32_get_gpio_bank_clock(unsigned int bank) { #if STM32MP13 - assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I)); + assert(bank <= GPIO_BANK_I); #endif #if STM32MP15 if (bank == GPIO_BANK_Z) { return GPIOZ; } - assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K)); + assert(bank <= GPIO_BANK_K); #endif return GPIOA + (bank - GPIO_BANK_A); From bfa5f61b579f9eaeead1278efc5997ddd4b5543a Mon Sep 17 00:00:00 2001 From: Pascal Paillet Date: Thu, 17 Feb 2022 17:22:04 +0100 Subject: [PATCH 4/5] feat(st-gpio): add set GPIO config API Add get and set GPIO level from bank and pin value. Add functions to set a pad in GPIO configuration and to apply some settings. Change-Id: I5e3acb5c95cd03f3e130e1a263b221b956cb3c8d Signed-off-by: Pascal Paillet --- drivers/st/gpio/stm32_gpio.c | 73 ++++++++++++++++++++++++++++++++- include/drivers/st/stm32_gpio.h | 13 +++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c index a4a64ca72..3947628b2 100644 --- a/drivers/st/gpio/stm32_gpio.c +++ b/drivers/st/gpio/stm32_gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved + * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -321,3 +321,74 @@ void set_gpio_reset_cfg(uint32_t bank, uint32_t pin) GPIO_ALTERNATE_(0), DT_DISABLED); set_gpio_secure_cfg(bank, pin, stm32_gpio_is_secure_at_reset(bank)); } + +void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level) +{ + uintptr_t base = stm32_get_gpio_bank_base(bank); + unsigned long clock = stm32_get_gpio_bank_clock(bank); + + assert(pin <= GPIO_PIN_MAX); + + clk_enable(clock); + + if (level == GPIO_LEVEL_HIGH) { + mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin)); + } else { + mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin + 16U)); + } + + VERBOSE("GPIO %u level set to 0x%x\n", bank, + mmio_read_32(base + GPIO_IDR_OFFSET)); + + clk_disable(clock); +} + +enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin) +{ + uintptr_t base = stm32_get_gpio_bank_base(bank); + unsigned long clock = stm32_get_gpio_bank_clock(bank); + enum gpio_level level = GPIO_LEVEL_LOW; + + assert(pin <= GPIO_PIN_MAX); + + clk_enable(clock); + + if (mmio_read_32(base + GPIO_IDR_OFFSET) & BIT(pin)) { + level = GPIO_LEVEL_HIGH; + } + + VERBOSE("GPIO %u get level 0x%x\n", bank, + mmio_read_32(base + GPIO_IDR_OFFSET)); + + clk_disable(clock); + + return level; +} + +void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status) +{ + uint32_t mode = GPIO_MODE_OUTPUT; + uint32_t od = 0U; + uint32_t pull = GPIO_NO_PULL; + + VERBOSE("GPIO %u:%u set config to 0x%x\n", bank, pin, config); + + if (config & GPIOF_DIR_IN) { + mode = GPIO_MODE_INPUT; + } + + if (config & GPIOF_OUT_INIT_HIGH) { + od = 1U; + } + + if (config & GPIOF_PULL_UP) { + pull |= GPIO_PULL_UP; + } + + if (config & GPIOF_PULL_DOWN) { + pull |= GPIO_PULL_DOWN; + } + + set_gpio(bank, pin, mode, GPIO_TYPE_PUSH_PULL, GPIO_SPEED_LOW, + pull, od, GPIO_ALTERNATE_(0), status); +} diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h index eeef9da5d..ef4eb04a2 100644 --- a/include/drivers/st/stm32_gpio.h +++ b/include/drivers/st/stm32_gpio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2022, STMicroelectronics - All Rights Reserved + * Copyright (c) 2015-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,7 @@ #define GPIO_TYPE_OFFSET U(0x04) #define GPIO_SPEED_OFFSET U(0x08) #define GPIO_PUPD_OFFSET U(0x0C) +#define GPIO_IDR_OFFSET U(0x10) #define GPIO_OD_OFFSET U(0x14) #define GPIO_BSRR_OFFSET U(0x18) #define GPIO_AFRL_OFFSET U(0x20) @@ -58,6 +59,16 @@ int dt_set_pinctrl_config(int node); void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure); void set_gpio_reset_cfg(uint32_t bank, uint32_t pin); + +enum gpio_level { + GPIO_LEVEL_LOW, + GPIO_LEVEL_HIGH +}; + +void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level); +enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin); + +void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status); #endif /*__ASSEMBLER__*/ #endif /* STM32_GPIO_H */ From 179a130aea4876c7fc89606c65b55f143724eb38 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Wed, 8 Nov 2023 18:59:07 +0100 Subject: [PATCH 5/5] fix(st-gpio): configure each GPIO mux as secure for STM32MP2 GPIOs are configured as secure by default on STM32MP2. The former code is then put under #if STM32MP13 || STM32MP15. The else part is for STM32MP2 family. Signed-off-by: Patrick Delaunay Signed-off-by: Christophe Kerello Change-Id: I80c5944d4ae662f9e28269c3dc543b13f0e26a7b --- drivers/st/gpio/stm32_gpio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c index 3947628b2..44d7c0954 100644 --- a/drivers/st/gpio/stm32_gpio.c +++ b/drivers/st/gpio/stm32_gpio.c @@ -282,6 +282,7 @@ static void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t type, clk_disable(clock); +#if STM32MP13 || STM32MP15 if (status == DT_SECURE) { stm32mp_register_secure_gpio(bank, pin); #if !IMAGE_BL2 @@ -294,6 +295,9 @@ static void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t type, set_gpio_secure_cfg(bank, pin, false); #endif } +#else /* !STM32MP13 && !STM32MP15 */ + set_gpio_secure_cfg(bank, pin, true); +#endif /* STM32MP13 || STM32MP15 */ } void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)