Просмотр исходного кода

Merge tag 'u-boot-stm32-20200707' of https://gitlab.denx.de/u-boot/custodians/u-boot-stm

- arch and board update for stm32mp15:
  - use OPP information in device tree for 800MHz/650MHz support
  - ram: inprovments of test command
  - solve boot on closed chip when access to DBGMCU_IDC is protected
  - stm32prog command: Add "device anme" during USB enumeration
  - update configs: activate WATCHDOG and 'env erase' command,
    increase teed partition, support SD card after NOR boot by default and
    use env info in env_check
  - some sboard cleanups: gpio hog in dh board, specific driver for
    type-c stusb1600 controller code in a driver move part of code in spl.c
    and in common directory
- fix STM32 compatible for dwc_eth_qos driver
- support of new pinctrl ops get_dir_flags/set_dir_flags in stm32 and stmfx
  drivers
- vrefbuf: fix a possible overshoot when re-enabling
Tom Rini 3 лет назад
Родитель
Сommit
1e88e78177
39 измененных файлов с 1166 добавлено и 460 удалено
  1. 11 1
      arch/arm/dts/stm32mp15-u-boot.dtsi
  2. 21 0
      arch/arm/dts/stm32mp151.dtsi
  3. 0 9
      arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
  4. 0 9
      arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
  5. 8 0
      arch/arm/dts/stm32mp157c-ed1.dts
  6. 0 9
      arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
  7. 0 9
      arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi
  8. 8 0
      arch/arm/dts/stm32mp15xx-dkx.dtsi
  9. 1 1
      arch/arm/mach-stm32mp/Kconfig
  10. 1 1
      arch/arm/mach-stm32mp/Makefile
  11. 31 5
      arch/arm/mach-stm32mp/bsec.c
  12. 4 2
      arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c
  13. 18 4
      arch/arm/mach-stm32mp/cpu.c
  14. 7 0
      arch/arm/mach-stm32mp/include/mach/bsec.h
  15. 3 0
      arch/arm/mach-stm32mp/include/mach/sys_proto.h
  16. 1 5
      board/dhelectronics/dh_stm32mp1/Makefile
  17. 12 8
      board/dhelectronics/dh_stm32mp1/board.c
  18. 8 1
      board/st/common/Kconfig
  19. 3 0
      board/st/common/Makefile
  20. 216 0
      board/st/common/stpmic1.c
  21. 6 0
      board/st/common/stpmic1.h
  22. 46 0
      board/st/common/stusb160x.c
  23. 10 0
      board/st/common/stusb160x.h
  24. 0 2
      board/st/stm32mp1/Makefile
  25. 0 158
      board/st/stm32mp1/board.c
  26. 43 33
      board/st/stm32mp1/spl.c
  27. 14 60
      board/st/stm32mp1/stm32mp1.c
  28. 1 1
      cmd/nvedit.c
  29. 6 0
      configs/stm32mp15_basic_defconfig
  30. 5 0
      configs/stm32mp15_trusted_defconfig
  31. 4 0
      doc/device-tree-bindings/clock/st,stm32mp1.txt
  32. 267 28
      drivers/clk/clk_stm32mp1.c
  33. 135 14
      drivers/gpio/stm32_gpio.c
  34. 1 1
      drivers/net/dwc_eth_qos.c
  35. 162 63
      drivers/pinctrl/pinctrl-stmfx.c
  36. 24 3
      drivers/pinctrl/pinctrl_stm32.c
  37. 14 2
      drivers/power/regulator/stm32-vrefbuf.c
  38. 71 27
      drivers/ram/stm32mp1/stm32mp1_tests.c
  39. 4 4
      include/configs/stm32mp1.h

+ 11 - 1
arch/arm/dts/stm32mp15-u-boot.dtsi

@@ -65,7 +65,7 @@
 };
 
 &bsec {
-	u-boot,dm-pre-proper;
+	u-boot,dm-pre-reloc;
 };
 
 &clk_csi {
@@ -88,6 +88,16 @@
 	u-boot,dm-pre-reloc;
 };
 
+&cpu0_opp_table {
+	u-boot,dm-spl;
+	opp-650000000 {
+		u-boot,dm-spl;
+	};
+	opp-800000000 {
+		u-boot,dm-spl;
+	};
+};
+
 &gpioa {
 	u-boot,dm-pre-reloc;
 };

+ 21 - 0
arch/arm/dts/stm32mp151.dtsi

@@ -20,6 +20,24 @@
 			clock-frequency = <650000000>;
 			device_type = "cpu";
 			reg = <0>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			nvmem-cells = <&part_number_otp>;
+			nvmem-cell-names = "part_number";
+		};
+	};
+
+	cpu0_opp_table: cpu0-opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+		opp-650000000 {
+			opp-hz = /bits/ 64 <650000000>;
+			opp-microvolt = <1200000>;
+			opp-supported-hw = <0x1>;
+		};
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <1350000>;
+			opp-supported-hw = <0x2>;
 		};
 	};
 
@@ -1522,6 +1540,9 @@
 			reg = <0x5c005000 0x400>;
 			#address-cells = <1>;
 			#size-cells = <1>;
+			part_number_otp: part_number_otp@4 {
+				reg = <0x4 0x1>;
+			};
 			ts_cal1: calib@5c {
 				reg = <0x5c 0x2>;
 			};

+ 0 - 9
arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi

@@ -133,15 +133,6 @@
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
-		u-boot,dm-pre-reloc;
-	};
-
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";

+ 0 - 9
arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi

@@ -129,15 +129,6 @@
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
-		u-boot,dm-pre-reloc;
-	};
-
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";

+ 8 - 0
arch/arm/dts/stm32mp157c-ed1.dts

@@ -107,6 +107,14 @@
 	};
 };
 
+&cpu0{
+	cpu-supply = <&vddcore>;
+};
+
+&cpu1{
+	cpu-supply = <&vddcore>;
+};
+
 &dac {
 	pinctrl-names = "default";
 	pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>;

+ 0 - 9
arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi

@@ -235,15 +235,6 @@
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
-		u-boot,dm-pre-reloc;
-	};
-
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";

+ 0 - 9
arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi

@@ -114,15 +114,6 @@
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
-		u-boot,dm-pre-reloc;
-	};
-
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";

+ 8 - 0
arch/arm/dts/stm32mp15xx-dkx.dtsi

@@ -116,6 +116,14 @@
 	status = "okay";
 };
 
+&cpu0{
+	cpu-supply = <&vddcore>;
+};
+
+&cpu1{
+	cpu-supply = <&vddcore>;
+};
+
 &ethernet0 {
 	status = "okay";
 	pinctrl-0 = <&ethernet0_rgmii_pins_a>;

+ 1 - 1
arch/arm/mach-stm32mp/Kconfig

@@ -1,7 +1,6 @@
 if ARCH_STM32MP
 
 config SPL
-	select SPL_BOARD_INIT
 	select SPL_CLK
 	select SPL_DM
 	select SPL_DM_SEQ_ALIAS
@@ -46,6 +45,7 @@ config STM32MP15x
 	select STM32_RESET
 	select STM32_SERIAL
 	select SYS_ARCH_TIMER
+	imply CMD_NVEDIT_INFO
 	imply SYSRESET_PSCI if TFABOOT
 	imply SYSRESET_SYSCON if !TFABOOT
 	help

+ 1 - 1
arch/arm/mach-stm32mp/Makefile

@@ -6,12 +6,12 @@
 obj-y += cpu.o
 obj-y += dram_init.o
 obj-y += syscon.o
+obj-y += bsec.o
 
 ifdef CONFIG_SPL_BUILD
 obj-y += spl.o
 else
 obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/
-obj-y += bsec.o
 obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o
 obj-$(CONFIG_ARMV7_PSCI) += psci.o
 obj-$(CONFIG_TFABOOT) += boot_params.o

+ 31 - 5
arch/arm/mach-stm32mp/bsec.c

@@ -8,6 +8,7 @@
 #include <log.h>
 #include <misc.h>
 #include <asm/io.h>
+#include <asm/arch/bsec.h>
 #include <asm/arch/stm32mp1_smc.h>
 #include <linux/arm-smccc.h>
 #include <linux/iopoll.h>
@@ -21,6 +22,7 @@
 #define BSEC_OTP_WRDATA_OFF		0x008
 #define BSEC_OTP_STATUS_OFF		0x00C
 #define BSEC_OTP_LOCK_OFF		0x010
+#define BSEC_DENABLE_OFF		0x014
 #define BSEC_DISTURBED_OFF		0x01C
 #define BSEC_ERROR_OFF			0x034
 #define BSEC_WRLOCK_OFF			0x04C /* OTP write permananet lock */
@@ -46,6 +48,9 @@
 #define BSEC_MODE_PROGFAIL_MASK		0x10
 #define BSEC_MODE_PWR_MASK		0x20
 
+/* DENABLE Register */
+#define BSEC_DENABLE_DBGSWENABLE	BIT(10)
+
 /*
  * OTP Lock services definition
  * Value must corresponding to the bit number in the register
@@ -474,20 +479,23 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev)
 	return 0;
 }
 
-#ifndef CONFIG_TFABOOT
 static int stm32mp_bsec_probe(struct udevice *dev)
 {
+#if !defined(CONFIG_TFABOOT) && !defined(CONFIG_SPL_BUILD)
 	int otp;
 	struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
 
-	/* update unlocked shadow for OTP cleared by the rom code */
+	/*
+	 * update unlocked shadow for OTP cleared by the rom code
+	 * only executed in U-Boot proper when TF-A is not used
+	 */
 	for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++)
 		if (!bsec_read_SR_lock(plat->base, otp))
 			bsec_shadow_register(plat->base, otp);
+#endif
 
 	return 0;
 }
-#endif
 
 static const struct udevice_id stm32mp_bsec_ids[] = {
 	{ .compatible = "st,stm32mp15-bsec" },
@@ -501,7 +509,25 @@ U_BOOT_DRIVER(stm32mp_bsec) = {
 	.ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
 	.platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
 	.ops = &stm32mp_bsec_ops,
-#ifndef CONFIG_TFABOOT
 	.probe = stm32mp_bsec_probe,
-#endif
 };
+
+bool bsec_dbgswenable(void)
+{
+	struct udevice *dev;
+	struct stm32mp_bsec_platdata *plat;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(stm32mp_bsec), &dev);
+	if (ret || !dev) {
+		pr_debug("bsec driver not available\n");
+		return false;
+	}
+
+	plat = dev_get_platdata(dev);
+	if (readl(plat->base + BSEC_DENABLE_OFF) & BSEC_DENABLE_DBGSWENABLE)
+		return true;
+
+	return false;
+}

+ 4 - 2
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c

@@ -197,10 +197,12 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev)
 	bool result;
 	/* USB download gadget for STM32 Programmer */
 	char product[128];
+	char name[SOC_NAME_SIZE];
 
+	get_soc_name(name);
 	snprintf(product, sizeof(product),
-		 "USB download gadget@Device ID /0x%03X, @Revision ID /0x%04X",
-		 get_cpu_dev(), get_cpu_rev());
+		 "USB download gadget@Device ID /0x%03X, @Revision ID /0x%04X, @Name /%s,",
+		 get_cpu_dev(), get_cpu_rev(), name);
 	g_dnl_set_product(product);
 
 	if (stm32prog_data->phase == PHASE_FLASHLAYOUT) {

+ 18 - 4
arch/arm/mach-stm32mp/cpu.c

@@ -12,6 +12,7 @@
 #include <misc.h>
 #include <net.h>
 #include <asm/io.h>
+#include <asm/arch/bsec.h>
 #include <asm/arch/stm32.h>
 #include <asm/arch/sys_proto.h>
 #include <dm/device.h>
@@ -155,8 +156,13 @@ static void dbgmcu_init(void)
 {
 	setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN);
 
-	/* Freeze IWDG2 if Cortex-A7 is in debug mode */
-	setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2);
+	/*
+	 * Freeze IWDG2 if Cortex-A7 is in debug mode
+	 * done in TF-A for TRUSTED boot and
+	 * DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE
+	*/
+	if (!IS_ENABLED(CONFIG_TFABOOT) && bsec_dbgswenable())
+		setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2);
 }
 #endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */
 
@@ -276,9 +282,17 @@ void enable_caches(void)
 
 static u32 read_idc(void)
 {
-	setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN);
+	/* DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE */
+	if (bsec_dbgswenable()) {
+		setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN);
 
-	return readl(DBGMCU_IDC);
+		return readl(DBGMCU_IDC);
+	}
+
+	if (CONFIG_IS_ENABLED(STM32MP15x))
+		return CPU_DEV_STM32MP15; /* STM32MP15x and unknown revision */
+	else
+		return 0x0;
 }
 
 u32 get_cpu_dev(void)

+ 7 - 0
arch/arm/mach-stm32mp/include/mach/bsec.h

@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
+ */
+
+/* check self hosted debug status = BSEC_DENABLE.DBGSWENABLE */
+bool bsec_dbgswenable(void);

+ 3 - 0
arch/arm/mach-stm32mp/include/mach/sys_proto.h

@@ -48,3 +48,6 @@ void get_soc_name(char name[SOC_NAME_SIZE]);
 u32 get_bootmode(void);
 
 int setup_mac_address(void);
+
+/* board power management : configure vddcore according OPP */
+void board_vddcore_init(u32 voltage_mv);

+ 1 - 5
board/dhelectronics/dh_stm32mp1/Makefile

@@ -3,11 +3,7 @@
 # Copyright (C) 2018, STMicroelectronics - All Rights Reserved
 #
 
-ifdef CONFIG_SPL_BUILD
-obj-y += ../../st/stm32mp1/spl.o
-endif
-
-obj-y += ../../st/stm32mp1/board.o board.o
+obj-y += ../../st/common/stpmic1.o board.o
 
 obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += ../../st/common/stm32mp_mtdparts.o
 obj-$(CONFIG_SET_DFU_ALT_INFO) += ../../st/common/stm32mp_dfu.o

+ 12 - 8
board/dhelectronics/dh_stm32mp1/board.c

@@ -41,6 +41,7 @@
 #include <usb.h>
 #include <usb/dwc2_udc.h>
 #include <watchdog.h>
+#include "../../st/common/stpmic1.h"
 
 /* SYSCFG registers */
 #define SYSCFG_BOOTR		0x00
@@ -139,6 +140,7 @@ int checkboard(void)
 static u8 brdcode __section("data");
 static u8 ddr3code __section("data");
 static u8 somcode __section("data");
+static u32 opp_voltage_mv __section(".data");
 
 static void board_get_coding_straps(void)
 {
@@ -196,8 +198,16 @@ int board_stm32mp1_ddr_config_name_match(struct udevice *dev,
 	return -EINVAL;
 }
 
+void board_vddcore_init(u32 voltage_mv)
+{
+	if (IS_ENABLED(CONFIG_SPL_BUILD))
+		opp_voltage_mv = voltage_mv;
+}
+
 int board_early_init_f(void)
 {
+	if (IS_ENABLED(CONFIG_SPL_BUILD))
+		stpmic1_init(opp_voltage_mv);
 	board_get_coding_straps();
 
 	return 0;
@@ -513,17 +523,11 @@ static void board_init_fmc2(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();
 

+ 8 - 1
board/st/common/Kconfig

@@ -39,7 +39,7 @@ config MTDPARTS_NOR0_BOOT
 
 config MTDPARTS_NOR0_TEE
 	string "mtd tee partitions for nor0"
-	default "256k(teeh),256k(teed),256k(teex)"
+	default "256k(teeh),512k(teed),256k(teex)"
 	depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP
 	help
 	  This define the tee partitions added in mtparts dynamically
@@ -69,3 +69,10 @@ config DFU_ALT_RAM0
 	depends on ARCH_STM32MP && SET_DFU_ALT_INFO
 	help
 	  This defines the partitions of ram used to build dfu dynamically.
+
+config TYPEC_STUSB160X
+	tristate "STMicroelectronics STUSB160X Type-C controller driver"
+	depends on DM_I2C
+	help
+	  Say Y if your system has STMicroelectronics STUSB160X Type-C port
+	  controller.

+ 3 - 0
board/st/common/Makefile

@@ -4,8 +4,11 @@
 #
 
 obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o
+obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
 
 ifeq ($(CONFIG_ARCH_STM32MP),y)
 obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += stm32mp_mtdparts.o
 obj-$(CONFIG_SET_DFU_ALT_INFO) += stm32mp_dfu.o
 endif
+
+obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o

+ 216 - 0
board/st/common/stpmic1.c

@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/ddr.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <power/pmic.h>
+#include <power/stpmic1.h>
+
+int board_ddr_power_init(enum ddr_type ddr_type)
+{
+	struct udevice *dev;
+	bool buck3_at_1800000v = false;
+	int ret;
+	u32 buck2;
+
+	ret = uclass_get_device_by_driver(UCLASS_PMIC,
+					  DM_GET_DRIVER(pmic_stpmic1), &dev);
+	if (ret)
+		/* No PMIC on board */
+		return 0;
+
+	switch (ddr_type) {
+	case STM32MP_DDR3:
+		/* VTT = Set LDO3 to sync mode */
+		ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
+		if (ret < 0)
+			return ret;
+
+		ret &= ~STPMIC1_LDO3_MODE;
+		ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+		ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
+
+		ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+				     ret);
+		if (ret < 0)
+			return ret;
+
+		/* VDD_DDR = Set BUCK2 to 1.35V */
+		ret = pmic_clrsetbits(dev,
+				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+				      STPMIC1_BUCK_VOUT_MASK,
+				      STPMIC1_BUCK2_1350000V);
+		if (ret < 0)
+			return ret;
+
+		/* Enable VDD_DDR = BUCK2 */
+		ret = pmic_clrsetbits(dev,
+				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+				      STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
+		if (ret < 0)
+			return ret;
+
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+		/* Enable VREF */
+		ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
+				      STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
+		if (ret < 0)
+			return ret;
+
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+		/* Enable VTT = LDO3 */
+		ret = pmic_clrsetbits(dev,
+				      STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+				      STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
+		if (ret < 0)
+			return ret;
+
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+		break;
+
+	case STM32MP_LPDDR2_16:
+	case STM32MP_LPDDR2_32:
+	case STM32MP_LPDDR3_16:
+	case STM32MP_LPDDR3_32:
+		/*
+		 * configure VDD_DDR1 = LDO3
+		 * Set LDO3 to 1.8V
+		 * + bypass mode if BUCK3 = 1.8V
+		 * + normal mode if BUCK3 != 1.8V
+		 */
+		ret = pmic_reg_read(dev,
+				    STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3));
+		if (ret < 0)
+			return ret;
+
+		if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V)
+			buck3_at_1800000v = true;
+
+		ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
+		if (ret < 0)
+			return ret;
+
+		ret &= ~STPMIC1_LDO3_MODE;
+		ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+		ret |= STPMIC1_LDO3_1800000;
+		if (buck3_at_1800000v)
+			ret |= STPMIC1_LDO3_MODE;
+
+		ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+				     ret);
+		if (ret < 0)
+			return ret;
+
+		/* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/
+		switch (ddr_type) {
+		case STM32MP_LPDDR2_32:
+		case STM32MP_LPDDR3_32:
+			buck2 = STPMIC1_BUCK2_1250000V;
+			break;
+		default:
+		case STM32MP_LPDDR2_16:
+		case STM32MP_LPDDR3_16:
+			buck2 = STPMIC1_BUCK2_1200000V;
+			break;
+		}
+
+		ret = pmic_clrsetbits(dev,
+				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+				      STPMIC1_BUCK_VOUT_MASK,
+				      buck2);
+		if (ret < 0)
+			return ret;
+
+		/* Enable VDD_DDR1 = LDO3 */
+		ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+				      STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
+		if (ret < 0)
+			return ret;
+
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+		/* Enable VDD_DDR2 =BUCK2 */
+		ret = pmic_clrsetbits(dev,
+				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+				      STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
+		if (ret < 0)
+			return ret;
+
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+		/* Enable VREF */
+		ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
+				      STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
+		if (ret < 0)
+			return ret;
+
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+		break;
+
+	default:
+		break;
+	};
+
+	return 0;
+}
+
+static int stmpic_buck1_set(struct udevice *dev, u32 voltage_mv)
+{
+	u32 value;
+
+	/* VDDCORE= STMPCI1 BUCK1 ramp=+25mV, 5 => 725mV, 36 => 1500mV */
+	value = ((voltage_mv - 725) / 25) + 5;
+	if (value < 5)
+		value = 5;
+	if (value > 36)
+		value = 36;
+
+	return pmic_clrsetbits(dev,
+			       STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK1),
+			       STPMIC1_BUCK_VOUT_MASK,
+			       STPMIC1_BUCK_VOUT(value));
+}
+
+/* early init of PMIC */
+void stpmic1_init(u32 voltage_mv)
+{
+	struct udevice *dev;
+
+	if (uclass_get_device_by_driver(UCLASS_PMIC,
+					DM_GET_DRIVER(pmic_stpmic1), &dev))
+		return;
+
+	/* update VDDCORE = BUCK1 */
+	if (voltage_mv)
+		stmpic_buck1_set(dev, voltage_mv);
+
+	/* Keep vdd on during the reset cycle */
+	pmic_clrsetbits(dev,
+			STPMIC1_BUCKS_MRST_CR,
+			STPMIC1_MRST_BUCK(STPMIC1_BUCK3),
+			STPMIC1_MRST_BUCK(STPMIC1_BUCK3));
+
+	/* Check if debug is enabled to program PMIC according to the bit */
+	if (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) {
+		printf("Keep debug unit ON\n");
+
+		pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR,
+				STPMIC1_MRST_BUCK_DEBUG,
+				STPMIC1_MRST_BUCK_DEBUG);
+
+		if (STPMIC1_MRST_LDO_DEBUG)
+			pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR,
+					STPMIC1_MRST_LDO_DEBUG,
+					STPMIC1_MRST_LDO_DEBUG);
+	}
+}

+ 6 - 0
board/st/common/stpmic1.h

@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
+ */
+
+void stpmic1_init(u32 voltage_mv);

+ 46 - 0
board/st/common/stusb160x.c

@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * STMicroelectronics STUSB Type-C controller driver
+ * based on Linux drivers/usb/typec/stusb160x.c
+ *
+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+
+/* REGISTER */
+#define STUSB160X_CC_CONNECTION_STATUS		0x0E
+
+/* STUSB160X_CC_CONNECTION_STATUS bitfields */
+#define STUSB160X_CC_ATTACH			BIT(0)
+
+int stusb160x_cable_connected(void)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_I2C_GENERIC,
+					  DM_GET_DRIVER(stusb160x),
+					  &dev);
+	if (ret < 0)
+		return ret;
+
+	ret = dm_i2c_reg_read(dev, STUSB160X_CC_CONNECTION_STATUS);
+	if (ret < 0)
+		return 0;
+
+	return ret & STUSB160X_CC_ATTACH;
+}
+
+static const struct udevice_id stusb160x_ids[] = {
+	{ .compatible = "st,stusb1600" },
+	{}
+};
+
+U_BOOT_DRIVER(stusb160x) = {
+	.name = "stusb160x",
+	.id = UCLASS_I2C_GENERIC,
+	.of_match = stusb160x_ids,
+};

+ 10 - 0
board/st/common/stusb160x.h

@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020, STMicroelectronics
+ */
+
+#ifdef CONFIG_TYPEC_STUSB160X
+int stusb160x_cable_connected(void);
+#else
+int stusb160x_cable_connected(void) { return -ENODEV; }
+#endif

+ 0 - 2
board/st/stm32mp1/Makefile

@@ -8,5 +8,3 @@ obj-y += spl.o
 else
 obj-y += stm32mp1.o
 endif
-
-obj-y += board.o

+ 0 - 158
board/st/stm32mp1/board.c

@@ -4,13 +4,9 @@
  */
 
 #include <common.h>
-#include <dm.h>
 #include <asm/io.h>
-#include <asm/arch/ddr.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
-#include <power/pmic.h>
-#include <power/stpmic1.h>
 
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 void board_debug_uart_init(void)
@@ -38,157 +34,3 @@ void board_debug_uart_init(void)
 #endif
 }
 #endif
-
-#ifdef CONFIG_PMIC_STPMIC1
-int board_ddr_power_init(enum ddr_type ddr_type)
-{
-	struct udevice *dev;
-	bool buck3_at_1800000v = false;
-	int ret;
-	u32 buck2;
-
-	ret = uclass_get_device_by_driver(UCLASS_PMIC,
-					  DM_GET_DRIVER(pmic_stpmic1), &dev);
-	if (ret)
-		/* No PMIC on board */
-		return 0;
-
-	switch (ddr_type) {
-	case STM32MP_DDR3:
-		/* VTT = Set LDO3 to sync mode */
-		ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
-		if (ret < 0)
-			return ret;
-
-		ret &= ~STPMIC1_LDO3_MODE;
-		ret &= ~STPMIC1_LDO12356_VOUT_MASK;
-		ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
-
-		ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
-				     ret);
-		if (ret < 0)
-			return ret;
-
-		/* VDD_DDR = Set BUCK2 to 1.35V */
-		ret = pmic_clrsetbits(dev,
-				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
-				      STPMIC1_BUCK_VOUT_MASK,
-				      STPMIC1_BUCK2_1350000V);
-		if (ret < 0)
-			return ret;
-
-		/* Enable VDD_DDR = BUCK2 */
-		ret = pmic_clrsetbits(dev,
-				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
-				      STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
-		if (ret < 0)
-			return ret;
-
-		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-		/* Enable VREF */
-		ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
-				      STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
-		if (ret < 0)
-			return ret;
-
-		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-		/* Enable VTT = LDO3 */
-		ret = pmic_clrsetbits(dev,
-				      STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
-				      STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
-		if (ret < 0)
-			return ret;
-
-		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-		break;
-
-	case STM32MP_LPDDR2_16:
-	case STM32MP_LPDDR2_32:
-	case STM32MP_LPDDR3_16:
-	case STM32MP_LPDDR3_32:
-		/*
-		 * configure VDD_DDR1 = LDO3
-		 * Set LDO3 to 1.8V
-		 * + bypass mode if BUCK3 = 1.8V
-		 * + normal mode if BUCK3 != 1.8V
-		 */
-		ret = pmic_reg_read(dev,
-				    STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3));
-		if (ret < 0)
-			return ret;
-
-		if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V)
-			buck3_at_1800000v = true;
-
-		ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
-		if (ret < 0)
-			return ret;
-
-		ret &= ~STPMIC1_LDO3_MODE;
-		ret &= ~STPMIC1_LDO12356_VOUT_MASK;
-		ret |= STPMIC1_LDO3_1800000;
-		if (buck3_at_1800000v)
-			ret |= STPMIC1_LDO3_MODE;
-
-		ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
-				     ret);
-		if (ret < 0)
-			return ret;
-
-		/* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/
-		switch (ddr_type) {
-		case STM32MP_LPDDR2_32:
-		case STM32MP_LPDDR3_32:
-			buck2 = STPMIC1_BUCK2_1250000V;
-			break;
-		default:
-		case STM32MP_LPDDR2_16:
-		case STM32MP_LPDDR3_16:
-			buck2 = STPMIC1_BUCK2_1200000V;
-			break;
-		}
-
-		ret = pmic_clrsetbits(dev,
-				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
-				      STPMIC1_BUCK_VOUT_MASK,
-				      buck2);
-		if (ret < 0)
-			return ret;
-
-		/* Enable VDD_DDR1 = LDO3 */
-		ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
-				      STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
-		if (ret < 0)
-			return ret;
-
-		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-		/* Enable VDD_DDR2 =BUCK2 */
-		ret = pmic_clrsetbits(dev,
-				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
-				      STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
-		if (ret < 0)
-			return ret;
-
-		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-		/* Enable VREF */
-		ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
-				      STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
-		if (ret < 0)
-			return ret;
-
-		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
-		break;
-
-	default:
-		break;
-	};
-
-	return 0;
-}
-#endif

+ 43 - 33
board/st/stm32mp1/spl.c

@@ -5,41 +5,51 @@
 
 #include <config.h>
 #include <common.h>
-#include <spl.h>
-#include <dm.h>
-#include <ram.h>
+#include <init.h>
 #include <asm/io.h>
-#include <power/pmic.h>
-#include <power/stpmic1.h>
-#include <asm/arch/ddr.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include "../common/stpmic1.h"
 
-void spl_board_init(void)
+/* board early initialisation in board_f: need to use global variable */
+static u32 opp_voltage_mv __section(".data");
+
+void board_vddcore_init(u32 voltage_mv)
+{
+	if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER_SUPPORT))
+		opp_voltage_mv = voltage_mv;
+}
+
+int board_early_init_f(void)
+{
+	if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER_SUPPORT))
+		stpmic1_init(opp_voltage_mv);
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
 {
-	/* Keep vdd on during the reset cycle */
-#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT)
-	struct udevice *dev;
-	int ret;
-
-	ret = uclass_get_device_by_driver(UCLASS_PMIC,
-					  DM_GET_DRIVER(pmic_stpmic1), &dev);
-	if (!ret)
-		pmic_clrsetbits(dev,
-				STPMIC1_BUCKS_MRST_CR,
-				STPMIC1_MRST_BUCK(STPMIC1_BUCK3),
-				STPMIC1_MRST_BUCK(STPMIC1_BUCK3));
-
-	/* Check if debug is enabled to program PMIC according to the bit */
-	if ((readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) && !ret) {
-		printf("Keep debug unit ON\n");
-
-		pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR,
-				STPMIC1_MRST_BUCK_DEBUG,
-				STPMIC1_MRST_BUCK_DEBUG);
-
-		if (STPMIC1_MRST_LDO_DEBUG)
-			pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR,
-					STPMIC1_MRST_LDO_DEBUG,
-					STPMIC1_MRST_LDO_DEBUG);
-	}
+#if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE)
+
+#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00)
+#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28)
+
+	/* UART4 clock enable */
+	setbits_le32(RCC_MP_APB1ENSETR, BIT(16));
+
+#define GPIOG_BASE 0x50008000
+	/* GPIOG clock enable */
+	writel(BIT(6), RCC_MP_AHB4ENSETR);
+	/* GPIO configuration for ST boards: Uart4 TX = G11 */
+	writel(0xffbfffff, GPIOG_BASE + 0x00);
+	writel(0x00006000, GPIOG_BASE + 0x24);
+#else
+
+#error("CONFIG_DEBUG_UART_BASE: not supported value")
+
 #endif
 }
+#endif

+ 14 - 60
board/st/stm32mp1/stm32mp1.c

@@ -41,6 +41,8 @@
 #include <power/regulator.h>
 #include <usb/dwc2_udc.h>
 
+#include "../../st/common/stusb160x.h"
+
 /* SYSCFG registers */
 #define SYSCFG_BOOTR		0x00
 #define SYSCFG_PMCSETR		0x04
@@ -84,6 +86,12 @@ DECLARE_GLOBAL_DATA_PTR;
 #define USB_START_LOW_THRESHOLD_UV	1230000
 #define USB_START_HIGH_THRESHOLD_UV	2150000
 
+int board_early_init_f(void)
+{
+	/* nothing to do, only used in SPL */
+	return 0;
+}
+
 int checkboard(void)
 {
 	int ret;
@@ -175,64 +183,16 @@ static void board_key_check(void)
 }
 
 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
-
-/* STMicroelectronics STUSB1600 Type-C controller */
-#define STUSB1600_CC_CONNECTION_STATUS		0x0E
-
-/* STUSB1600_CC_CONNECTION_STATUS bitfields */
-#define STUSB1600_CC_ATTACH			BIT(0)
-
-static int stusb1600_init(struct udevice **dev_stusb1600)
-{
-	ofnode node;
-	struct udevice *dev, *bus;
-	int ret;
-	u32 chip_addr;
-
-	*dev_stusb1600 = NULL;
-
-	/* if node stusb1600 is present, means DK1 or DK2 board */
-	node = ofnode_by_compatible(ofnode_null(), "st,stusb1600");
-	if (!ofnode_valid(node))
-		return -ENODEV;
-
-	ret = ofnode_read_u32(node, "reg", &chip_addr);
-	if (ret)
-		return -EINVAL;
-
-	ret = uclass_get_device_by_ofnode(UCLASS_I2C, ofnode_get_parent(node),
-					  &bus);
-	if (ret) {
-		printf("bus for stusb1600 not found\n");
-		return -ENODEV;
-	}
-
-	ret = dm_i2c_probe(bus, chip_addr, 0, &dev);
-	if (!ret)
-		*dev_stusb1600 = dev;
-
-	return ret;
-}
-
-static int stusb1600_cable_connected(struct udevice *dev)
-{
-	u8 status;
-
-	if (dm_i2c_read(dev, STUSB1600_CC_CONNECTION_STATUS, &status, 1))
-		return 0;
-
-	return status & STUSB1600_CC_ATTACH;
-}
-
 #include <usb/dwc2_udc.h>
 int g_dnl_board_usb_cable_connected(void)
 {
-	struct udevice *stusb1600;
 	struct udevice *dwc2_udc_otg;
 	int ret;
 
-	if (!stusb1600_init(&stusb1600))
-		return stusb1600_cable_connected(stusb1600);
+	/* if typec stusb160x is present, means DK1 or DK2 board */
+	ret = stusb160x_cable_connected();
+	if (ret >= 0)
+		return ret;
 
 	ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC,
 					  DM_GET_DRIVER(dwc2_udc_otg),
@@ -664,17 +624,11 @@ static void board_ev1_init(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();
 

+ 1 - 1
cmd/nvedit.c

@@ -1265,7 +1265,7 @@ static int do_env_info(struct cmd_tbl *cmdtp, int flag,
 
 	/* evaluate whether environment can be persisted */
 	if (eval_flags & ENV_INFO_IS_PERSISTED) {
-#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
+#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
 		printf("Environment can be persisted\n");
 		eval_results |= ENV_INFO_IS_PERSISTED;
 #else

+ 6 - 0
configs/stm32mp15_basic_defconfig

@@ -10,6 +10,7 @@ CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL=y
 CONFIG_TARGET_ST_STM32MP15x=y
 CONFIG_CMD_STM32PROG=y
+CONFIG_TYPEC_STUSB160X=y
 CONFIG_ENV_OFFSET_REDUND=0x2C0000
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
@@ -18,6 +19,7 @@ CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1"
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_FIT=y
 CONFIG_BOOTCOMMAND="run bootcmd_stm32mp"
+CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3
 CONFIG_SPL_I2C_SUPPORT=y
@@ -29,6 +31,7 @@ CONFIG_SYS_PROMPT="STM32MP> "
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
 CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_MEMTEST_START=0xc0000000
@@ -75,6 +78,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
@@ -142,5 +146,7 @@ CONFIG_VIDEO_STM32=y
 CONFIG_VIDEO_STM32_DSI=y
 CONFIG_VIDEO_STM32_MAX_XRES=1280
 CONFIG_VIDEO_STM32_MAX_YRES=800
+CONFIG_WDT=y
+CONFIG_WDT_STM32MP=y
 CONFIG_ERRNO_STR=y
 CONFIG_FDT_FIXUP_PARTITIONS=y

+ 5 - 0
configs/stm32mp15_trusted_defconfig

@@ -6,6 +6,7 @@ CONFIG_ENV_OFFSET=0x280000
 CONFIG_ENV_SECT_SIZE=0x40000
 CONFIG_TARGET_ST_STM32MP15x=y
 CONFIG_CMD_STM32PROG=y
+CONFIG_TYPEC_STUSB160X=y
 CONFIG_ENV_OFFSET_REDUND=0x2C0000
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_FIT=y
@@ -14,6 +15,7 @@ CONFIG_SYS_PROMPT="STM32MP> "
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
 CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_MEMTEST_START=0xc0000000
@@ -59,6 +61,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
@@ -127,5 +130,7 @@ CONFIG_VIDEO_STM32=y
 CONFIG_VIDEO_STM32_DSI=y
 CONFIG_VIDEO_STM32_MAX_XRES=1280
 CONFIG_VIDEO_STM32_MAX_YRES=800
+CONFIG_WDT=y
+CONFIG_WDT_STM32MP=y
 CONFIG_ERRNO_STR=y
 CONFIG_FDT_FIXUP_PARTITIONS=y

+ 4 - 0
doc/device-tree-bindings/clock/st,stm32mp1.txt

@@ -87,6 +87,10 @@ Optional Properties:
   are listed with associated reg 0 to 3.
   PLLx is off when the associated node is absent or deactivated.
 
+  For PLL1, when the node is absent, the frequency of the OPP node is used
+  to compute the PLL setting (see compatible "operating-points-v2" in
+  opp/opp.txt for details).
+
   Here are the available properties for each PLL node:
     - compatible: should be "st,stm32mp1-pll"
 

+ 267 - 28
drivers/clk/clk_stm32mp1.c

@@ -17,6 +17,7 @@
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <asm/arch/sys_proto.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <dt-bindings/clock/stm32mp1-clksrc.h>
 
@@ -644,8 +645,18 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
 };
 
 #ifdef STM32MP1_CLOCK_TREE_INIT
+
 /* define characteristic of PLL according type */
+#define DIVM_MIN	0
+#define DIVM_MAX	63
 #define DIVN_MIN	24
+#define DIVP_MIN	0
+#define DIVP_MAX	127
+#define FRAC_MAX	8192
+
+#define PLL1600_VCO_MIN	800000000
+#define PLL1600_VCO_MAX	1600000000
+
 static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
 	[PLL_800] = {
 		.refclk_min = 4,
@@ -1190,6 +1201,213 @@ static ulong stm32mp1_clk_get_rate(struct clk *clk)
 }
 
 #ifdef STM32MP1_CLOCK_TREE_INIT
+
+bool stm32mp1_supports_opp(u32 opp_id, u32 cpu_type)
+{
+	unsigned int id;
+
+	switch (opp_id) {
+	case 1:
+	case 2:
+		id = opp_id;
+		break;
+	default:
+		id = 1; /* default value */
+		break;
+	}
+
+	switch (cpu_type) {
+	case CPU_STM32MP157Fxx:
+	case CPU_STM32MP157Dxx:
+	case CPU_STM32MP153Fxx:
+	case CPU_STM32MP153Dxx:
+	case CPU_STM32MP151Fxx:
+	case CPU_STM32MP151Dxx:
+		return true;
+	default:
+		return id == 1;
+	}
+}
+
+__weak void board_vddcore_init(u32 voltage_mv)
+{
+}
+
+/*
+ * gets OPP parameters (frequency in KHz and voltage in mV) from
+ * an OPP table subnode. Platform HW support capabilities are also checked.
+ * Returns 0 on success and a negative FDT error code on failure.
+ */
+static int stm32mp1_get_opp(u32 cpu_type, ofnode subnode,
+			    u32 *freq_khz, u32 *voltage_mv)
+{
+	u32 opp_hw;
+	u64 read_freq_64;
+	u32 read_voltage_32;
+
+	*freq_khz = 0;
+	*voltage_mv = 0;
+
+	opp_hw = ofnode_read_u32_default(subnode, "opp-supported-hw", 0);
+	if (opp_hw)
+		if (!stm32mp1_supports_opp(opp_hw, cpu_type))
+			return -FDT_ERR_BADVALUE;
+
+	read_freq_64 = ofnode_read_u64_default(subnode, "opp-hz", 0) /
+		       1000ULL;
+	read_voltage_32 = ofnode_read_u32_default(subnode, "opp-microvolt", 0) /
+			  1000U;
+
+	if (!read_voltage_32 || !read_freq_64)
+		return -FDT_ERR_NOTFOUND;
+
+	/* Frequency value expressed in KHz must fit on 32 bits */
+	if (read_freq_64 > U32_MAX)
+		return -FDT_ERR_BADVALUE;
+
+	/* Millivolt value must fit on 16 bits */
+	if (read_voltage_32 > U16_MAX)
+		return -FDT_ERR_BADVALUE;
+
+	*freq_khz = (u32)read_freq_64;
+	*voltage_mv = read_voltage_32;
+
+	return 0;
+}
+
+/*
+ * parses OPP table in DT and finds the parameters for the
+ * highest frequency supported by the HW platform.
+ * Returns 0 on success and a negative FDT error code on failure.
+ */
+int stm32mp1_get_max_opp_freq(struct stm32mp1_clk_priv *priv, u64 *freq_hz)
+{
+	ofnode node, subnode;
+	int ret;
+	u32 freq = 0U, voltage = 0U;
+	u32 cpu_type = get_cpu_type();
+
+	node = ofnode_by_compatible(ofnode_null(), "operating-points-v2");
+	if (!ofnode_valid(node))
+		return -FDT_ERR_NOTFOUND;
+
+	ofnode_for_each_subnode(subnode, node) {
+		unsigned int read_freq;
+		unsigned int read_voltage;
+
+		ret = stm32mp1_get_opp(cpu_type, subnode,
+				       &read_freq, &read_voltage);
+		if (ret)
+			continue;
+
+		if (read_freq > freq) {
+			freq = read_freq;
+			voltage = read_voltage;
+		}
+	}
+
+	if (!freq || !voltage)
+		return -FDT_ERR_NOTFOUND;
+
+	*freq_hz = (u64)1000U * freq;
+	board_vddcore_init(voltage);
+
+	return 0;
+}
+
+static int stm32mp1_pll1_opp(struct stm32mp1_clk_priv *priv, int clksrc,
+			     u32 *pllcfg, u32 *fracv)
+{
+	u32 post_divm;
+	u32 input_freq;
+	u64 output_freq;
+	u64 freq;
+	u64 vco;
+	u32 divm, divn, divp, frac;
+	int i, ret;
+	u32 diff;
+	u32 best_diff = U32_MAX;
+
+	/* PLL1 is 1600 */
+	const u32 DIVN_MAX = stm32mp1_pll[PLL_1600].divn_max;
+	const u32 POST_DIVM_MIN = stm32mp1_pll[PLL_1600].refclk_min * 1000000U;
+	const u32 POST_DIVM_MAX = stm32mp1_pll[PLL_1600].refclk_max * 1000000U;
+
+	ret = stm32mp1_get_max_opp_freq(priv, &output_freq);
+	if (ret) {
+		debug("PLL1 OPP configuration not found (%d).\n", ret);
+		return ret;
+	}
+
+	switch (clksrc) {
+	case CLK_PLL12_HSI:
+		input_freq = stm32mp1_clk_get_fixed(priv, _HSI);
+		break;
+	case CLK_PLL12_HSE:
+		input_freq = stm32mp1_clk_get_fixed(priv, _HSE);
+		break;
+	default:
+		return -EINTR;
+	}
+
+	/* Following parameters have always the same value */
+	pllcfg[PLLCFG_Q] = 0;
+	pllcfg[PLLCFG_R] = 0;
+	pllcfg[PLLCFG_O] = PQR(1, 0, 0);
+
+	for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--)	{
+		post_divm = (u32)(input_freq / (divm + 1));
+		if (post_divm < POST_DIVM_MIN || post_divm > POST_DIVM_MAX)
+			continue;
+
+		for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+			freq = output_freq * (divm + 1) * (divp + 1);
+			divn = (u32)((freq / input_freq) - 1);
+			if (divn < DIVN_MIN || divn > DIVN_MAX)
+				continue;
+
+			frac = (u32)(((freq * FRAC_MAX) / input_freq) -
+				     ((divn + 1) * FRAC_MAX));
+			/* 2 loops to refine the fractional part */
+			for (i = 2; i != 0; i--) {
+				if (frac > FRAC_MAX)
+					break;
+
+				vco = (post_divm * (divn + 1)) +
+				      ((post_divm * (u64)frac) /
+				       FRAC_MAX);
+				if (vco < (PLL1600_VCO_MIN / 2) ||
+				    vco > (PLL1600_VCO_MAX / 2)) {
+					frac++;
+					continue;
+				}
+				freq = vco / (divp + 1);
+				if (output_freq < freq)
+					diff = (u32)(freq - output_freq);
+				else
+					diff = (u32)(output_freq - freq);
+				if (diff < best_diff)  {
+					pllcfg[PLLCFG_M] = divm;
+					pllcfg[PLLCFG_N] = divn;
+					pllcfg[PLLCFG_P] = divp;
+					*fracv = frac;
+
+					if (diff == 0)
+						return 0;
+
+					best_diff = diff;
+				}
+				frac++;
+			}
+		}
+	}
+
+	if (best_diff == U32_MAX)
+		return -1;
+
+	return 0;
+}
+
 static void stm32mp1_ls_osc_set(int enable, fdt_addr_t rcc, u32 offset,
 				u32 mask_on)
 {
@@ -1661,9 +1879,12 @@ static int stm32mp1_clktree(struct udevice *dev)
 	unsigned int clksrc[CLKSRC_NB];
 	unsigned int clkdiv[CLKDIV_NB];
 	unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
-	ofnode plloff[_PLL_NB];
-	int ret, len;
-	uint i;
+	unsigned int pllfracv[_PLL_NB];
+	unsigned int pllcsg[_PLL_NB][PLLCSG_NB];
+	bool pllcfg_valid[_PLL_NB];
+	bool pllcsg_set[_PLL_NB];
+	int ret;
+	int i, len;
 	int lse_css = 0;
 	const u32 *pkcs_cell;
 
@@ -1683,16 +1904,43 @@ static int stm32mp1_clktree(struct udevice *dev)
 	/* check mandatory field in each pll */
 	for (i = 0; i < _PLL_NB; i++) {
 		char name[12];
+		ofnode node;
 
 		sprintf(name, "st,pll@%d", i);
-		plloff[i] = dev_read_subnode(dev, name);
-		if (!ofnode_valid(plloff[i]))
-			continue;
-		ret = ofnode_read_u32_array(plloff[i], "cfg",
-					    pllcfg[i], PLLCFG_NB);
-		if (ret < 0) {
-			debug("field cfg invalid: error %d\n", ret);
-			return -FDT_ERR_NOTFOUND;
+		node = dev_read_subnode(dev, name);
+		pllcfg_valid[i] = ofnode_valid(node);
+		pllcsg_set[i] = false;
+		if (pllcfg_valid[i]) {
+			debug("DT for PLL %d @ %s\n", i, name);
+			ret = ofnode_read_u32_array(node, "cfg",
+						    pllcfg[i], PLLCFG_NB);
+			if (ret < 0) {
+				debug("field cfg invalid: error %d\n", ret);
+				return -FDT_ERR_NOTFOUND;
+			}
+			pllfracv[i] = ofnode_read_u32_default(node, "frac", 0);
+
+			ret = ofnode_read_u32_array(node, "csg", pllcsg[i],
+						    PLLCSG_NB);
+			if (!ret) {
+				pllcsg_set[i] = true;
+			} else if (ret != -FDT_ERR_NOTFOUND) {
+				debug("invalid csg node for pll@%d res=%d\n",
+				      i, ret);
+				return ret;
+			}
+		} else if (i == _PLL1)	{
+			/* use OPP for PLL1 for A7 CPU */
+			debug("DT for PLL %d with OPP\n", i);
+			ret = stm32mp1_pll1_opp(priv,
+						clksrc[CLKSRC_PLL12],
+						pllcfg[i],
+						&pllfracv[i]);
+			if (ret) {
+				debug("PLL %d with OPP error = %d\n", i, ret);
+				return ret;
+			}
+			pllcfg_valid[i] = true;
 		}
 	}
 
@@ -1778,29 +2026,18 @@ static int stm32mp1_clktree(struct udevice *dev)
 	/* configure and start PLLs */
 	debug("configure PLLs\n");
 	for (i = 0; i < _PLL_NB; i++) {
-		u32 fracv;
-		u32 csg[PLLCSG_NB];
-
-		debug("configure PLL %d @ %d\n", i,
-		      ofnode_to_offset(plloff[i]));
-		if (!ofnode_valid(plloff[i]))
+		if (!pllcfg_valid[i])
 			continue;
-
-		fracv = ofnode_read_u32_default(plloff[i], "frac", 0);
-		pll_config(priv, i, pllcfg[i], fracv);
-		ret = ofnode_read_u32_array(plloff[i], "csg", csg, PLLCSG_NB);
-		if (!ret) {
-			pll_csg(priv, i, csg);
-		} else if (ret != -FDT_ERR_NOTFOUND) {
-			debug("invalid csg node for pll@%d res=%d\n", i, ret);
-			return ret;
-		}
+		debug("configure PLL %d\n", i);
+		pll_config(priv, i, pllcfg[i], pllfracv[i]);
+		if (pllcsg_set[i])
+			pll_csg(priv, i, pllcsg[i]);
 		pll_start(priv, i);
 	}
 
 	/* wait and start PLLs ouptut when ready */
 	for (i = 0; i < _PLL_NB; i++) {
-		if (!ofnode_valid(plloff[i]))
+		if (!pllcfg_valid[i])
 			continue;
 		debug("output PLL %d\n", i);
 		pll_output(priv, i, pllcfg[i][PLLCFG_O]);
@@ -2050,6 +2287,8 @@ static int stm32mp1_clk_probe(struct udevice *dev)
 	/* clock tree init is done only one time, before relocation */
 	if (!(gd->flags & GD_FLG_RELOC))
 		result = stm32mp1_clktree(dev);
+	if (result)
+		printf("clock tree initialization failed (%d)\n", result);
 #endif
 
 #ifndef CONFIG_SPL_BUILD

+ 135 - 14
drivers/gpio/stm32_gpio.c

@@ -18,9 +18,65 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 
-#define MODE_BITS(gpio_pin)		(gpio_pin * 2)
+#define MODE_BITS(gpio_pin)		((gpio_pin) * 2)
 #define MODE_BITS_MASK			3
-#define BSRR_BIT(gpio_pin, value)	BIT(gpio_pin + (value ? 0 : 16))
+#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
+
+static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs,
+				 int idx,
+				 int mode)
+{
+	int bits_index;
+	int mask;
+
+	bits_index = MODE_BITS(idx);
+	mask = MODE_BITS_MASK << bits_index;
+
+	clrsetbits_le32(&regs->moder, mask, mode << bits_index);
+}
+
+static int stm32_gpio_get_moder(struct stm32_gpio_regs *regs, int idx)
+{
+	return (readl(&regs->moder) >> MODE_BITS(idx)) & MODE_BITS_MASK;
+}
+
+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(&regs->otyper, OTYPE_MSK << bits, otype << bits);
+}
+
+static enum stm32_gpio_otype stm32_gpio_get_otype(struct stm32_gpio_regs *regs,
+						  int idx)
+{
+	return (readl(&regs->otyper) >> OTYPE_BITS(idx)) & OTYPE_MSK;
+}
+
+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(&regs->pupdr, PUPD_MASK << bits, pupd << bits);
+}
+
+static enum stm32_gpio_pupd stm32_gpio_get_pupd(struct stm32_gpio_regs *regs,
+						int idx)
+{
+	return (readl(&regs->pupdr) >> PUPD_BITS(idx)) & PUPD_MASK;
+}
 
 /*
  * convert gpio offset to gpio index taking into account gpio holes
@@ -47,18 +103,13 @@ static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
 	struct stm32_gpio_regs *regs = priv->regs;
-	int bits_index;
-	int mask;
 	int idx;
 
 	idx = stm32_offset_to_index(dev, offset);
 	if (idx < 0)
 		return idx;
 
-	bits_index = MODE_BITS(idx);
-	mask = MODE_BITS_MASK << bits_index;
-
-	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_IN << bits_index);
+	stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
 
 	return 0;
 }
@@ -68,18 +119,13 @@ static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset,
 {
 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
 	struct stm32_gpio_regs *regs = priv->regs;
-	int bits_index;
-	int mask;
 	int idx;
 
 	idx = stm32_offset_to_index(dev, offset);
 	if (idx < 0)
 		return idx;
 
-	bits_index = MODE_BITS(idx);
-	mask = MODE_BITS_MASK << bits_index;
-
-	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_OUT << bits_index);
+	stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
 
 	writel(BSRR_BIT(idx, value), &regs->bsrr);
 
@@ -141,12 +187,87 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset)
 	return GPIOF_FUNC;
 }
 
+static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
+				    ulong flags)
+{
+	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;
+
+	if (flags & GPIOD_IS_OUT) {
+		int value = GPIOD_FLAGS_OUTPUT(flags);
+
+		if (flags & GPIOD_OPEN_DRAIN)
+			stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
+		else
+			stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
+		stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
+		writel(BSRR_BIT(idx, value), &regs->bsrr);
+
+	} 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);
+	}
+
+	return 0;
+}
+
+static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
+				    ulong *flags)
+{
+	struct stm32_gpio_priv *priv = dev_get_priv(dev);
+	struct stm32_gpio_regs *regs = priv->regs;
+	int idx;
+	ulong dir_flags = 0;
+
+	idx = stm32_offset_to_index(dev, offset);
+	if (idx < 0)
+		return idx;
+
+	switch (stm32_gpio_get_moder(regs, idx)) {
+	case STM32_GPIO_MODE_OUT:
+		dir_flags |= GPIOD_IS_OUT;
+		if (stm32_gpio_get_otype(regs, idx) == STM32_GPIO_OTYPE_OD)
+			dir_flags |= GPIOD_OPEN_DRAIN;
+		if (readl(&regs->idr) & BIT(idx))
+			dir_flags |= GPIOD_IS_OUT_ACTIVE;
+		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;
+	}
+	*flags = dir_flags;
+
+	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_dir_flags		= stm32_gpio_set_dir_flags,
+	.get_dir_flags		= stm32_gpio_get_dir_flags,
 };
 
 static int gpio_stm32_probe(struct udevice *dev)

+ 1 - 1
drivers/net/dwc_eth_qos.c

@@ -2170,7 +2170,7 @@ static const struct udevice_id eqos_ids[] = {
 		.data = (ulong)&eqos_tegra186_config
 	},
 	{
-		.compatible = "snps,dwmac-4.20a",
+		.compatible = "st,stm32mp1-dwmac",
 		.data = (ulong)&eqos_stm32_config
 	},
 	{

+ 162 - 63
drivers/pinctrl/pinctrl-stmfx.c

@@ -74,17 +74,61 @@ 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_gpio_get(struct udevice *dev, unsigned int offset)
+static int stmfx_read_reg(struct udevice *dev, u8 reg_base, uint offset)
 {
-	u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset);
+	u8 reg = reg_base + get_reg(offset);
 	u32 mask = get_mask(offset);
 	int ret;
 
 	ret = stmfx_read(dev, reg);
+	if (ret < 0)
+		return ret;
 
 	return ret < 0 ? ret : !!(ret & mask);
 }
 
+static int stmfx_write_reg(struct udevice *dev, u8 reg_base, uint offset,
+			   uint val)
+{
+	u8 reg = reg_base + get_reg(offset);
+	u32 mask = get_mask(offset);
+	int ret;
+
+	ret = stmfx_read(dev, reg);
+	if (ret < 0)
+		return ret;
+	ret = (ret & ~mask) | (val ? mask : 0);
+
+	return stmfx_write(dev, reg, ret);
+}
+
+static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int offset,
+			       uint pupd)
+{
+	return stmfx_write_reg(dev, STMFX_REG_GPIO_PUPD, offset, pupd);
+}
+
+static int stmfx_conf_get_pupd(struct udevice *dev, unsigned int offset)
+{
+	return stmfx_read_reg(dev, STMFX_REG_GPIO_PUPD, offset);
+}
+
+static int stmfx_conf_set_type(struct udevice *dev, unsigned int offset,
+			       uint type)
+{
+	return stmfx_write_reg(dev, STMFX_REG_GPIO_TYPE, offset, type);
+}
+
+static int stmfx_conf_get_type(struct udevice *dev, unsigned int offset)
+{
+	return stmfx_read_reg(dev, STMFX_REG_GPIO_TYPE, offset);
+}
+
+static int stmfx_gpio_get(struct udevice *dev, unsigned int offset)
+{
+	return stmfx_read_reg(dev, STMFX_REG_GPIO_STATE, offset);
+}
+
 static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value)
 {
 	u32 reg = value ? STMFX_REG_GPO_SET : STMFX_REG_GPO_CLR;
@@ -95,50 +139,103 @@ static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value)
 
 static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset)
 {
-	u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
-	u32 mask = get_mask(offset);
-	int ret;
-
-	ret = stmfx_read(dev, reg);
+	int ret = stmfx_read_reg(dev, STMFX_REG_GPIO_DIR, offset);
 
 	if (ret < 0)
 		return ret;
 	/* On stmfx, gpio pins direction is (0)input, (1)output. */
 
-	return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT;
+	return ret ? GPIOF_OUTPUT : GPIOF_INPUT;
 }
 
 static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset)
 {
-	u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
-	u32 mask = get_mask(offset);
-	int ret;
+	return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 0);
+}
 
-	ret = stmfx_read(dev, reg);
+static int stmfx_gpio_direction_output(struct udevice *dev,
+				       unsigned int offset, int value)
+{
+	int ret = stmfx_gpio_set(dev, offset, value);
 	if (ret < 0)
 		return ret;
 
-	ret &= ~mask;
+	return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1);
+}
 
-	return stmfx_write(dev, reg, ret & ~mask);
+static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
+				    ulong flags)
+{
+	int ret = -ENOTSUPP;
+
+	if (flags & GPIOD_IS_OUT) {
+		if (flags & GPIOD_OPEN_SOURCE)
+			return -ENOTSUPP;
+		if (flags & GPIOD_OPEN_DRAIN)
+			ret = stmfx_conf_set_type(dev, offset, 0);
+		else /* PUSH-PULL */
+			ret = stmfx_conf_set_type(dev, offset, 1);
+		if (ret)
+			return ret;
+		ret = stmfx_gpio_direction_output(dev, offset,
+						  GPIOD_FLAGS_OUTPUT(flags));
+	} else if (flags & GPIOD_IS_IN) {
+		ret = stmfx_gpio_direction_input(dev, offset);
+		if (ret)
+			return ret;
+		if (flags & GPIOD_PULL_UP) {
+			ret = stmfx_conf_set_type(dev, offset, 1);
+			if (ret)
+				return ret;
+			ret = stmfx_conf_set_pupd(dev, offset, 1);
+		} else if (flags & GPIOD_PULL_DOWN) {
+			ret = stmfx_conf_set_type(dev, offset, 1);
+			if (ret)
+				return ret;
+			ret = stmfx_conf_set_pupd(dev, offset, 0);
+		}
+	}
+
+	return ret;
 }
 
-static int stmfx_gpio_direction_output(struct udevice *dev,
-				       unsigned int offset, int value)
+static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
+				    ulong *flags)
 {
-	u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
-	u32 mask = get_mask(offset);
+	ulong dir_flags = 0;
 	int ret;
 
-	ret = stmfx_gpio_set(dev, offset, value);
-	if (ret < 0)
-		return ret;
-
-	ret = stmfx_read(dev, reg);
-	if (ret < 0)
-		return ret;
+	if (stmfx_gpio_get_function(dev, offset) == GPIOF_OUTPUT) {
+		dir_flags |= GPIOD_IS_OUT;
+		ret = stmfx_conf_get_type(dev, offset);
+		if (ret < 0)
+			return ret;
+		if (ret == 0)
+			dir_flags |= GPIOD_OPEN_DRAIN;
+			/* 1 = push-pull (default), open source not supported */
+		ret = stmfx_gpio_get(dev, offset);
+		if (ret < 0)
+			return ret;
+		if (ret)
+			dir_flags |= GPIOD_IS_OUT_ACTIVE;
+	} else {
+		dir_flags |= GPIOD_IS_IN;
+		ret = stmfx_conf_get_type(dev, offset);
+		if (ret < 0)
+			return ret;
+		if (ret == 1) {
+			ret = stmfx_conf_get_pupd(dev, offset);
+			if (ret < 0)
+				return ret;
+			if (ret == 1)
+				dir_flags |= GPIOD_PULL_UP;
+			else
+				dir_flags |= GPIOD_PULL_DOWN;
+		}
+	}
+	*flags = dir_flags;
 
-	return stmfx_write(dev, reg, ret | mask);
+	return 0;
 }
 
 static int stmfx_gpio_probe(struct udevice *dev)
@@ -169,6 +266,8 @@ 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_dir_flags = stmfx_gpio_set_dir_flags,
+	.get_dir_flags = stmfx_gpio_get_dir_flags,
 };
 
 U_BOOT_DRIVER(stmfx_gpio) = {
@@ -190,36 +289,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)
 {
@@ -235,22 +304,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);
@@ -289,6 +358,34 @@ 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;
+
+	type = stmfx_conf_get_type(dev, pin);
+	if (type < 0)
+		return "";
+
+	if (func == GPIOF_OUTPUT) {
+		if (type)
+			return "drive-open-drain";
+		else
+			return ""; /* default: push-pull*/
+	}
+	if (!type)
+		return ""; /* default: bias-disable*/
+
+	pupd = stmfx_conf_get_pupd(dev, pin);
+	if (pupd < 0)
+		return "";
+
+	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)
@@ -300,7 +397,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;
 }

+ 24 - 3
drivers/pinctrl/pinctrl_stm32.c

@@ -45,6 +45,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);
@@ -182,10 +193,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);
@@ -194,9 +207,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) {
@@ -211,9 +224,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;
 	}
 

+ 14 - 2
drivers/power/regulator/stm32-vrefbuf.c

@@ -43,8 +43,20 @@ static int stm32_vrefbuf_set_enable(struct udevice *dev, bool enable)
 	u32 val;
 	int ret;
 
-	clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_HIZ | STM32_ENVR,
-			enable ? STM32_ENVR : STM32_HIZ);
+	if (enable && !(readl(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR)) {
+		/*
+		 * There maybe an overshoot:
+		 * - when disabling, then re-enabling vrefbuf too quickly
+		 * - or upon platform reset as external capacitor maybe slow
+		 *   discharging (VREFBUF is HiZ at reset by default).
+		 * So force active discharge (HiZ=0) for 1ms before enabling.
+		 */
+		clrbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_HIZ);
+		udelay(1000);
+	}
+
+	clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_ENVR,
+			enable ? STM32_ENVR : 0);
 	if (!enable)
 		return 0;
 

+ 71 - 27
drivers/ram/stm32mp1/stm32mp1_tests.c

@@ -14,10 +14,12 @@
 
 #define ADDR_INVALID	0xFFFFFFFF
 
+#define PATTERN_DEFAULT	"-"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
-		       size_t *bufsize, size_t default_size)
+		       size_t *bufsize, size_t default_size, size_t min_size)
 {
 	unsigned long value;
 
@@ -27,13 +29,14 @@ static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
 				arg_nb, argv[arg_nb]);
 			return -1;
 		}
-		if (value > STM32_DDR_SIZE || value == 0) {
-			sprintf(string, "invalid size %s", argv[arg_nb]);
+		if (value > STM32_DDR_SIZE || value < min_size) {
+			sprintf(string, "invalid size %s (min=%d)",
+				argv[arg_nb], min_size);
 			return -1;
 		}
-		if (value & 0x3) {
-			sprintf(string, "unaligned size %s",
-				argv[arg_nb]);
+		if (value & (min_size - 1)) {
+			sprintf(string, "unaligned size %s (min=%d)",
+				argv[arg_nb], min_size);
 			return -1;
 		}
 		*bufsize = value;
@@ -102,6 +105,10 @@ static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
 	unsigned long value;
 
 	if (argc > arg_nb) {
+		if (!strcmp(argv[arg_nb], PATTERN_DEFAULT)) {
+			*pattern = default_pattern;
+			return 0;
+		}
 		if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
 			sprintf(string, "invalid %d parameter %s",
 				arg_nb, argv[arg_nb]);
@@ -441,7 +448,7 @@ static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
 	u32 bufsize;
 	u32 error;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, STM32_DDR_SIZE, 4))
 		return TEST_ERROR;
 	if (!is_power_of_2(bufsize)) {
 		sprintf(string, "size 0x%x is not a power of 2",
@@ -451,6 +458,7 @@ static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
 	if (get_addr(string, argc, argv, 1, &addr))
 		return TEST_ERROR;
 
+	printf("running at 0x%08x length 0x%x\n", addr, bufsize);
 	error = (u32)addressbus((u32 *)addr, bufsize);
 	if (error) {
 		sprintf(string, "0x%x: error for address 0x%x",
@@ -470,7 +478,7 @@ static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
 	size_t bufsize;
 	u32 error;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
 		return TEST_ERROR;
 	if (get_addr(string, argc, argv, 1, &addr))
 		return TEST_ERROR;
@@ -512,7 +520,7 @@ static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
 	u32 error = 0;
 	u32 data;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
 		return TEST_ERROR;
 	if (get_addr(string, argc, argv, 1, &addr))
 		return TEST_ERROR;
@@ -584,7 +592,7 @@ static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
 	u32 error = 0;
 	unsigned int seed;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 8 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
 		return TEST_ERROR;
 	if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
 		return TEST_ERROR;
@@ -744,7 +752,7 @@ static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl,
 	int i;
 	enum test_result res = TEST_PASSED;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
 		return TEST_ERROR;
 	if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
 		return TEST_ERROR;
@@ -918,9 +926,11 @@ static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
 	enum test_result res = TEST_PASSED, pattern_res;
 	int i, bus_width;
 	const u32 **patterns;
-	u32 bufsize;
+	u32 bufsize, addr;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
+		return TEST_ERROR;
+	if (get_addr(string, argc, argv, 1, &addr))
 		return TEST_ERROR;
 
 	switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
@@ -934,15 +944,14 @@ static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
 	}
 
 	printf("running test pattern at 0x%08x length 0x%x width = %d\n",
-	       STM32_DDR_BASE, bufsize, bus_width);
+	       addr, bufsize, bus_width);
 
 	patterns =
 		(const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
 
 	for (i = 0; i < NB_PATTERN; i++) {
 		printf("test data pattern %s:", patterns_comments[i]);
-		pattern_res = test_loop(patterns[i], (u32 *)STM32_DDR_BASE,
-					bufsize);
+		pattern_res = test_loop(patterns[i], (u32 *)addr, bufsize);
 		if (pattern_res != TEST_PASSED)	{
 			printf("Failed\n");
 			return pattern_res;
@@ -1007,7 +1016,7 @@ static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
 
 	u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
 		return TEST_ERROR;
 	if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
 		return TEST_ERROR;
@@ -1042,7 +1051,7 @@ static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
 	u32 bufsize, nb_loop, loop = 0, addr, value;
 	int i;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
 		return TEST_ERROR;
 	if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
 		return TEST_ERROR;
@@ -1076,7 +1085,7 @@ static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
 	u32 bufsize, nb_loop, loop = 0, addr, value;
 	int i;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
 		return TEST_ERROR;
 	if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
 		return TEST_ERROR;
@@ -1114,7 +1123,7 @@ static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
 	u32 bufsize, nb_loop, loop = 0, addr, value;
 	int i;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
 		return TEST_ERROR;
 	if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
 		return TEST_ERROR;
@@ -1156,7 +1165,7 @@ static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
 	u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
 	int i, j;
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
 		return TEST_ERROR;
 	if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
 		return TEST_ERROR;
@@ -1203,7 +1212,7 @@ static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
 
 	u32 bitflip[4];
 
-	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+	if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
 		return TEST_ERROR;
 	if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
 		return TEST_ERROR;
@@ -1340,17 +1349,52 @@ static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
 				 char *string, int argc, char *argv[])
 {
 	enum test_result res = TEST_PASSED, result;
-	int i, nb_error = 0;
+	int i, j, nb_error = 0, len;
 	u32 loop = 0, nb_loop;
+	int argc_test;
+	char *argv_test[4];
+	char loop_string[] = "1";
+	char pattern_string[] = PATTERN_DEFAULT;
+	u32 *addr;
 
 	if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
 		return TEST_ERROR;
 
+	if (get_addr(string, argc, argv, 2, (u32 *)&addr))
+		return TEST_ERROR;
+
 	while (!nb_error) {
 		/* execute all the test except the lasts which are infinite */
 		for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) {
+			argc_test = 0;
+			j = 0;
+			len = strlen(test[i].usage);
+			if (argc > 1 && j < len &&
+			    !strncmp("[size]", &test[i].usage[j], 6)) {
+				argv_test[argc_test++] = argv[1];
+				j += 7;
+			}
+			if (argc > 2) {
+				if (j < len &&
+				    !strncmp("[loop]", &test[i].usage[j], 6)) {
+					argv_test[argc_test++] = loop_string;
+					j += 7;
+				}
+				if (j < len &&
+				    !strncmp("[pattern]", &test[i].usage[j],
+					     9)) {
+					argv_test[argc_test++] = pattern_string;
+					j += 10;
+				}
+				if (j < len &&
+				    !strncmp("[addr]", &test[i].usage[j], 6)) {
+					argv_test[argc_test++] = argv[2];
+					j += 7;
+				}
+			}
 			printf("execute %d:%s\n", (int)i, test[i].name);
-			result = test[i].fct(ctl, phy, string, 0, NULL);
+			result = test[i].fct(ctl, phy, string,
+					     argc_test, argv_test);
 			printf("result %d:%s = ", (int)i, test[i].name);
 			if (result != TEST_PASSED) {
 				nb_error++;
@@ -1381,7 +1425,7 @@ static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
  ****************************************************************/
 
 const struct test_desc test[] = {
-	{test_all, "All", "[loop]", "Execute all tests", 1 },
+	{test_all, "All", "[loop] [size] [addr]", "Execute all tests", 3 },
 	{test_databus, "Simple DataBus", "[addr]",
 	 "Verifies each data line by walking 1 on fixed address",
 	 1
@@ -1418,9 +1462,9 @@ const struct test_desc test[] = {
 	 "Verifies r/w and memcopy(burst for pseudo random value.",
 	 3
 	},
-	{test_freq_pattern, "FrequencySelectivePattern", "[size]",
+	{test_freq_pattern, "FrequencySelectivePattern", "[size] [addr]",
 	 "write & test patterns: Mostly Zero, Mostly One and F/n",
-	 1
+	 2
 	},
 	{test_blockseq, "BlockSequential", "[size] [loop] [addr]",
 	 "test incremental pattern",

+ 4 - 4
include/configs/stm32mp1.h

@@ -123,7 +123,7 @@
  * for serial/usb: execute the stm32prog command
  * for mmc boot (eMMC, SD card), boot only on the same device
  * for nand or spi-nand boot, boot with on ubifs partition on UBI partition
- * for nor boot, use the default order
+ * for nor boot, use SD card = mmc0
  */
 #define STM32MP_BOOTCMD "bootcmd_stm32mp=" \
 	"echo \"Boot over ${boot_device}${boot_instance}!\";" \
@@ -136,6 +136,8 @@
 		"if test ${boot_device} = nand ||" \
 		  " test ${boot_device} = spi-nand ;" \
 		"then env set boot_targets ubifs0; fi;" \
+		"if test ${boot_device} = nor;" \
+		"then env set boot_targets mmc0; fi;" \
 		"run distro_bootcmd;" \
 	"fi;\0"
 
@@ -155,9 +157,7 @@
 	"splashimage=0xc4300000\0"  \
 	"ramdisk_addr_r=0xc4400000\0" \
 	"altbootcmd=run bootcmd\0" \
-	"env_default=1\0" \
-	"env_check=if test $env_default -eq 1;"\
-		" then env set env_default 0;env save;fi\0" \
+	"env_check=if env info -p -d; then env save; fi\0" \
 	STM32MP_BOOTCMD \
 	BOOTENV \
 	"boot_net_usb_start=true\0"