stm32mp1: get boot mode from BootRom

SPL copy BootRom boot mode information
in TAMP register 21.

This TAMP register information is used
after relocation to set 2 env variables
- boot_device
- boot_instance

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 3e5ac15..4ba2aec 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -8,6 +8,7 @@
 #include <asm/io.h>
 #include <asm/arch/stm32.h>
 #include <asm/arch/sys_proto.h>
+#include <dm/uclass.h>
 
 /* RCC register */
 #define RCC_TZCR		(STM32_RCC_BASE + 0x00)
@@ -40,6 +41,16 @@
 #define DBGMCU_IDC_REV_ID_MASK	GENMASK(31, 16)
 #define DBGMCU_IDC_REV_ID_SHIFT	16
 
+/* boot interface from Bootrom
+ * - boot instance = bit 31:16
+ * - boot device = bit 15:0
+ */
+#define BOOTROM_PARAM_ADDR	0x2FFC0078
+#define BOOTROM_MODE_MASK	GENMASK(15, 0)
+#define BOOTROM_MODE_SHIFT	0
+#define BOOTROM_INSTANCE_MASK	 GENMASK(31, 16)
+#define BOOTROM_INSTANCE_SHIFT	16
+
 #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
 static void security_init(void)
 {
@@ -109,6 +120,37 @@
 }
 #endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */
 
+static u32 get_bootmode(void)
+{
+	u32 boot_mode;
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+	u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR);
+	u32 bootrom_device, bootrom_instance;
+
+	bootrom_device =
+		(bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT;
+	bootrom_instance =
+		(bootrom_itf & BOOTROM_INSTANCE_MASK) >> BOOTROM_INSTANCE_SHIFT;
+	boot_mode =
+		((bootrom_device << BOOT_TYPE_SHIFT) & BOOT_TYPE_MASK) |
+		((bootrom_instance << BOOT_INSTANCE_SHIFT) &
+		 BOOT_INSTANCE_MASK);
+
+	/* save the boot mode in TAMP backup register */
+	clrsetbits_le32(TAMP_BOOT_CONTEXT,
+			TAMP_BOOT_MODE_MASK,
+			boot_mode << TAMP_BOOT_MODE_SHIFT);
+#else
+	/* read TAMP backup register */
+	boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
+		    TAMP_BOOT_MODE_SHIFT;
+#endif
+	return boot_mode;
+}
+
+/*
+ * Early system init
+ */
 int arch_cpu_init(void)
 {
 	/* early armv7 timer init: needed for polling */
@@ -119,6 +161,8 @@
 
 	security_init();
 #endif
+	/* get bootmode from BootRom context: saved in TAMP register */
+	get_bootmode();
 
 	return 0;
 }
@@ -178,6 +222,54 @@
 }
 #endif /* CONFIG_DISPLAY_CPUINFO */
 
+static void setup_boot_mode(void)
+{
+	char cmd[60];
+	u32 boot_ctx = readl(TAMP_BOOT_CONTEXT);
+	u32 boot_mode =
+		(boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
+	int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
+
+	pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d\n",
+		 __func__, boot_ctx, boot_mode, instance);
+
+	switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
+	case BOOT_SERIAL_UART:
+		sprintf(cmd, "%d", instance);
+		env_set("boot_device", "uart");
+		env_set("boot_instance", cmd);
+		break;
+	case BOOT_SERIAL_USB:
+		env_set("boot_device", "usb");
+		env_set("boot_instance", "0");
+		break;
+	case BOOT_FLASH_SD:
+	case BOOT_FLASH_EMMC:
+		sprintf(cmd, "%d", instance);
+		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_NOR:
+		env_set("boot_device", "nor");
+		env_set("boot_instance", "0");
+		break;
+	default:
+		pr_debug("unexpected boot mode = %x\n", boot_mode);
+		break;
+	}
+}
+
+int arch_misc_init(void)
+{
+	setup_boot_mode();
+
+	return 0;
+}
+
 void reset_cpu(ulong addr)
 {
 }
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index ffbe0b1..40faeb0 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -24,4 +24,57 @@
 #define STM32_DDR_BASE			0xC0000000
 #define STM32_DDR_SIZE			SZ_1G
 
+#ifndef __ASSEMBLY__
+
+/*
+ * enumerated for boot interface from Bootrom, used in TAMP_BOOT_CONTEXT
+ * - boot device = bit 8:4
+ * - boot instance = bit 3:0
+ */
+#define BOOT_TYPE_MASK		0xF0
+#define BOOT_TYPE_SHIFT		4
+#define BOOT_INSTANCE_MASK	0x0F
+#define BOOT_INSTANCE_SHIFT	0
+
+enum boot_device {
+	BOOT_FLASH_SD = 0x10,
+	BOOT_FLASH_SD_1 = 0x11,
+	BOOT_FLASH_SD_2 = 0x12,
+	BOOT_FLASH_SD_3 = 0x13,
+
+	BOOT_FLASH_EMMC = 0x20,
+	BOOT_FLASH_EMMC_1 = 0x21,
+	BOOT_FLASH_EMMC_2 = 0x22,
+	BOOT_FLASH_EMMC_3 = 0x23,
+
+	BOOT_FLASH_NAND = 0x30,
+	BOOT_FLASH_NAND_FMC = 0x31,
+
+	BOOT_FLASH_NOR = 0x40,
+	BOOT_FLASH_NOR_QSPI = 0x41,
+
+	BOOT_SERIAL_UART = 0x50,
+	BOOT_SERIAL_UART_1 = 0x51,
+	BOOT_SERIAL_UART_2 = 0x52,
+	BOOT_SERIAL_UART_3 = 0x53,
+	BOOT_SERIAL_UART_4 = 0x54,
+	BOOT_SERIAL_UART_5 = 0x55,
+	BOOT_SERIAL_UART_6 = 0x56,
+	BOOT_SERIAL_UART_7 = 0x57,
+	BOOT_SERIAL_UART_8 = 0x58,
+
+	BOOT_SERIAL_USB = 0x60,
+	BOOT_SERIAL_USB_OTG = 0x62,
+};
+
+/* TAMP registers */
+#define TAMP_BACKUP_REGISTER(x)		(STM32_TAMP_BASE + 0x100 + 4 * x)
+#define TAMP_BOOT_CONTEXT		TAMP_BACKUP_REGISTER(20)
+
+#define TAMP_BOOT_MODE_MASK		GENMASK(15, 8)
+#define TAMP_BOOT_MODE_SHIFT		8
+#define TAMP_BOOT_DEVICE_MASK		GENMASK(7, 4)
+#define TAMP_BOOT_INSTANCE_MASK		GENMASK(3, 0)
+
+#endif /* __ASSEMBLY__*/
 #endif /* _MACH_STM32_H_ */