From 37e4d7ca4a83fb0a2a11e74063cefbe144ff5f64 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Thu, 2 Feb 2017 01:10:54 +0530 Subject: [PATCH] mmc: Change frequency while accessing to boot partition 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 Signed-off-by: Michal Simek --- drivers/mmc/mmc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++ include/mmc.h | 2 ++ 2 files changed, 60 insertions(+) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 7e18a38165b..1a240ba9b14 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -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)); diff --git a/include/mmc.h b/include/mmc.h index 4d99c8b7610..7d1484dc40d 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -282,6 +282,7 @@ #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 { -- 2.47.3