ARM: sama5d2: Implement boot device autodetection
authorMarek Vasut <marex@denx.de>
Fri, 22 Apr 2016 19:56:21 +0000 (21:56 +0200)
committerAndreas Bießmann <andreas@biessmann.org>
Tue, 24 May 2016 06:08:37 +0000 (08:08 +0200)
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>
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/bootparams_atmel.S [new file with mode: 0644]
arch/arm/mach-at91/include/mach/sama5d2.h
arch/arm/mach-at91/spl.c

index 44245234ee77b0aa9f7a4a86916c818dc4fd6166..d2abf310a59989c51362585fff3d83a6bc007d4e 100644 (file)
@@ -9,7 +9,7 @@ obj-$(CONFIG_AT91SAM9G20) += sdram.o spl_at91.o
 obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o spl_at91.o
 obj-$(CONFIG_AT91SAM9N12) += mpddrc.o spl_at91.o
 obj-$(CONFIG_AT91SAM9X5) += mpddrc.o spl_at91.o
-obj-$(CONFIG_SAMA5D2) += mpddrc.o spl_atmel.o matrix.o atmel_sfr.o
+obj-$(CONFIG_SAMA5D2) += bootparams_atmel.o mpddrc.o spl_atmel.o matrix.o atmel_sfr.o
 obj-$(CONFIG_SAMA5D3) += mpddrc.o spl_atmel.o
 obj-$(CONFIG_SAMA5D4) += mpddrc.o spl_atmel.o matrix.o atmel_sfr.o
 obj-y += spl.o
diff --git a/arch/arm/mach-at91/bootparams_atmel.S b/arch/arm/mach-at91/bootparams_atmel.S
new file mode 100644 (file)
index 0000000..568094b
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Atmel SAMA5Dx boot parameter handling
+ *
+ * Copyright (c) 2016 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
+
+ENTRY(save_boot_params)
+       ldr     r0, =bootrom_stash
+       str     r4, [r0, #0]
+       b       save_boot_params_ret
+ENDPROC(save_boot_params)
index 25c85411e5a1e3c7ce3ee9dc6def14d3b1358f9e..ee841da971a527d90915783db969a7b3ee49e2ef 100644 (file)
 /* No PMECC Galois table in ROM */
 #define NO_GALOIS_TABLE_IN_ROM
 
+/* Boot modes stored by BootROM in r4 */
+#define ATMEL_SAMA5D2_BOOT_FROM_OFF    0
+#define ATMEL_SAMA5D2_BOOT_FROM_MASK   0xf
+#define ATMEL_SAMA5D2_BOOT_FROM_SPI    (0 << 0)
+#define ATMEL_SAMA5D2_BOOT_FROM_MCI    (1 << 0)
+#define ATMEL_SAMA5D2_BOOT_FROM_SMC    (2 << 0)
+#define ATMEL_SAMA5D2_BOOT_FROM_TWI    (3 << 0)
+#define ATMEL_SAMA5D2_BOOT_FROM_QSPI   (4 << 0)
+
+#define ATMEL_SAMA5D2_BOOT_DEV_ID_OFF  4
+#define ATMEL_SAMA5D2_BOOT_DEV_ID_MASK 0xf
+
 #ifndef __ASSEMBLY__
 unsigned int get_chip_id(void);
 unsigned int get_extension_chip_id(void);
index 27a405a42bf884ed49f2646646637e910386057d..c4ed224d03dffa9ef0f19172cba33ca6fea9e496 100644 (file)
@@ -23,6 +23,40 @@ void at91_disable_wdt(void)
 }
 #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 @@ u32 spl_boot_device(void)
 #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