diff options
author | Yann Gautier <yann.gautier@st.com> | 2018-07-13 21:33:09 +0200 |
---|---|---|
committer | Yann Gautier <yann.gautier@st.com> | 2018-07-24 17:14:08 +0200 |
commit | 6a339a49522db3ebb7eb44dec5772941b68372b6 (patch) | |
tree | 07d676719edf1eb945443f78665b2431214227fa /drivers/st | |
parent | 7839a050909944bd3ee6a70245a2bcc5471b3507 (diff) | |
download | trusted-firmware-a-6a339a49522db3ebb7eb44dec5772941b68372b6.tar.gz |
stm32mp1: Add GPIO support
The management of pinctrl nodes of device tree is also added.
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Mathieu Belou <mathieu.belou@st.com>
Signed-off-by: Nicolas Le Bayon <nicolas.le.bayon@st.com>
Diffstat (limited to 'drivers/st')
-rw-r--r-- | drivers/st/gpio/stm32_gpio.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c new file mode 100644 index 0000000000..200b47340a --- /dev/null +++ b/drivers/st/gpio/stm32_gpio.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <bl_common.h> +#include <debug.h> +#include <mmio.h> +#include <stdbool.h> +#include <stm32_gpio.h> + +static bool check_gpio(uint32_t bank, uint32_t pin) +{ + if (pin > GPIO_PIN_MAX) { + ERROR("%s: wrong pin number (%d)\n", __func__, pin); + return false; + } + + if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) { + ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank); + return false; + } + + return true; +} + +void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, + uint32_t pull, uint32_t alternate) +{ + volatile uint32_t bank_address; + + if (!check_gpio(bank, pin)) { + return; + } + + if (bank == GPIO_BANK_Z) { + bank_address = STM32_GPIOZ_BANK; + } else { + bank_address = STM32_GPIOA_BANK + + (bank * STM32_GPIO_BANK_OFFSET); + } + + mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET, + ((uint32_t)GPIO_MODE_MASK << (pin << 1))); + mmio_setbits_32(bank_address + GPIO_MODE_OFFSET, + (mode & ~GPIO_OPEN_DRAIN) << (pin << 1)); + + if ((mode & GPIO_OPEN_DRAIN) != 0U) { + mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET, + BIT(pin)); + } + + mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET, + ((uint32_t)GPIO_SPEED_MASK << (pin << 1))); + mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1)); + + mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET, + ((uint32_t)GPIO_PULL_MASK << (pin << 1))); + mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1)); + + if (pin < GPIO_ALT_LOWER_LIMIT) { + mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET, + ((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2))); + mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET, + alternate << (pin << 2)); + } else { + mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET, + ((uint32_t)GPIO_ALTERNATE_MASK << + ((pin - GPIO_ALT_LOWER_LIMIT) << 2))); + mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET, + alternate << ((pin - GPIO_ALT_LOWER_LIMIT) << + 2)); + } + + VERBOSE("GPIO %u mode set to 0x%x\n", bank, + mmio_read_32(bank_address + GPIO_MODE_OFFSET)); + VERBOSE("GPIO %u speed set to 0x%x\n", bank, + mmio_read_32(bank_address + GPIO_SPEED_OFFSET)); + VERBOSE("GPIO %u mode pull to 0x%x\n", bank, + mmio_read_32(bank_address + GPIO_PUPD_OFFSET)); + VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank, + mmio_read_32(bank_address + GPIO_AFRL_OFFSET)); + VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank, + mmio_read_32(bank_address + GPIO_AFRH_OFFSET)); +} |