aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini2022-05-20 13:50:11 -0400
committerTom Rini2022-05-20 13:50:11 -0400
commit658d38e193073846af0514ca7c39d03c16b6cddc (patch)
treef1a876f98f336b18fbc5d60bdbea1197b2561d5c
parentf83bd23e2a0e9861969c9d43395299a14f25ddda (diff)
parentb6a469360a0dec01dbbf087c5184a59dda494569 (diff)
Merge tag 'u-boot-stm32-20220520' of https://source.denx.de/u-boot/custodians/u-boot-stm
- spi: fix busy bit check in stm32_qspi driver - stm32mp15: configure Buck3 voltage per PMIC NVM on Avenger96 board
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi2
-rw-r--r--board/dhelectronics/dh_stm32mp1/board.c109
-rw-r--r--drivers/spi/stm32_qspi.c27
3 files changed, 118 insertions, 20 deletions
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi
index 9937b28548c..e20917824bf 100644
--- a/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi
@@ -19,7 +19,7 @@
};
&vdd {
- regulator-min-microvolt = <2900000>;
+ regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2900000>;
};
diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c
index 67273f90992..d407f0bf592 100644
--- a/board/dhelectronics/dh_stm32mp1/board.c
+++ b/board/dhelectronics/dh_stm32mp1/board.c
@@ -594,14 +594,98 @@ static void board_init_fmc2(void)
setbits_le32(STM32_FMC2_BASE + STM32_FMC2_BCR1, STM32_FMC2_BCRx_FMCEN);
}
+#ifdef CONFIG_DM_REGULATOR
+#define STPMIC_NVM_BUCKS_VOUT_SHR 0xfc
+#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V2 0
+#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V8 1
+#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V0 2
+#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3 3
+#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_MASK GENMASK(1, 0)
+#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_OFFSET(n) ((((n) - 1) & 3) * 2)
+static int board_get_regulator_buck3_nvm_uv_av96(int *uv)
+{
+ const void *fdt = gd->fdt_blob;
+ struct udevice *dev;
+ u8 bucks_vout = 0;
+ const char *prop;
+ int len, ret;
+
+ /* Check whether this is Avenger96 board. */
+ prop = fdt_getprop(fdt, 0, "compatible", &len);
+ if (!prop || !len)
+ return -ENODEV;
+
+ if (!strstr(prop, "avenger96"))
+ return -EINVAL;
+
+ /* Read out STPMIC1 NVM and determine default Buck3 voltage. */
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_DRIVER_GET(stpmic1_nvm),
+ &dev);
+ if (ret)
+ return ret;
+
+ ret = misc_read(dev, STPMIC_NVM_BUCKS_VOUT_SHR, &bucks_vout, 1);
+ if (ret != 1)
+ return -EINVAL;
+
+ bucks_vout >>= STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_OFFSET(3);
+ bucks_vout &= STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_MASK;
+
+ /*
+ * Avenger96 board comes in multiple regulator configurations:
+ * - rev.100 or rev.200 have Buck3 preconfigured to 3V3 operation on
+ * boot and contains extra Enpirion EP53A8LQI DCDC converter which
+ * supplies the IO. Reduce Buck3 voltage to 2V9 to not waste power.
+ * - rev.200L have Buck3 preconfigured to 1V8 operation and have no
+ * Enpirion EP53A8LQI DCDC anymore, the IO is supplied from Buck3.
+ */
+ if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3)
+ *uv = 2900000;
+ else
+ *uv = 1800000;
+
+ return 0;
+}
+
+static void board_init_regulator_av96(void)
+{
+ struct udevice *rdev;
+ int ret, uv;
+
+ ret = board_get_regulator_buck3_nvm_uv_av96(&uv);
+ if (ret) /* Not Avenger96 board. */
+ return;
+
+ ret = regulator_get_by_devname("buck3", &rdev);
+ if (ret)
+ return;
+
+ /* Adjust Buck3 per preconfigured PMIC voltage from NVM. */
+ regulator_set_value(rdev, uv);
+}
+
+static void board_init_regulator(void)
+{
+ board_init_regulator_av96();
+
+ regulators_enable_boot_on(_DEBUG);
+}
+#else
+static inline int board_get_regulator_buck3_nvm_uv_av96(int *uv)
+{
+ return -EINVAL;
+}
+
+static inline void board_init_regulator(void) {}
+#endif
+
/* board dependent setup after realloc */
int board_init(void)
{
board_key_check();
-#ifdef CONFIG_DM_REGULATOR
- regulators_enable_boot_on(_DEBUG);
-#endif
+ board_init_regulator();
sysconf_init();
@@ -721,6 +805,25 @@ int board_interface_eth_init(struct udevice *dev,
#if defined(CONFIG_OF_BOARD_SETUP)
int ft_board_setup(void *blob, struct bd_info *bd)
{
+ const char *buck3path = "/soc/i2c@5c002000/stpmic@33/regulators/buck3";
+ int buck3off, ret, uv;
+
+ ret = board_get_regulator_buck3_nvm_uv_av96(&uv);
+ if (ret) /* Not Avenger96 board, do not patch Buck3 in DT. */
+ return 0;
+
+ buck3off = fdt_path_offset(blob, buck3path);
+ if (buck3off < 0) /* No Buck3 regulator found. */
+ return 0;
+
+ ret = fdt_setprop_u32(blob, buck3off, "regulator-min-microvolt", uv);
+ if (ret < 0)
+ return ret;
+
+ ret = fdt_setprop_u32(blob, buck3off, "regulator-max-microvolt", uv);
+ if (ret < 0)
+ return ret;
+
return 0;
}
#endif
diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
index 8f4aabc3d16..ceba413727e 100644
--- a/drivers/spi/stm32_qspi.c
+++ b/drivers/spi/stm32_qspi.c
@@ -150,20 +150,19 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv,
u32 sr;
int ret = 0;
- if (op->data.nbytes) {
- ret = readl_poll_timeout(&priv->regs->sr, sr,
- sr & STM32_QSPI_SR_TCF,
- STM32_QSPI_CMD_TIMEOUT_US);
- if (ret) {
- log_err("cmd timeout (stat:%#x)\n", sr);
- } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
- log_err("transfer error (stat:%#x)\n", sr);
- ret = -EIO;
- }
- /* clear flags */
- writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr);
+ ret = readl_poll_timeout(&priv->regs->sr, sr,
+ sr & STM32_QSPI_SR_TCF,
+ STM32_QSPI_CMD_TIMEOUT_US);
+ if (ret) {
+ log_err("cmd timeout (stat:%#x)\n", sr);
+ } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
+ log_err("transfer error (stat:%#x)\n", sr);
+ ret = -EIO;
}
+ /* clear flags */
+ writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr);
+
if (!ret)
ret = _stm32_qspi_wait_for_not_busy(priv);
@@ -256,10 +255,6 @@ static int stm32_qspi_exec_op(struct spi_slave *slave,
op->dummy.buswidth, op->data.buswidth,
op->addr.val, op->data.nbytes);
- ret = _stm32_qspi_wait_for_not_busy(priv);
- if (ret)
- return ret;
-
addr_max = op->addr.val + op->data.nbytes + 1;
if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes) {