From f4f933a64d20de0634f8b0a2bd44b0df04a3221f Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Jun 2019 17:07:44 +0200 Subject: pinctrl: add driver for STM32 GPIO and pin multiplexer This adds driver support for the 12 GPIO banks on the STM32MP157. As they are accessible to both the Cortex-A cores as well as the Cortex-M core, modifications to these are protected by a hardware spinlock and clocks are enabled/disabled as required. All register fiddling done by the driver is collected in , so future PBL code may make use of it as well to chainload barebox proper. Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- include/soc/stm32/gpio.h | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 include/soc/stm32/gpio.h (limited to 'include/soc') diff --git a/include/soc/stm32/gpio.h b/include/soc/stm32/gpio.h new file mode 100644 index 0000000000..13b492a693 --- /dev/null +++ b/include/soc/stm32/gpio.h @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015 Maxime Coquelin + * Copyright (C) 2017 STMicroelectronics + * Copyright (C) 2019 Ahmad Fatoum, Pengutronix + */ + +#ifndef __STM32_GPIO_H__ +#define __STM32_GPIO_H__ + +#include + +#define STM32_GPIO_MODER 0x00 +#define STM32_GPIO_TYPER 0x04 +#define STM32_GPIO_SPEEDR 0x08 +#define STM32_GPIO_PUPDR 0x0c +#define STM32_GPIO_IDR 0x10 +#define STM32_GPIO_ODR 0x14 +#define STM32_GPIO_BSRR 0x18 +#define STM32_GPIO_LCKR 0x1c +#define STM32_GPIO_AFRL 0x20 +#define STM32_GPIO_AFRH 0x24 + +#define STM32_PIN_GPIO 0 +#define STM32_PIN_AF(x) ((x) + 1) +#define STM32_PIN_ANALOG (STM32_PIN_AF(15) + 1) + +#define STM32_GPIO_PINS_PER_BANK 16 + +enum stm32_pin_bias { STM32_PIN_NO_BIAS, STM32_PIN_PULL_UP, STM32_PIN_PULL_DOWN }; +enum stm32_pin_out_type { STM32_PIN_OUT_PUSHPULL, STM32_PIN_OUT_OPENDRAIN }; + +static inline void __stm32_pmx_set_speed(void __iomem *base, + unsigned offset, u32 speed) +{ + u32 val = readl(base + STM32_GPIO_SPEEDR); + val &= ~GENMASK(offset * 2 + 1, offset * 2); + val |= speed << (offset * 2); + writel(val, base + STM32_GPIO_SPEEDR); +} + +static inline void __stm32_pmx_set_bias(void __iomem *base, unsigned offset, + enum stm32_pin_bias bias) +{ + u32 val = readl(base + STM32_GPIO_PUPDR); + val &= ~GENMASK(offset * 2 + 1, offset * 2); + val |= bias << (offset * 2); + writel(val, base + STM32_GPIO_PUPDR); +} + +static inline void __stm32_pmx_set_mode(void __iomem *base, + int pin, u32 mode, u32 alt) +{ + u32 val; + int alt_shift = (pin % 8) * 4; + int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4; + + val = readl(base + alt_offset); + val &= ~GENMASK(alt_shift + 3, alt_shift); + val |= (alt << alt_shift); + writel(val, base + alt_offset); + + val = readl(base + STM32_GPIO_MODER); + val &= ~GENMASK(pin * 2 + 1, pin * 2); + val |= mode << (pin * 2); + writel(val, base + STM32_GPIO_MODER); +} + +static inline void __stm32_pmx_get_mode(void __iomem *base, int pin, + u32 *mode, u32 *alt) +{ + u32 val; + int alt_shift = (pin % 8) * 4; + int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4; + + val = readl(base + alt_offset); + val &= GENMASK(alt_shift + 3, alt_shift); + *alt = val >> alt_shift; + + val = readl(base + STM32_GPIO_MODER); + val &= GENMASK(pin * 2 + 1, pin * 2); + *mode = val >> (pin * 2); +} + +static inline int __stm32_pmx_gpio_get(void __iomem *base, unsigned offset) +{ + return !!(readl(base + STM32_GPIO_IDR) & BIT(offset)); +} + +static inline void __stm32_pmx_gpio_set(void __iomem *base, unsigned offset, + unsigned value) +{ + if (!value) + offset += STM32_GPIO_PINS_PER_BANK; + + writel(BIT(offset), base + STM32_GPIO_BSRR); +} + +static inline void __stm32_pmx_gpio_input(void __iomem *base, unsigned offset) +{ + __stm32_pmx_set_mode(base, offset, 0, 0); +} + +static inline void __stm32_pmx_gpio_output(void __iomem *base, unsigned offset, + unsigned value) +{ + __stm32_pmx_gpio_set(base, offset, value); + __stm32_pmx_set_mode(base, offset, 1, 0); +} + +static inline void __stm32_pmx_set_output_type(void __iomem *base, unsigned offset, + enum stm32_pin_out_type type) +{ + u32 val = readl(base + STM32_GPIO_TYPER); + val &= ~BIT(offset); + val |= type << offset; + writel(val, base + STM32_GPIO_TYPER); +} + +#endif /* __STM32_GPIO_H__ */ -- cgit v1.2.3