summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/stm32_gpio.c28
-rw-r--r--drivers/phy/phy-stm32-usbphyc.c33
-rw-r--r--drivers/pinctrl/pinctrl-stmfx.c13
-rw-r--r--drivers/pinctrl/pinctrl_stm32.c24
-rw-r--r--drivers/remoteproc/stm32_copro.c108
-rw-r--r--drivers/reset/stm32-reset.c17
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,
&regulator_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));