diff options
Diffstat (limited to 'arch/arm/mach-imx/imx8m/soc.c')
-rw-r--r-- | arch/arm/mach-imx/imx8m/soc.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index f5983320c7..f2ddc834d4 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -585,6 +585,67 @@ enum boot_device get_boot_device(void) } #endif +#if defined(CONFIG_IMX8M) +#include <spl.h> +int spl_mmc_emmc_boot_partition(struct mmc *mmc) +{ + u32 *rom_log_addr = (u32 *)0x9e0; + u32 *rom_log; + u8 event_id; + int i, part; + + part = default_spl_mmc_emmc_boot_partition(mmc); + + /* If the ROM event log pointer is not valid. */ + if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xb00000 || + *rom_log_addr & 0x3) + return part; + + /* Parse the ROM event ID version 2 log */ + rom_log = (u32 *)(uintptr_t)(*rom_log_addr); + for (i = 0; i < 128; i++) { + event_id = rom_log[i] >> 24; + switch (event_id) { + case 0x00: /* End of list */ + return part; + /* Log entries with 1 parameter, skip 1 */ + case 0x80: /* Start to perform the device initialization */ + case 0x81: /* The boot device initialization completes */ + case 0x8f: /* The boot device initialization fails */ + case 0x90: /* Start to read data from boot device */ + case 0x91: /* Reading data from boot device completes */ + case 0x9f: /* Reading data from boot device fails */ + i += 1; + continue; + /* Log entries with 2 parameters, skip 2 */ + case 0xa0: /* Image authentication result */ + case 0xc0: /* Jump to the boot image soon */ + i += 2; + continue; + /* Boot from the secondary boot image */ + case 0x51: + /* + * Swap the eMMC boot partitions in case there was a + * fallback event (i.e. primary image was corrupted + * and that corruption was recognized by the BootROM), + * so the SPL loads the rest of the U-Boot from the + * correct eMMC boot partition, since the BootROM + * leaves the boot partition set to the corrupted one. + */ + if (part == 1) + part = 2; + else if (part == 2) + part = 1; + continue; + default: + continue; + } + } + + return part; +} +#endif + bool is_usb_boot(void) { return get_boot_device() == USB_BOOT; |