diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index c07dd68e6ce..1e989ac48ac 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -156,6 +156,43 @@ config SYS_DEFAULT_LPDDR2_TIMINGS endchoice +config SPL_AM33XX_MMCSD_MULTIPLE + bool "Support multiple locations of next boot phase" + depends on AM33XX + depends on SPL_SYS_MMCSD_RAW_MODE + depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR + help + The boot ROM on the am33xx looks for the first stage + bootloader at several hard-coded offsets in the mmc device + (0, 128K, 256K, 384K) and uses the first location which has + a valid header. This can be used to implement failsafe + update of that first stage (SPL). But in order for the + update of the whole bootloader to be failsafe, SPL must load + U-Boot proper from a location dependent on where SPL itself + was loaded from. This option allows you to specify four + different offsets corresponding to the different places + where SPL could have been loaded from. + +if SPL_AM33XX_MMCSD_MULTIPLE + +config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_0K + hex "Address on the MMC to load U-Boot from when SPL was loaded from offset 0K" + default SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR + +config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_128K + hex "Address on the MMC to load U-Boot from when SPL was loaded from offset 128K" + default SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR + +config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_256K + hex "Address on the MMC to load U-Boot from when SPL was loaded from offset 256K" + default SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR + +config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_384K + hex "Address on the MMC to load U-Boot from when SPL was loaded from offset 384K" + default SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR + +endif + source "arch/arm/mach-omap2/omap3/Kconfig" source "arch/arm/mach-omap2/omap5/Kconfig" diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c index 95b44c8b1e5..88fa59feaf1 100644 --- a/arch/arm/mach-omap2/boot-common.c +++ b/arch/arm/mach-omap2/boot-common.c @@ -318,3 +318,34 @@ static void tee_image_process(ulong tee_image, size_t tee_size) } U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, tee_image_process); #endif + +#ifdef CONFIG_SPL_AM33XX_MMCSD_MULTIPLE + +#define AM335X_TRACE_VECTOR2 0x4030CE44 + +unsigned long arch_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect) +{ + u32 bits = *(u32 *)AM335X_TRACE_VECTOR2; + + bits &= 0xf000; + + /* + * The ROM code sets the "trial bit 3", bit 15, first, when + * attempting offset 0, then "trial bit 2", bit 14, when + * attempting offset 128K, and so on. If the tracing vector + * has completely unexpected contents, fall back to the + * raw_sect we were given. + */ + switch (bits) { + case 0x8000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_0K; break; + case 0xc000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_128K; break; + case 0xe000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_256K; break; + case 0xf000: raw_sect = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_384K; break; + default: + printf("Warning: Unexpected trial bits 0x%04x in trace vector 2, falling back to 0x%lx\n", + bits, raw_sect); + } + + return raw_sect; +} +#endif