[PATCH v2 03/22] arm: stm32mp: add boot_mode support for STM32MP25

Patrice Chotard patrice.chotard at foss.st.com
Fri Apr 25 15:15:14 CEST 2025


From: Patrick Delaunay <patrick.delaunay at foss.st.com>

Add support of all the boot mode supported by STM32MP25x family
with information provided by TF-A in backup register

Signed-off-by: Patrick Delaunay <patrick.delaunay at foss.st.com>
Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---

(no changes since v1)

 arch/arm/mach-stm32mp/include/mach/stm32.h |  15 ++
 arch/arm/mach-stm32mp/stm32mp2/cpu.c       | 155 +++++++++++++++++++--
 configs/stm32mp25_defconfig                |   2 +
 3 files changed, 164 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index 6eb85ba7233..156009f51e3 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -42,6 +42,9 @@ enum boot_device {
 
 	BOOT_FLASH_SPINAND = 0x70,
 	BOOT_FLASH_SPINAND_1 = 0x71,
+
+	BOOT_FLASH_HYPERFLASH = 0x80,
+	BOOT_FLASH_HYPERFLASH_1 = 0x81
 };
 
 #define TAMP_BOOT_MODE_MASK		GENMASK(15, 8)
@@ -158,8 +161,20 @@ enum forced_boot_mode {
 #endif /* CONFIG_STM32MP15X || CONFIG_STM32MP13X */
 
 #ifdef CONFIG_STM32MP25X
+#define STM32_USART2_BASE		0x400E0000
+#define STM32_USART3_BASE		0x400F0000
+#define STM32_UART4_BASE		0x40100000
+#define STM32_UART5_BASE		0x40110000
+#define STM32_USART6_BASE		0x40220000
+#define STM32_UART9_BASE		0x402C0000
+#define STM32_USART1_BASE		0x40330000
+#define STM32_UART7_BASE		0x40370000
+#define STM32_UART8_BASE		0x40380000
 #define STM32_RCC_BASE			0x44200000
 #define STM32_TAMP_BASE			0x46010000
+#define STM32_SDMMC1_BASE		0x48220000
+#define STM32_SDMMC2_BASE		0x48230000
+#define STM32_SDMMC3_BASE		0x48240000
 
 #define STM32_DDR_BASE			0x80000000
 
diff --git a/arch/arm/mach-stm32mp/stm32mp2/cpu.c b/arch/arm/mach-stm32mp/stm32mp2/cpu.c
index 9530aa8534b..7cb71c518bd 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/cpu.c
+++ b/arch/arm/mach-stm32mp/stm32mp2/cpu.c
@@ -67,14 +67,6 @@ void enable_caches(void)
 	dcache_enable();
 }
 
-int arch_misc_init(void)
-{
-	setup_serial_number();
-	setup_mac_address();
-
-	return 0;
-}
-
 /*
  * Force data-section, as .bss will not be valid
  * when save_boot_params is invoked.
@@ -97,3 +89,150 @@ void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
 
 	save_boot_params_ret();
 }
+
+u32 get_bootmode(void)
+{
+	/* read bootmode from TAMP backup register */
+	return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
+		    TAMP_BOOT_MODE_SHIFT;
+}
+
+static void setup_boot_mode(void)
+{
+	const u32 serial_addr[] = {
+		STM32_USART1_BASE,
+		STM32_USART2_BASE,
+		STM32_USART3_BASE,
+		STM32_UART4_BASE,
+		STM32_UART5_BASE,
+		STM32_USART6_BASE,
+		STM32_UART7_BASE,
+		STM32_UART8_BASE,
+		STM32_UART9_BASE
+	};
+	const u32 sdmmc_addr[] = {
+		STM32_SDMMC1_BASE,
+		STM32_SDMMC2_BASE,
+		STM32_SDMMC3_BASE
+	};
+	char cmd[60];
+	u32 boot_ctx = readl(TAMP_BOOT_CONTEXT);
+	u32 boot_mode =
+		(boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
+	unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
+	u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK);
+	struct udevice *dev;
+
+	log_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n",
+		  __func__, boot_ctx, boot_mode, instance, forced_mode);
+	switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
+	case BOOT_SERIAL_UART:
+		if (instance > ARRAY_SIZE(serial_addr))
+			break;
+		/* serial : search associated node in devicetree */
+		sprintf(cmd, "serial@%x", serial_addr[instance]);
+		if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev)) {
+			/* restore console on error */
+			if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL))
+				gd->flags &= ~(GD_FLG_SILENT |
+					       GD_FLG_DISABLE_CONSOLE);
+			log_err("uart%d = %s not found in device tree!\n",
+				instance + 1, cmd);
+			break;
+		}
+		sprintf(cmd, "%d", dev_seq(dev));
+		env_set("boot_device", "serial");
+		env_set("boot_instance", cmd);
+
+		/* restore console on uart when not used */
+		if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && gd->cur_serial_dev != dev) {
+			gd->flags &= ~(GD_FLG_SILENT |
+				       GD_FLG_DISABLE_CONSOLE);
+			log_info("serial boot with console enabled!\n");
+		}
+		break;
+	case BOOT_SERIAL_USB:
+		env_set("boot_device", "usb");
+		env_set("boot_instance", "0");
+		break;
+	case BOOT_FLASH_SD:
+	case BOOT_FLASH_EMMC:
+		if (instance > ARRAY_SIZE(sdmmc_addr))
+			break;
+		/* search associated sdmmc node in devicetree */
+		sprintf(cmd, "mmc@%x", sdmmc_addr[instance]);
+		if (uclass_get_device_by_name(UCLASS_MMC, cmd, &dev)) {
+			printf("mmc%d = %s not found in device tree!\n",
+			       instance, cmd);
+			break;
+		}
+		sprintf(cmd, "%d", dev_seq(dev));
+		env_set("boot_device", "mmc");
+		env_set("boot_instance", cmd);
+		break;
+	case BOOT_FLASH_NAND:
+		env_set("boot_device", "nand");
+		env_set("boot_instance", "0");
+		break;
+	case BOOT_FLASH_SPINAND:
+		env_set("boot_device", "spi-nand");
+		env_set("boot_instance", "0");
+		break;
+	case BOOT_FLASH_NOR:
+		env_set("boot_device", "nor");
+		if (IS_ENABLED(CONFIG_SYS_MAX_FLASH_BANKS))
+			sprintf(cmd, "%d", CONFIG_SYS_MAX_FLASH_BANKS);
+		else
+			sprintf(cmd, "%d", 0);
+		env_set("boot_instance", cmd);
+		break;
+	case BOOT_FLASH_HYPERFLASH:
+		env_set("boot_device", "nor");
+		env_set("boot_instance", "0");
+		break;
+	default:
+		env_set("boot_device", "invalid");
+		env_set("boot_instance", "");
+		log_err("unexpected boot mode = %x\n", boot_mode);
+		break;
+	}
+
+	switch (forced_mode) {
+	case BOOT_FASTBOOT:
+		log_info("Enter fastboot!\n");
+		env_set("preboot", "env set preboot; fastboot 0");
+		break;
+	case BOOT_STM32PROG:
+		env_set("boot_device", "usb");
+		env_set("boot_instance", "0");
+		break;
+	case BOOT_UMS_MMC0:
+	case BOOT_UMS_MMC1:
+	case BOOT_UMS_MMC2:
+		log_info("Enter UMS!\n");
+		instance = forced_mode - BOOT_UMS_MMC0;
+		sprintf(cmd, "env set preboot; ums 0 mmc %d", instance);
+		env_set("preboot", cmd);
+		break;
+	case BOOT_RECOVERY:
+		env_set("preboot", "env set preboot; run altbootcmd");
+		break;
+	case BOOT_NORMAL:
+		break;
+	default:
+		log_debug("unexpected forced boot mode = %x\n", forced_mode);
+		break;
+	}
+
+	/* clear TAMP for next reboot */
+	clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL);
+}
+
+int arch_misc_init(void)
+{
+	setup_boot_mode();
+	setup_serial_number();
+	setup_mac_address();
+
+	return 0;
+}
diff --git a/configs/stm32mp25_defconfig b/configs/stm32mp25_defconfig
index 717724ff672..d11910f139f 100644
--- a/configs/stm32mp25_defconfig
+++ b/configs/stm32mp25_defconfig
@@ -44,6 +44,8 @@ CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_STM32F7=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_STM32_SDMMC2=y
+CONFIG_MTD=y
+CONFIG_USE_SYS_MAX_FLASH_BANKS=y
 CONFIG_PINCONF=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
-- 
2.25.1



More information about the U-Boot mailing list