ARM: sama5d2: Implement boot device autodetection
Implement support for saving ARM register R4 early during boot using
save_boot_params . Implement support for decoding the stored register
R4 value in spl_boot_device() to obtain boot device from which the
SoC booted. This way, the SPL will always load U-Boot from the same
device from which the SPL itself booted instead of using hard-coded
boot device.
This functionality is useful for example when booting sama5d2-xplained
from SD card, where by default the SPL would try loading the U-Boot
from eMMC and fail. This is because eMMC is on SDHCI0 (BOOT_DEVICE_MMC1),
while SD slot is on SDHCI1 (BOOT_DEVICE_MMC2) and the SPL was hard-wired
to always boot from BOOT_DEVICE_MMC1.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Andreas Bießmann <andreas.devel@googlemail.com>
Cc: Wenyou Yang <wenyou.yang@atmel.com>
Reviewed-by: Andreas Bießmann <andreas@biessmann.org>
diff --git a/arch/arm/mach-at91/spl.c b/arch/arm/mach-at91/spl.c
index 27a405a..c4ed224 100644
--- a/arch/arm/mach-at91/spl.c
+++ b/arch/arm/mach-at91/spl.c
@@ -23,6 +23,40 @@
}
#endif
+#if defined(CONFIG_SAMA5D2)
+struct {
+ u32 r4;
+} bootrom_stash __attribute__((section(".data")));
+
+u32 spl_boot_device(void)
+{
+ u32 dev = (bootrom_stash.r4 >> ATMEL_SAMA5D2_BOOT_FROM_OFF) &
+ ATMEL_SAMA5D2_BOOT_FROM_MASK;
+ u32 off = (bootrom_stash.r4 >> ATMEL_SAMA5D2_BOOT_DEV_ID_OFF) &
+ ATMEL_SAMA5D2_BOOT_DEV_ID_MASK;
+
+#if defined(CONFIG_SYS_USE_MMC)
+ if (dev == ATMEL_SAMA5D2_BOOT_FROM_MCI) {
+ if (off == 0)
+ return BOOT_DEVICE_MMC1;
+ if (off == 1)
+ return BOOT_DEVICE_MMC2;
+ printf("ERROR: MMC controller %i not present!\n", dev);
+ hang();
+ }
+#endif
+
+#if defined(CONFIG_SYS_USE_SERIALFLASH) || defined(CONFIG_SYS_USE_SPIFLASH)
+ if (dev == ATMEL_SAMA5D2_BOOT_FROM_SPI)
+ return BOOT_DEVICE_SPI;
+#endif
+
+ printf("ERROR: SMC/TWI/QSPI boot device not supported!\n"
+ " Boot device %i, controller number %i\n", dev, off);
+
+ return BOOT_DEVICE_NONE;
+}
+#else
u32 spl_boot_device(void)
{
#ifdef CONFIG_SYS_USE_MMC
@@ -34,12 +68,14 @@
#endif
return BOOT_DEVICE_NONE;
}
+#endif
u32 spl_boot_mode(void)
{
switch (spl_boot_device()) {
#ifdef CONFIG_SYS_USE_MMC
case BOOT_DEVICE_MMC1:
+ case BOOT_DEVICE_MMC2:
return MMCSD_MODE_FS;
break;
#endif