summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Cooper <alcooperx@gmail.com>2019-09-03 07:51:14 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-10-05 13:13:56 +0200
commitd32263d8b9b5525df9053b1b177d7e3f2198f7ed (patch)
treeea6673ae88dfa6928f050bfcb2e12d650f3f51f7
parentde6fea9fcf1e8b6fac38810c57b65f7fe553c29f (diff)
downloadlinux-stable-d32263d8b9b5525df9053b1b177d7e3f2198f7ed.tar.gz
linux-stable-d32263d8b9b5525df9053b1b177d7e3f2198f7ed.tar.bz2
linux-stable-d32263d8b9b5525df9053b1b177d7e3f2198f7ed.zip
mmc: sdhci: Fix incorrect switch to HS mode
[ Upstream commit c894e33ddc1910e14d6f2a2016f60ab613fd8b37 ] When switching from any MMC speed mode that requires 1.8v (HS200, HS400 and HS400ES) to High Speed (HS) mode, the system ends up configured for SDR12 with a 50MHz clock which is an illegal mode. This happens because the SDHCI_CTRL_VDD_180 bit in the SDHCI_HOST_CONTROL2 register is left set and when this bit is set, the speed mode is controlled by the SDHCI_CTRL_UHS field in the SDHCI_HOST_CONTROL2 register. The SDHCI_CTRL_UHS field will end up being set to 0 (SDR12) by sdhci_set_uhs_signaling() because there is no UHS mode being set. The fix is to change sdhci_set_uhs_signaling() to set the SDHCI_CTRL_UHS field to SDR25 (which is the same as HS) for any switch to HS mode. This was found on a new eMMC controller that does strict checking of the speed mode and the corresponding clock rate. It caused the switch to HS400 mode to fail because part of the sequence to switch to HS400 requires a switch from HS200 to HS before going to HS400. Suggested-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Al Cooper <alcooperx@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/mmc/host/sdhci.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a5dc5aae973e..c66e66fbaeb4 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1849,7 +1849,9 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
else if (timing == MMC_TIMING_UHS_SDR12)
ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
- else if (timing == MMC_TIMING_UHS_SDR25)
+ else if (timing == MMC_TIMING_SD_HS ||
+ timing == MMC_TIMING_MMC_HS ||
+ timing == MMC_TIMING_UHS_SDR25)
ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
else if (timing == MMC_TIMING_UHS_SDR50)
ctrl_2 |= SDHCI_CTRL_UHS_SDR50;