Decode the PBL boot-configuration register once and use it for MMC preparation, FIT partition lookup, and SPL boot-device reporting.
Map eMMC to MMC1/sequence 0 and SD to MMC2/sequence 1. When PBL selects SD, enable polling for that device because SPL does not resolve the optional card-detect GPIO. Signed-off-by: Abhilash V <[email protected]> --- board/qualcomm/shikra/spl-shikra.c | 99 ++++++++++++++++++------------ 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/board/qualcomm/shikra/spl-shikra.c b/board/qualcomm/shikra/spl-shikra.c index 091a2a49e09..00952d7769a 100644 --- a/board/qualcomm/shikra/spl-shikra.c +++ b/board/qualcomm/shikra/spl-shikra.c @@ -149,6 +149,32 @@ enum { IPQ_SPL_BOOTCFG_DEV_MAX }; +static int shikra_boot_device(int *mmc_seq) +{ + u8 boot_device_cfg; + + boot_device_cfg = + (readl(IPQ_SPL_BOOTCFG_REG_ADDR) & IPQ_SPL_BOOTCFG_DEV_MASK) >> + IPQ_SPL_BOOTCFG_DEV_SHFT; + + switch (boot_device_cfg) { + case IPQ_SPL_BOOTCFG_DEV_MMC: + if (mmc_seq) + *mmc_seq = 0; + return BOOT_DEVICE_MMC1; + case IPQ_SPL_BOOTCFG_DEV_SD_EMMC: + if (mmc_seq) + *mmc_seq = 1; + return BOOT_DEVICE_MMC2; + case IPQ_SPL_BOOTCFG_DEV_EDL: + return BOOT_DEVICE_USB; + case IPQ_SPL_BOOTCFG_DEV_NAND: + return BOOT_DEVICE_NAND; + default: + return -EINVAL; + } +} + #if defined(CONFIG_SPL_BUILD) /** * shikra_prepare_qup_clocks() - Enable QUP wrapper clocks. @@ -197,23 +223,11 @@ static int shikra_prepare_boot_mmc(void) { struct udevice *dev; struct mmc *mmc; - u8 boot_device_cfg; - int seq, ret; + int boot_device, seq, ret; - boot_device_cfg = - (readl(IPQ_SPL_BOOTCFG_REG_ADDR) & IPQ_SPL_BOOTCFG_DEV_MASK) >> - IPQ_SPL_BOOTCFG_DEV_SHFT; - - switch (boot_device_cfg) { - case IPQ_SPL_BOOTCFG_DEV_MMC: - seq = 0; - break; - case IPQ_SPL_BOOTCFG_DEV_SD_EMMC: - seq = 1; - break; - default: - return 0; - } + boot_device = shikra_boot_device(&seq); + if (boot_device != BOOT_DEVICE_MMC1 && boot_device != BOOT_DEVICE_MMC2) + return -ENODEV; ret = uclass_get_device_by_seq(UCLASS_MMC, seq, &dev); if (ret) @@ -223,6 +237,13 @@ static int shikra_prepare_boot_mmc(void) if (!mmc) return -ENODEV; + /* + * SPL cannot resolve the SD card-detect GPIO from its live device tree. + * PBL selected this device as the boot source, so poll it for the card. + */ + if (boot_device == BOOT_DEVICE_MMC2) + ((struct mmc_config *)mmc->cfg)->host_caps |= MMC_CAP_NEEDS_POLL; + return mmc_init(mmc); } @@ -404,13 +425,20 @@ int spl_mmc_boot_partition(struct mmc *mmc, const u32 boot_device) { struct blk_desc *desc; struct disk_partition info; - int partition; + int mmc_seq, partition; if (!IS_ENABLED(CONFIG_MMC)) return -ENOSYS; + /* + * The MMC core selected @mmc from @boot_device. Confirm that it is + * the device PBL configured before searching it for the FIT partition. + */ + if (shikra_boot_device(&mmc_seq) != boot_device) + return -ENODEV; + desc = mmc_get_blk_desc(mmc); - if (!desc) + if (!desc || desc->devnum != mmc_seq) return -ENODEV; partition = part_get_info_by_name(desc, QCOM_SPL_FIT_IMG_PARTITION, @@ -428,33 +456,28 @@ int spl_mmc_boot_partition(struct mmc *mmc, const u32 boot_device) */ u32 spl_boot_device(void) { - u8 boot_device_cfg = - (readl(IPQ_SPL_BOOTCFG_REG_ADDR) & IPQ_SPL_BOOTCFG_DEV_MASK) >> - IPQ_SPL_BOOTCFG_DEV_SHFT; - u32 boot_device_smem; + int boot_device; - switch (boot_device_cfg) { - case IPQ_SPL_BOOTCFG_DEV_MMC: - boot_device_smem = BOOT_DEVICE_MMC1; + boot_device = shikra_boot_device(NULL); + if (boot_device < 0) { + pr_err("Invalid boot device configured\n"); + return boot_device; + } + + switch (boot_device) { + case BOOT_DEVICE_MMC1: printf("Selected boot device: MMC\n"); break; - case IPQ_SPL_BOOTCFG_DEV_SD_EMMC: - boot_device_smem = BOOT_DEVICE_MMC2; + case BOOT_DEVICE_MMC2: printf("Selected boot device: SD MMC\n"); break; - case IPQ_SPL_BOOTCFG_DEV_EDL: - boot_device_smem = BOOT_DEVICE_USB; - printf("Selected boot device: SPI-NAND\n"); + case BOOT_DEVICE_USB: + printf("Selected boot device: USB\n"); break; - case IPQ_SPL_BOOTCFG_DEV_NAND: - boot_device_smem = BOOT_DEVICE_NAND; - printf("Selected boot device: SPI-NAND\n"); + case BOOT_DEVICE_NAND: + printf("Selected boot device: NAND\n"); break; - default: - pr_err("Invalid boot device configured: %d\n", - boot_device_cfg); - return -EINVAL; } - return boot_device_smem; + return boot_device; } -- 2.34.1
