aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2015-10-28 08:25:41 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2015-11-09 07:16:20 -0500
commit51b12f7764fa8bb464cbd0f7bbd3a408d21ade16 (patch)
treee61ea476673ba3cfc3698ae6daacf23cf12f38a7
parent1815e61b1a7efe81017a883e817292daf7d2f922 (diff)
mmc: mmc: Fix HS setting in mmc_select_hs400()
mmc_select_hs400() begins with the card and host in HS200 mode. Therefore, any commands sent to the card should use HS200 timing. It is incorrect to set the host to High Speed (HS) timing before sending the switch command. Doing so is unreliable because the timing parameters for HS mode are tighter than the timing parameters for HS200 mode. Thus the HS timings should be set only after the card has switched mode. However, it is not unreasonable first to reduce the frequency to the HS mode frequency, which should make the switch command and subsequent CMD13 commands more reliable. This patch does that. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: <stable@vger.kernel.org> # 4.2+ Tested-by: Alim Akhtar <alim.akhtar@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/core/mmc.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 2cef40ce9851..14fb767ee8dd 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1043,6 +1043,7 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
1043static int mmc_select_hs400(struct mmc_card *card) 1043static int mmc_select_hs400(struct mmc_card *card)
1044{ 1044{
1045 struct mmc_host *host = card->host; 1045 struct mmc_host *host = card->host;
1046 unsigned int max_dtr;
1046 int err = 0; 1047 int err = 0;
1047 u8 val; 1048 u8 val;
1048 1049
@@ -1053,13 +1054,11 @@ static int mmc_select_hs400(struct mmc_card *card)
1053 host->ios.bus_width == MMC_BUS_WIDTH_8)) 1054 host->ios.bus_width == MMC_BUS_WIDTH_8))
1054 return 0; 1055 return 0;
1055 1056
1056 /* 1057 /* Reduce frequency to HS frequency */
1057 * Before switching to dual data rate operation for HS400, 1058 max_dtr = card->ext_csd.hs_max_dtr;
1058 * it is required to convert from HS200 mode to HS mode. 1059 mmc_set_clock(host, max_dtr);
1059 */
1060 mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
1061 mmc_set_bus_speed(card);
1062 1060
1061 /* Switch card to HS mode */
1063 val = EXT_CSD_TIMING_HS | 1062 val = EXT_CSD_TIMING_HS |
1064 card->drive_strength << EXT_CSD_DRV_STR_SHIFT; 1063 card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
1065 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1064 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -1072,6 +1071,9 @@ static int mmc_select_hs400(struct mmc_card *card)
1072 return err; 1071 return err;
1073 } 1072 }
1074 1073
1074 /* Set host controller to HS timing */
1075 mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
1076
1075 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1077 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1076 EXT_CSD_BUS_WIDTH, 1078 EXT_CSD_BUS_WIDTH,
1077 EXT_CSD_DDR_BUS_WIDTH_8, 1079 EXT_CSD_DDR_BUS_WIDTH_8,