diff mbox

[U-Boot,v2,15/15] mmc: Change frequency while accessing to boot partition

Message ID 1485772712-4653-16-git-send-email-sivadur@xilinx.com
State Changes Requested
Delegated to: Jaehoon Chung
Headers show

Commit Message

Siva Durga Prasad Paladugu Jan. 30, 2017, 10:38 a.m. UTC
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>
---
Changes from v1:
- Added this in series as per review comment
---
 drivers/mmc/mmc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     |  2 ++
 2 files changed, 60 insertions(+)
diff mbox

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 02c0408..be6003f 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 e0b5510..6f9a41c 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 {