diff options
author | Marek Vasut <marex@denx.de> | 2016-04-22 21:56:21 +0200 |
---|---|---|
committer | Andreas Bießmann <andreas@biessmann.org> | 2016-05-24 08:08:37 +0200 |
commit | bb0c63a5f3b05770e8cb6171be57ca69995bd447 (patch) | |
tree | b5cfe93f0e4932dfb757a9df66deecc8804227d8 /arch | |
parent | 12328f25f257c347c79562ebc7f66c1a0f48bc2b (diff) |
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-at91/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/bootparams_atmel.S | 18 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/sama5d2.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-at91/spl.c | 36 |
4 files changed, 67 insertions, 1 deletions
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 4424523..d2abf31 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -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 index 0000000..568094b --- /dev/null +++ b/arch/arm/mach-at91/bootparams_atmel.S @@ -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) diff --git a/arch/arm/mach-at91/include/mach/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h index 25c8541..ee841da 100644 --- a/arch/arm/mach-at91/include/mach/sama5d2.h +++ b/arch/arm/mach-at91/include/mach/sama5d2.h @@ -230,6 +230,18 @@ /* 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); 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 @@ 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 |