aboutsummaryrefslogtreecommitdiff
path: root/drivers/st
diff options
context:
space:
mode:
authorYann Gautier <yann.gautier@st.com>2018-07-13 21:33:09 +0200
committerYann Gautier <yann.gautier@st.com>2018-07-24 17:14:08 +0200
commit6a339a49522db3ebb7eb44dec5772941b68372b6 (patch)
tree07d676719edf1eb945443f78665b2431214227fa /drivers/st
parent7839a050909944bd3ee6a70245a2bcc5471b3507 (diff)
downloadtrusted-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.c86
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));
+}