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>
This commit is contained in:
Marek Vasut 2016-04-22 21:56:21 +02:00 committed by Andreas Bießmann
parent 12328f25f2
commit bb0c63a5f3
4 changed files with 67 additions and 1 deletions

View 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

View file

@ -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)

View file

@ -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);

View 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