From patchwork Tue Jun 9 10:34:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ye Li X-Patchwork-Id: 241993 List-Id: U-Boot discussion From: ye.li at nxp.com (Ye Li) Date: Tue, 9 Jun 2020 03:34:42 -0700 Subject: [PATCH 1/3] misc: scu_api: Add SCFW API to get the index of boot container set Message-ID: <1591698884-72174-1-git-send-email-ye.li@nxp.com> Add SCFW API sc_misc_get_boot_container to get current boot container set index. The index value returns 1 for primary container set, 2 for secondary container set. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sci/rpc.h | 1 + arch/arm/include/asm/arch-imx8/sci/sci.h | 1 + drivers/misc/imx8/scu_api.c | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8/sci/rpc.h b/arch/arm/include/asm/arch-imx8/sci/rpc.h index c1a9c35..9f55904 100644 --- a/arch/arm/include/asm/arch-imx8/sci/rpc.h +++ b/arch/arm/include/asm/arch-imx8/sci/rpc.h @@ -115,6 +115,7 @@ struct sc_rpc_msg_s { #define MISC_FUNC_GET_TEMP 13U #define MISC_FUNC_GET_BOOT_DEV 16U #define MISC_FUNC_GET_BUTTON_STATUS 18U +#define MISC_FUNC_GET_BOOT_CONTAINER 36U /* PAD RPC */ #define PAD_FUNC_UNKNOWN 0 diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h index f91f7cc..1c29209 100644 --- a/arch/arm/include/asm/arch-imx8/sci/sci.h +++ b/arch/arm/include/asm/arch-imx8/sci/sci.h @@ -82,6 +82,7 @@ int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl, u32 *val); void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev); void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status); +int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx); void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit); int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val); int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp, diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index 3e38edb..20b74fb 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -374,6 +374,31 @@ void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status) __func__, status, RPC_R8(&msg)); } +int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx) +{ + struct udevice *dev = gd->arch.scu_dev; + int size = sizeof(struct sc_rpc_msg_s); + struct sc_rpc_msg_s msg; + int ret; + + if (!dev) + hang(); + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 1U; + RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC; + RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_CONTAINER; + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret < 0) + return ret; + + if (idx) + *idx = (u8)RPC_U8(&msg, 0U); + + return 0; +} + void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit) { struct udevice *dev = gd->arch.scu_dev; From patchwork Tue Jun 9 10:34:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ye Li X-Patchwork-Id: 241994 List-Id: U-Boot discussion From: ye.li at nxp.com (Ye Li) Date: Tue, 9 Jun 2020 03:34:43 -0700 Subject: [PATCH 2/3] spl: mmc: Move the eMMC boot part index to weak function In-Reply-To: <1591698884-72174-1-git-send-email-ye.li@nxp.com> References: <1591698884-72174-1-git-send-email-ye.li@nxp.com> Message-ID: <1591698884-72174-2-git-send-email-ye.li@nxp.com> Move the default eMMC boot partition index used for SPL load to a weak function. So we can override it in iMX8 specified codes. Because on iMX8 when the emmc regular boot is from boot part0/1, ROM will switch to the other boot part for secondary boot. So we can't directly use the boot part index in PARTITION_CONFIG register, but have to check the secondary boot for using correct boot partition. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- common/spl/spl_mmc.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index add2785..f2880cc 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -324,6 +324,27 @@ unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc, return raw_sect; } +int __weak spl_mmc_emmc_boot_partition(struct mmc *mmc) +{ + int part = 0; + +#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION + part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION; +#else + /* + * We need to check what the partition is configured to. + * 1 and 2 match up to boot0 / boot1 and 7 is user data + * which is the first physical partition (0). + */ + part = (mmc->part_config >> 3) & PART_ACCESS_MASK; + + if (part == 7) + part = 0; +#endif + + return part; +} + int spl_mmc_load(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, const char *filename, @@ -355,19 +376,7 @@ int spl_mmc_load(struct spl_image_info *spl_image, err = -EINVAL; switch (boot_mode) { case MMCSD_MODE_EMMCBOOT: -#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION - part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION; -#else - /* - * We need to check what the partition is configured to. - * 1 and 2 match up to boot0 / boot1 and 7 is user data - * which is the first physical partition (0). - */ - part = (mmc->part_config >> 3) & PART_ACCESS_MASK; - - if (part == 7) - part = 0; -#endif + part = spl_mmc_emmc_boot_partition(mmc); if (CONFIG_IS_ENABLED(MMC_TINY)) err = mmc_switch_part(mmc, part); From patchwork Tue Jun 9 10:34:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ye Li X-Patchwork-Id: 241995 List-Id: U-Boot discussion From: ye.li at nxp.com (Ye Li) Date: Tue, 9 Jun 2020 03:34:44 -0700 Subject: [PATCH 3/3] imx8: spl: Support booting from secondary container set In-Reply-To: <1591698884-72174-1-git-send-email-ye.li@nxp.com> References: <1591698884-72174-1-git-send-email-ye.li@nxp.com> Message-ID: <1591698884-72174-3-git-send-email-ye.li@nxp.com> On i.MX8QM B0 and i.MX8QXP C0, ROM supports to boot from secondary container set when either booting from primary container set is failed or secondary container set has higher SW version. Add the support to SPL to load u-boot container from secondary set when ROM boots from the secondary set. Using the SCFW API to get current container set index. If it is the secondary boot, get the offset from fuse and apply it to the offset of primary container set. For emmc boot from boot0/1 part, override the emmc boot partition function to check secondary boot and switch to correct boot part. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- arch/arm/mach-imx/imx8/image.c | 81 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/imx8/image.c b/arch/arm/mach-imx/imx8/image.c index 5abc0d3..bd0e0a2 100644 --- a/arch/arm/mach-imx/imx8/image.c +++ b/arch/arm/mach-imx/imx8/image.c @@ -20,6 +20,23 @@ #define NAND_DEV 2 #define QSPI_NOR_DEV 3 +/* 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) + +#if IS_ENABLED(CONFIG_IMX8QM) +#define FUSE_IMG_SET_OFF_WORD 464 +#elif IS_ENABLED(CONFIG_IMX8QXP) +#define FUSE_IMG_SET_OFF_WORD 720 +#endif + static int __get_container_size(ulong addr) { struct container_hdr *phdr; @@ -122,15 +139,46 @@ static int get_container_size(void *dev, int dev_type, unsigned long offset) return ret; } +static bool check_secondary_cnt_set(unsigned long *set_off) +{ + 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) { + /* 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(fuse_val); + return true; + } + } + } + } + + 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; + + 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); @@ -140,17 +188,21 @@ 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; } + debug("container set offset 0x%lx\n", offset); + return offset; } @@ -210,6 +262,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 = 0; + + 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