[U-Boot] [PATCH 0/5] stm32mp1: activate gpio hog support and add new pinctrl ops

Hi,
This serie updates the two pincontrol drivers for stm32mp1 and activates the gpio hog support to prepare the rebase on the v5.4 linux kernel device tree.
The 2 last commits have dependency with the previous serie "dm: add support of new binding in gpio and pincontrol" http://patchwork.ozlabs.org/project/uboot/list/?series=138082
My working branch: https://github.com/patrickdelaunay/u-boot/tree/dm
CI-Travis build: https://travis-ci.org/patrickdelaunay/u-boot/builds/601829330
Regards.
Patrick
Patrick Delaunay (5): pinctrl: stmfx: add information on pin configuration pinctrl: stm32: add information on pin configuration stm32mp1: activate CONFIG_GPIO_HOG and update the gpio hog support gpio: stm32: add set_config ops gpio: stmfx: add set_config ops
board/st/stm32mp1/stm32mp1.c | 10 +- configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_optee_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + drivers/gpio/stm32_gpio.c | 58 ++++++++++++ drivers/pinctrl/pinctrl-stmfx.c | 140 ++++++++++++++++++++-------- drivers/pinctrl/pinctrl_stm32.c | 27 +++++- 7 files changed, 190 insertions(+), 48 deletions(-)

Add information on pin configuration used for pinmux command.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
drivers/pinctrl/pinctrl-stmfx.c | 35 ++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 0b5a0433cd..0cd371fefa 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -286,6 +286,37 @@ static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, return pin_name; }
+static const char *stmfx_pinctrl_get_pin_conf(struct udevice *dev, + unsigned int pin, int func) +{ + int pupd, type; + u32 mask = get_mask(pin); + + type = stmfx_read(dev, STMFX_REG_GPIO_TYPE + get_reg(pin)); + if (type < 0) + return ""; + type &= mask; + + if (func == GPIOF_INPUT) { + if (type) + return "drive-open-drain"; + else + return "drive-push-pull"; + } + if (!type) + return "bias-disable"; + + pupd = stmfx_read(dev, STMFX_REG_GPIO_PUPD + get_reg(pin)); + if (pupd < 0) + return ""; + pupd &= mask; + + if (pupd) + return "bias-pull-up"; + else + return "bias-pull-down"; +} + static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, unsigned int selector, char *buf, int size) @@ -297,7 +328,9 @@ static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, if (func < 0) return func;
- snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output"); + snprintf(buf, size, "%s ", func == GPIOF_INPUT ? "input" : "output"); + + strncat(buf, stmfx_pinctrl_get_pin_conf(dev, selector, func), size);
return 0; }

Add information on pin configuration used for pinmux command: - bias configuration for output (disable, pull up, pull down) - otype for input (open drain or push pull)
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
drivers/pinctrl/pinctrl_stm32.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 3a235ae5a7..4511cd7a45 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -39,6 +39,17 @@ static const char * const pinmux_mode[PINMUX_MODE_COUNT] = { "alt function", };
+static const char * const pinmux_output[] = { + [STM32_GPIO_PUPD_NO] = "bias-disable", + [STM32_GPIO_PUPD_UP] = "bias-pull-up", + [STM32_GPIO_PUPD_DOWN] = "bias-pull-down", +}; + +static const char * const pinmux_input[] = { + [STM32_GPIO_OTYPE_PP] = "drive-push-pull", + [STM32_GPIO_OTYPE_OD] = "drive-open-drain", +}; + static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) { struct stm32_gpio_priv *priv = dev_get_priv(dev); @@ -176,10 +187,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, int size) { struct udevice *gpio_dev; + struct stm32_gpio_priv *priv; const char *label; int mode; int af_num; unsigned int gpio_idx; + u32 pupd, otype;
/* look up for the bank which owns the requested pin */ gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); @@ -188,9 +201,9 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, return -ENODEV;
mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label); - dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", selector, gpio_idx, mode); + priv = dev_get_priv(gpio_dev);
switch (mode) { @@ -205,9 +218,17 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); break; case GPIOF_OUTPUT: + pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) & + PUPD_MASK; + snprintf(buf, size, "%s %s %s", + pinmux_mode[mode], pinmux_output[pupd], + label ? label : ""); + break; case GPIOF_INPUT: - snprintf(buf, size, "%s %s", - pinmux_mode[mode], label ? label : ""); + otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK; + snprintf(buf, size, "%s %s %s", + pinmux_mode[mode], pinmux_input[otype], + label ? label : ""); break; }

This patch migrates the current gpio hog implementation with the new configuration CONFIG_GPIO_HOG.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
board/st/stm32mp1/stm32mp1.c | 10 ++-------- configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_optee_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + 4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 18f9b84876..2b96b1ae23 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -599,17 +599,11 @@ static bool board_is_dk2(void) /* board dependent setup after realloc */ int board_init(void) { - struct udevice *dev; - /* address of boot parameters */ gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
- /* probe all PINCTRL for hog */ - for (uclass_first_device(UCLASS_PINCTRL, &dev); - dev; - uclass_next_device(&dev)) { - pr_debug("probe pincontrol = %s\n", dev->name); - } + if (CONFIG_IS_ENABLED(DM_GPIO_HOG)) + gpio_hog_probe_all();
board_key_check();
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index c54feb03e6..7daa059865 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -68,6 +68,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x02000000 CONFIG_FASTBOOT_USB_DEV=1 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y diff --git a/configs/stm32mp15_optee_defconfig b/configs/stm32mp15_optee_defconfig index 491174fc15..925e31b5ca 100644 --- a/configs/stm32mp15_optee_defconfig +++ b/configs/stm32mp15_optee_defconfig @@ -55,6 +55,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x02000000 CONFIG_FASTBOOT_USB_DEV=1 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index a8a7eec357..eb6eea6dc9 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -54,6 +54,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x02000000 CONFIG_FASTBOOT_USB_DEV=1 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y

Manage flags for GPIO configuration: - open_drain, open_source, push_pull - pull_up, pull_down
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
drivers/gpio/stm32_gpio.c | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+)
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index 302a434947..bc4c378260 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -19,6 +19,12 @@ #define MODE_BITS_MASK 3 #define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16))
+#define PUPD_BITS(gpio_pin) (gpio_pin * 2) +#define PUPD_MASK 3 + +#define OTYPE_BITS(gpio_pin) (gpio_pin) +#define OTYPE_MSK 1 + #ifndef CONFIG_SPL_BUILD /* * convert gpio offset to gpio index taking into account gpio holes @@ -139,12 +145,64 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) return GPIOF_FUNC; }
+static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs, + int idx, + enum stm32_gpio_otype otype) +{ + int bits; + + bits = OTYPE_BITS(idx); + clrsetbits_le32(®s->otyper, OTYPE_MSK << bits, otype << bits); +} + +static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs, + int idx, + enum stm32_gpio_pupd pupd) +{ + int bits; + + bits = PUPD_BITS(idx); + clrsetbits_le32(®s->pupdr, PUPD_MASK << bits, pupd << bits); +} + +static int stm32_gpio_set_config(struct udevice *dev, unsigned int offset, + enum gpio_config config) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + int idx; + + idx = stm32_offset_to_index(dev, offset); + if (idx < 0) + return idx; + + switch (config) { + default: + return -ENOTSUPP; + case GPIO_CONF_DRIVE_OPEN_DRAIN: + stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD); + break; + case GPIO_CONF_DRIVE_PULL_PUSH: + stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP); + break; + case GPIO_CONF_BIAS_PULL_UP: + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); + break; + case GPIO_CONF_BIAS_PULL_DOWN: + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); + break; + } + + return 0; +} + static const struct dm_gpio_ops gpio_stm32_ops = { .direction_input = stm32_gpio_direction_input, .direction_output = stm32_gpio_direction_output, .get_value = stm32_gpio_get_value, .set_value = stm32_gpio_set_value, .get_function = stm32_gpio_get_function, + .set_config = stm32_gpio_set_config, }; #endif

Manage the flags for GPIO configuration: - open_drain, push_pull - pull_up, pull_down
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
drivers/pinctrl/pinctrl-stmfx.c | 105 +++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 36 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 0cd371fefa..d90e6fb57c 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -71,6 +71,36 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) return dm_i2c_reg_write(dev_get_parent(dev), offset, val); }
+static int stmfx_conf_set_pupd(struct udevice *dev, + unsigned int pin, u32 pupd) +{ + u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); + u32 mask = get_mask(pin); + int ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + ret = (ret & ~mask) | (pupd ? mask : 0); + + return stmfx_write(dev, reg, ret); +} + +static int stmfx_conf_set_type(struct udevice *dev, + unsigned int pin, u32 type) +{ + u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); + u32 mask = get_mask(pin); + int ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + ret = (ret & ~mask) | (type ? mask : 0); + + return stmfx_write(dev, reg, ret); +} + static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) { u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset); @@ -138,6 +168,38 @@ static int stmfx_gpio_direction_output(struct udevice *dev, return stmfx_write(dev, reg, ret | mask); }
+static int stmfx_gpio_set_config(struct udevice *dev, unsigned int offset, + enum gpio_config config) +{ + int ret; + + switch (config) { + case GPIO_CONF_DRIVE_OPEN_DRAIN: + ret = stmfx_conf_set_type(dev, offset, 0); + break; + case GPIO_CONF_DRIVE_PULL_PUSH: + ret = stmfx_conf_set_type(dev, offset, 1); + break; + case GPIO_CONF_BIAS_PULL_UP: + ret = stmfx_conf_set_type(dev, offset, 1); + if (ret) + return ret; + ret = stmfx_conf_set_pupd(dev, offset, 1); + break; + case GPIO_CONF_BIAS_PULL_DOWN: + ret = stmfx_conf_set_type(dev, offset, 1); + if (ret) + return ret; + ret = stmfx_conf_set_pupd(dev, offset, 0); + break; + case GPIO_CONF_DRIVE_OPEN_SOURCE: + default: + return -ENOTSUPP; + } + + return ret; +} + static int stmfx_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); @@ -166,6 +228,7 @@ static const struct dm_gpio_ops stmfx_gpio_ops = { .get_function = stmfx_gpio_get_function, .direction_input = stmfx_gpio_direction_input, .direction_output = stmfx_gpio_direction_output, + .set_config = stmfx_gpio_set_config, };
U_BOOT_DRIVER(stmfx_gpio) = { @@ -187,36 +250,6 @@ static const struct pinconf_param stmfx_pinctrl_conf_params[] = { { "output-low", PIN_CONFIG_OUTPUT, 0 }, };
-static int stmfx_pinctrl_set_pupd(struct udevice *dev, - unsigned int pin, u32 pupd) -{ - u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); - u32 mask = get_mask(pin); - int ret; - - ret = stmfx_read(dev, reg); - if (ret < 0) - return ret; - ret = (ret & ~mask) | (pupd ? mask : 0); - - return stmfx_write(dev, reg, ret); -} - -static int stmfx_pinctrl_set_type(struct udevice *dev, - unsigned int pin, u32 type) -{ - u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); - u32 mask = get_mask(pin); - int ret; - - ret = stmfx_read(dev, reg); - if (ret < 0) - return ret; - ret = (ret & ~mask) | (type ? mask : 0); - - return stmfx_write(dev, reg, ret); -} - static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, unsigned int param, unsigned int arg) { @@ -232,22 +265,22 @@ static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_DRIVE_PUSH_PULL: - ret = stmfx_pinctrl_set_type(dev, pin, 0); + ret = stmfx_conf_set_type(dev, pin, 0); break; case PIN_CONFIG_BIAS_PULL_DOWN: - ret = stmfx_pinctrl_set_type(dev, pin, 1); + ret = stmfx_conf_set_type(dev, pin, 1); if (ret) return ret; - ret = stmfx_pinctrl_set_pupd(dev, pin, 0); + ret = stmfx_conf_set_pupd(dev, pin, 0); break; case PIN_CONFIG_BIAS_PULL_UP: - ret = stmfx_pinctrl_set_type(dev, pin, 1); + ret = stmfx_conf_set_type(dev, pin, 1); if (ret) return ret; - ret = stmfx_pinctrl_set_pupd(dev, pin, 1); + ret = stmfx_conf_set_pupd(dev, pin, 1); break; case PIN_CONFIG_DRIVE_OPEN_DRAIN: - ret = stmfx_pinctrl_set_type(dev, pin, 1); + ret = stmfx_conf_set_type(dev, pin, 1); break; case PIN_CONFIG_OUTPUT: ret = stmfx_gpio_direction_output(plat->gpio, pin, arg);
participants (1)
-
Patrick Delaunay