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

Reply via email to