diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c index a4a64ca72..44d7c0954 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 */ @@ -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) @@ -321,3 +325,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 */ 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 */ 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/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); 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__