mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
imx: iamge-container: support secondary container
Add the support for loading image from secondary container set on iMX8QM B0, iMX8QXP C0. Using the SCFW API to get container set index, if it is the secondary boot, get the offset from fuse and apply to offset of current container set beginning for loading. Also override the emmc boot partition to check secondary boot and switch to the other boot part. This patch is modified from NXP downstream: imx8: Fix the fuse used by secondary container offset imx: container: Skip container set check for ROM API imx8: spl: Support booting from secondary container set Signed-off-by: Ye Li <ye.li@nxp.com> Signed-off-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
parent
3b5c1d0ea1
commit
455ebf8f45
1 changed files with 87 additions and 7 deletions
|
@ -22,6 +22,25 @@
|
|||
#define QSPI_NOR_DEV 3
|
||||
#define ROM_API_DEV 4
|
||||
|
||||
/* The unit of second image offset number which provision by the fuse bits */
|
||||
#define SND_IMG_OFF_UNIT (0x100000UL)
|
||||
|
||||
/*
|
||||
* If num = 0, off = (2 ^ 2) * 1MB
|
||||
* else If num = 2, off = (2 ^ 0) * 1MB
|
||||
* else off = (2 ^ num) * 1MB
|
||||
*/
|
||||
#define SND_IMG_NUM_TO_OFF(num) \
|
||||
((1UL << ((0 == (num)) ? 2 : (2 == (num)) ? 0 : (num))) * SND_IMG_OFF_UNIT)
|
||||
|
||||
#define GET_SND_IMG_NUM(fuse) (((fuse) >> 24) & 0x1F)
|
||||
|
||||
#if defined(CONFIG_IMX8QM)
|
||||
#define FUSE_IMG_SET_OFF_WORD 464
|
||||
#elif defined(CONFIG_IMX8QXP)
|
||||
#define FUSE_IMG_SET_OFF_WORD 720
|
||||
#endif
|
||||
|
||||
int get_container_size(ulong addr, u16 *header_length)
|
||||
{
|
||||
struct container_hdr *phdr;
|
||||
|
@ -136,15 +155,53 @@ static int get_dev_container_size(void *dev, int dev_type, unsigned long offset,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool check_secondary_cnt_set(unsigned long *set_off)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_ARCH_IMX8)
|
||||
int ret;
|
||||
u8 set_id = 1;
|
||||
u32 fuse_val = 0;
|
||||
|
||||
if (!(is_imx8qxp() && is_soc_rev(CHIP_REV_B))) {
|
||||
ret = sc_misc_get_boot_container(-1, &set_id);
|
||||
if (ret)
|
||||
return false;
|
||||
/* Secondary boot */
|
||||
if (set_id == 2) {
|
||||
ret = sc_misc_otp_fuse_read(-1, FUSE_IMG_SET_OFF_WORD, &fuse_val);
|
||||
if (!ret) {
|
||||
if (set_off)
|
||||
*set_off = SND_IMG_NUM_TO_OFF(GET_SND_IMG_NUM(fuse_val));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned long get_boot_device_offset(void *dev, int dev_type)
|
||||
{
|
||||
unsigned long offset = 0;
|
||||
unsigned long offset = 0, sec_set_off = 0;
|
||||
bool sec_boot = false;
|
||||
|
||||
if (dev_type == ROM_API_DEV) {
|
||||
offset = (unsigned long)dev;
|
||||
return offset;
|
||||
}
|
||||
|
||||
sec_boot = check_secondary_cnt_set(&sec_set_off);
|
||||
if (sec_boot)
|
||||
printf("Secondary set selected\n");
|
||||
else
|
||||
printf("Primary set selected\n");
|
||||
|
||||
if (dev_type == MMC_DEV) {
|
||||
struct mmc *mmc = (struct mmc *)dev;
|
||||
|
||||
if (IS_SD(mmc) || mmc->part_config == MMCPART_NOAVAILABLE) {
|
||||
offset = CONTAINER_HDR_MMCSD_OFFSET;
|
||||
offset = sec_boot ? sec_set_off : CONTAINER_HDR_MMCSD_OFFSET;
|
||||
} else {
|
||||
u8 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
|
||||
|
||||
|
@ -154,19 +211,23 @@ static unsigned long get_boot_device_offset(void *dev, int dev_type)
|
|||
else
|
||||
offset = CONTAINER_HDR_EMMC_OFFSET;
|
||||
} else {
|
||||
offset = CONTAINER_HDR_MMCSD_OFFSET;
|
||||
offset = sec_boot ? sec_set_off : CONTAINER_HDR_MMCSD_OFFSET;
|
||||
}
|
||||
}
|
||||
} else if (dev_type == QSPI_DEV) {
|
||||
offset = CONTAINER_HDR_QSPI_OFFSET;
|
||||
offset = sec_boot ? (sec_set_off + CONTAINER_HDR_QSPI_OFFSET) :
|
||||
CONTAINER_HDR_QSPI_OFFSET;
|
||||
} else if (dev_type == NAND_DEV) {
|
||||
offset = CONTAINER_HDR_NAND_OFFSET;
|
||||
offset = sec_boot ? (sec_set_off + CONTAINER_HDR_NAND_OFFSET) :
|
||||
CONTAINER_HDR_NAND_OFFSET;
|
||||
} else if (dev_type == QSPI_NOR_DEV) {
|
||||
offset = CONTAINER_HDR_QSPI_OFFSET + 0x08000000;
|
||||
} else if (dev_type == ROM_API_DEV) {
|
||||
offset = (unsigned long)dev;
|
||||
} else {
|
||||
printf("Not supported dev_type: %d\n", dev_type);
|
||||
}
|
||||
|
||||
debug("container set offset 0x%lx\n", offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
@ -227,6 +288,25 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
|
|||
|
||||
return end / mmc->read_bl_len;
|
||||
}
|
||||
|
||||
int spl_mmc_emmc_boot_partition(struct mmc *mmc)
|
||||
{
|
||||
int part;
|
||||
|
||||
part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
|
||||
if (part == 1 || part == 2) {
|
||||
unsigned long sec_set_off = 0;
|
||||
bool sec_boot = false;
|
||||
|
||||
sec_boot = check_secondary_cnt_set(&sec_set_off);
|
||||
if (sec_boot)
|
||||
part = (part == 1) ? 2 : 1;
|
||||
} else if (part == 7) {
|
||||
part = 0;
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_NAND_SUPPORT
|
||||
|
|
Loading…
Reference in a new issue