diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpio/stm32_gpio.c | 28 | ||||
-rw-r--r-- | drivers/phy/phy-stm32-usbphyc.c | 33 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-stmfx.c | 13 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl_stm32.c | 24 | ||||
-rw-r--r-- | drivers/remoteproc/stm32_copro.c | 108 | ||||
-rw-r--r-- | drivers/reset/stm32-reset.c | 17 |
6 files changed, 102 insertions, 121 deletions
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index b885cfb57e..51e1efd701 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -212,11 +212,11 @@ static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, } else if (flags & GPIOD_IS_IN) { stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN); - if (flags & GPIOD_PULL_UP) - stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); - else if (flags & GPIOD_PULL_DOWN) - stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); } + if (flags & GPIOD_PULL_UP) + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); + else if (flags & GPIOD_PULL_DOWN) + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); return 0; } @@ -243,16 +243,16 @@ static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset, break; case STM32_GPIO_MODE_IN: dir_flags |= GPIOD_IS_IN; - switch (stm32_gpio_get_pupd(regs, idx)) { - case STM32_GPIO_PUPD_UP: - dir_flags |= GPIOD_PULL_UP; - break; - case STM32_GPIO_PUPD_DOWN: - dir_flags |= GPIOD_PULL_DOWN; - break; - default: - break; - } + break; + default: + break; + } + switch (stm32_gpio_get_pupd(regs, idx)) { + case STM32_GPIO_PUPD_UP: + dir_flags |= GPIOD_PULL_UP; + break; + case STM32_GPIO_PUPD_DOWN: + dir_flags |= GPIOD_PULL_DOWN; break; default: break; diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c index 9d4296d649..ab4a913c93 100644 --- a/drivers/phy/phy-stm32-usbphyc.c +++ b/drivers/phy/phy-stm32-usbphyc.c @@ -59,6 +59,7 @@ struct stm32_usbphyc { struct udevice *vdda1v8; struct stm32_usbphyc_phy { struct udevice *vdd; + struct udevice *vbus; bool init; bool powered; } phys[MAX_PHYS]; @@ -244,6 +245,11 @@ static int stm32_usbphyc_phy_power_on(struct phy *phy) if (ret) return ret; } + if (usbphyc_phy->vbus) { + ret = regulator_set_enable(usbphyc_phy->vbus, true); + if (ret) + return ret; + } usbphyc_phy->powered = true; @@ -262,6 +268,11 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) if (stm32_usbphyc_is_powered(usbphyc)) return 0; + if (usbphyc_phy->vbus) { + ret = regulator_set_enable(usbphyc_phy->vbus, false); + if (ret) + return ret; + } if (usbphyc_phy->vdd) { ret = regulator_set_enable_if_allowed(usbphyc_phy->vdd, false); if (ret) @@ -271,7 +282,7 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) return 0; } -static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node, +static int stm32_usbphyc_get_regulator(ofnode node, char *supply_name, struct udevice **regulator) { @@ -281,19 +292,14 @@ static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node, ret = ofnode_parse_phandle_with_args(node, supply_name, NULL, 0, 0, ®ulator_phandle); - if (ret) { - dev_err(dev, "Can't find %s property (%d)\n", supply_name, ret); + if (ret) return ret; - } ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR, regulator_phandle.node, regulator); - - if (ret) { - dev_err(dev, "Can't get %s regulator (%d)\n", supply_name, ret); + if (ret) return ret; - } return 0; } @@ -380,10 +386,17 @@ static int stm32_usbphyc_probe(struct udevice *dev) usbphyc_phy->init = false; usbphyc_phy->powered = false; - ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply", + ret = stm32_usbphyc_get_regulator(node, "phy-supply", &usbphyc_phy->vdd); - if (ret) + if (ret) { + dev_err(dev, "Can't get phy-supply regulator\n"); return ret; + } + + ret = stm32_usbphyc_get_regulator(node, "vbus-supply", + &usbphyc_phy->vbus); + if (ret) + usbphyc_phy->vbus = NULL; node = dev_read_next_subnode(node); } diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index c2ea82770e..a62be44d2d 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -343,8 +343,8 @@ static int stmfx_pinctrl_get_pins_count(struct udevice *dev) } /* - * STMFX pins[15:0] are called "gpio[15:0]" - * and STMFX pins[23:16] are called "agpio[7:0]" + * STMFX pins[15:0] are called "stmfx_gpio[15:0]" + * and STMFX pins[23:16] are called "stmfx_agpio[7:0]" */ #define MAX_PIN_NAME_LEN 7 static char pin_name[MAX_PIN_NAME_LEN]; @@ -352,9 +352,9 @@ static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, unsigned int selector) { if (selector < STMFX_MAX_GPIO) - snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); + snprintf(pin_name, MAX_PIN_NAME_LEN, "stmfx_gpio%u", selector); else - snprintf(pin_name, MAX_PIN_NAME_LEN, "agpio%u", selector - 16); + snprintf(pin_name, MAX_PIN_NAME_LEN, "stmfx_agpio%u", selector - 16); return pin_name; } @@ -408,8 +408,11 @@ static int stmfx_pinctrl_bind(struct udevice *dev) { struct stmfx_pinctrl *plat = dev_get_platdata(dev); + /* subnode name is not explicit: use father name */ + device_set_name(dev, dev->parent->name); + return device_bind_driver_to_node(dev->parent, - "stmfx-gpio", "stmfx-gpio", + "stmfx-gpio", dev->parent->name, dev_ofnode(dev), &plat->gpio); }; diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index dbea99532c..262b2c3d7e 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -48,15 +48,15 @@ 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_bias[] = { + [STM32_GPIO_PUPD_NO] = "", + [STM32_GPIO_PUPD_UP] = "pull-up", + [STM32_GPIO_PUPD_DOWN] = "pull-down", }; static const char * const pinmux_input[] = { - [STM32_GPIO_OTYPE_PP] = "drive-push-pull", - [STM32_GPIO_OTYPE_OD] = "drive-open-drain", + [STM32_GPIO_OTYPE_PP] = "push-pull", + [STM32_GPIO_OTYPE_OD] = "open-drain", }; static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) @@ -213,6 +213,7 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", selector, gpio_idx, mode); priv = dev_get_priv(gpio_dev); + pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) & PUPD_MASK; switch (mode) { @@ -224,20 +225,19 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, break; case GPIOF_FUNC: af_num = stm32_pinctrl_get_af(gpio_dev, gpio_idx); - snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); + snprintf(buf, size, "%s %d %s", pinmux_mode[mode], af_num, + pinmux_bias[pupd]); 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], + pinmux_mode[mode], pinmux_bias[pupd], label ? label : ""); break; case GPIOF_INPUT: otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK; - snprintf(buf, size, "%s %s %s", + snprintf(buf, size, "%s %s %s %s", pinmux_mode[mode], pinmux_input[otype], - label ? label : ""); + pinmux_bias[pupd], label ? label : ""); break; } diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c index 33b574b1bd..dc87cb794e 100644 --- a/drivers/remoteproc/stm32_copro.c +++ b/drivers/remoteproc/stm32_copro.c @@ -8,30 +8,21 @@ #include <errno.h> #include <fdtdec.h> #include <log.h> -#include <regmap.h> #include <remoteproc.h> #include <reset.h> -#include <syscon.h> #include <asm/io.h> #include <dm/device_compat.h> #include <linux/err.h> -#define RCC_GCR_HOLD_BOOT 0 -#define RCC_GCR_RELEASE_BOOT 1 - /** * struct stm32_copro_privdata - power processor private data * @reset_ctl: reset controller handle - * @hold_boot_regmap: regmap for remote processor reset hold boot - * @hold_boot_offset: offset of the register controlling the hold boot setting - * @hold_boot_mask: bitmask of the register for the hold boot field + * @hold_boot: hold boot controller handle * @rsc_table_addr: resource table address */ struct stm32_copro_privdata { struct reset_ctl reset_ctl; - struct regmap *hold_boot_regmap; - uint hold_boot_offset; - uint hold_boot_mask; + struct reset_ctl hold_boot; ulong rsc_table_addr; }; @@ -43,32 +34,19 @@ struct stm32_copro_privdata { static int stm32_copro_probe(struct udevice *dev) { struct stm32_copro_privdata *priv; - struct regmap *regmap; - const fdt32_t *cell; - int len, ret; + int ret; priv = dev_get_priv(dev); - regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscfg-holdboot"); - if (IS_ERR(regmap)) { - dev_err(dev, "unable to find holdboot regmap (%ld)\n", - PTR_ERR(regmap)); - return PTR_ERR(regmap); - } - - cell = dev_read_prop(dev, "st,syscfg-holdboot", &len); - if (len < 3 * sizeof(fdt32_t)) { - dev_err(dev, "holdboot offset and mask not available\n"); - return -EINVAL; + ret = reset_get_by_name(dev, "mcu_rst", &priv->reset_ctl); + if (ret) { + dev_err(dev, "failed to get reset (%d)\n", ret); + return ret; } - priv->hold_boot_regmap = regmap; - priv->hold_boot_offset = fdtdec_get_number(cell + 1, 1); - priv->hold_boot_mask = fdtdec_get_number(cell + 2, 1); - - ret = reset_get_by_index(dev, 0, &priv->reset_ctl); + ret = reset_get_by_name(dev, "hold_boot", &priv->hold_boot); if (ret) { - dev_err(dev, "failed to get reset (%d)\n", ret); + dev_err(dev, "failed to get hold boot (%d)\n", ret); return ret; } @@ -78,35 +56,6 @@ static int stm32_copro_probe(struct udevice *dev) } /** - * stm32_copro_set_hold_boot() - Hold boot bit management - * @dev: corresponding STM32 remote processor device - * @hold: hold boot value - * @return 0 if all went ok, else corresponding -ve error - */ -static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold) -{ - struct stm32_copro_privdata *priv; - uint val; - int ret; - - priv = dev_get_priv(dev); - - val = hold ? RCC_GCR_HOLD_BOOT : RCC_GCR_RELEASE_BOOT; - - /* - * Note: shall run an SMC call (STM32_SMC_RCC) if platform is secured. - * To be updated when the code for this SMC service is available which - * is not the case for the time being. - */ - ret = regmap_update_bits(priv->hold_boot_regmap, priv->hold_boot_offset, - priv->hold_boot_mask, val); - if (ret) - dev_err(dev, "failed to set hold boot\n"); - - return ret; -} - -/** * stm32_copro_device_to_virt() - Convert device address to virtual address * @dev: corresponding STM32 remote processor device * @da: device address @@ -149,9 +98,11 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) priv = dev_get_priv(dev); - ret = stm32_copro_set_hold_boot(dev, true); - if (ret) + ret = reset_assert(&priv->hold_boot); + if (ret) { + dev_err(dev, "Unable to assert hold boot (ret=%d)\n", ret); return ret; + } ret = reset_assert(&priv->reset_ctl); if (ret) { @@ -180,23 +131,26 @@ static int stm32_copro_start(struct udevice *dev) priv = dev_get_priv(dev); - /* move hold boot from true to false start the copro */ - ret = stm32_copro_set_hold_boot(dev, false); - if (ret) + ret = reset_deassert(&priv->hold_boot); + if (ret) { + dev_err(dev, "Unable to deassert hold boot (ret=%d)\n", ret); return ret; + } /* * Once copro running, reset hold boot flag to avoid copro - * rebooting autonomously + * rebooting autonomously (error should never occur) */ - ret = stm32_copro_set_hold_boot(dev, true); - writel(ret ? TAMP_COPRO_STATE_OFF : TAMP_COPRO_STATE_CRUN, - TAMP_COPRO_STATE); - if (!ret) - /* Store rsc_address in bkp register */ - writel(priv->rsc_table_addr, TAMP_COPRO_RSC_TBL_ADDRESS); - - return ret; + ret = reset_assert(&priv->hold_boot); + if (ret) + dev_err(dev, "Unable to assert hold boot (ret=%d)\n", ret); + + /* indicates that copro is running */ + writel(TAMP_COPRO_STATE_CRUN, TAMP_COPRO_STATE); + /* Store rsc_address in bkp register */ + writel(priv->rsc_table_addr, TAMP_COPRO_RSC_TBL_ADDRESS); + + return 0; } /** @@ -211,9 +165,11 @@ static int stm32_copro_reset(struct udevice *dev) priv = dev_get_priv(dev); - ret = stm32_copro_set_hold_boot(dev, true); - if (ret) + ret = reset_assert(&priv->hold_boot); + if (ret) { + dev_err(dev, "Unable to assert hold boot (ret=%d)\n", ret); return ret; + } ret = reset_assert(&priv->reset_ctl); if (ret) { diff --git a/drivers/reset/stm32-reset.c b/drivers/reset/stm32-reset.c index 64a11cfcfc..20c36a99eb 100644 --- a/drivers/reset/stm32-reset.c +++ b/drivers/reset/stm32-reset.c @@ -14,6 +14,9 @@ #include <asm/io.h> #include <linux/bitops.h> +/* offset of register without set/clear management */ +#define RCC_MP_GCR_OFFSET 0x10C + /* reset clear offset for STM32MP RCC */ #define RCC_CL 0x4 @@ -40,8 +43,11 @@ static int stm32_reset_assert(struct reset_ctl *reset_ctl) reset_ctl->id, bank, offset); if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) - /* reset assert is done in rcc set register */ - writel(BIT(offset), priv->base + bank); + if (bank != RCC_MP_GCR_OFFSET) + /* reset assert is done in rcc set register */ + writel(BIT(offset), priv->base + bank); + else + clrbits_le32(priv->base + bank, BIT(offset)); else setbits_le32(priv->base + bank, BIT(offset)); @@ -57,8 +63,11 @@ static int stm32_reset_deassert(struct reset_ctl *reset_ctl) reset_ctl->id, bank, offset); if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) - /* reset deassert is done in rcc clr register */ - writel(BIT(offset), priv->base + bank + RCC_CL); + if (bank != RCC_MP_GCR_OFFSET) + /* reset deassert is done in rcc clr register */ + writel(BIT(offset), priv->base + bank + RCC_CL); + else + setbits_le32(priv->base + bank, BIT(offset)); else clrbits_le32(priv->base + bank, BIT(offset)); |