]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
mmc: Change frequency while accessing to boot partition
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Wed, 1 Feb 2017 19:40:54 +0000 (01:10 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 2 Feb 2017 09:29:59 +0000 (10:29 +0100)
Boot partition is not supported in HS200 mode, hence change
clock to high speed while accessing boot partition and
revert back when partition is switching to other than boot
partition

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/mmc/mmc.c
include/mmc.h

index 7e18a38165b28b870ce015b16eddb422c081fe7f..1a240ba9b143243f804fc4e71c67b80ae3ea305a 100644 (file)
@@ -621,6 +621,9 @@ static int mmc_change_freq(struct mmc *mmc)
 
        cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
 
+       if (mmc->forcehs)
+               cardtype &= ~EXT_CSD_CARD_TYPE_HS200;
+
        if (cardtype & EXT_CSD_CARD_TYPE_HS200)
                err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_HS_TIMING,
@@ -685,10 +688,65 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
        return 0;
 }
 
+static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
+{
+       int ret;
+
+       if (((part_num & PART_ACCESS_MASK) == PART_ACCESS_BOOT0) &&
+           (mmc->card_caps == MMC_MODE_HS200)) {
+               mmc->forcehs = 1;
+               ret = mmc_change_freq(mmc);
+               if (ret)
+                       return ret;
+
+               mmc->card_caps &= mmc->cfg->host_caps;
+               if (mmc->card_caps & MMC_MODE_HS) {
+                       if (mmc->card_caps & MMC_MODE_HS_52MHz)
+                               mmc->tran_speed = 52000000;
+                       else
+                               mmc->tran_speed = 26000000;
+               }
+               mmc_set_clock(mmc, mmc->tran_speed);
+       }
+
+       if (((part_num & PART_ACCESS_MASK) != PART_ACCESS_BOOT0) &&
+           mmc->forcehs) {
+               mmc->forcehs = 0;
+               ret = mmc_change_freq(mmc);
+               if (ret)
+                       return ret;
+
+               mmc->card_caps &= mmc->cfg->host_caps;
+               if (mmc->card_caps & MMC_MODE_HS200) {
+                       mmc->tran_speed = 200000000;
+               } else if (mmc->card_caps & MMC_MODE_HS) {
+                       if (mmc->card_caps & MMC_MODE_HS_52MHz)
+                               mmc->tran_speed = 52000000;
+                       else
+                               mmc->tran_speed = 26000000;
+               }
+
+               mmc_set_clock(mmc, mmc->tran_speed);
+
+               if ((mmc->card_caps &  MMC_MODE_HS200) &&
+                   (mmc->cfg->host_caps & MMC_MODE_NEEDS_TUNING)) {
+                       ret = mmc_execute_tuning(mmc);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
 int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
        int ret;
 
+       ret = mmc_boot_part_access_chk(mmc, part_num);
+       if (ret)
+               return ret;
+
        ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
                         (mmc->part_config & ~PART_ACCESS_MASK)
                         | (part_num & PART_ACCESS_MASK));
index 4d99c8b7610614dfa65647a2461b00537bf21888..7d1484dc40daa0a1245a0e78ff03ad7010a401f2 100644 (file)
 
 #define MMCPART_NOAVAILABLE    (0xff)
 #define PART_ACCESS_MASK       (0x7)
+#define PART_ACCESS_BOOT0      (0x2)
 #define PART_SUPPORT           (0x1)
 #define ENHNCD_SUPPORT         (0x2)
 #define PART_ENH_ATTRIB                (0x1f)
@@ -522,6 +523,7 @@ struct mmc {
 #endif
        u8 is_uhs;
        u8 uhsmode;
+       u8 forcehs;
 };
 
 struct mmc_hwpart_conf {