From: Al Cooper alcooperx@gmail.com
stable inclusion from linux-4.19.198 commit 357251e565560e014acb9180ec9093fc2156241f
--------------------------------
commit d0244847f9fc5e20df8b7483c8a4717fe0432d38 upstream.
When an eMMC device is being run in HS400 mode, any access to the RPMB device will cause the error message "mmc1: Invalid UHS-I mode selected". This happens as a result of tuning being disabled before RPMB access and then re-enabled after the RPMB access is complete. When tuning is re-enabled, the system has to switch from HS400 to HS200 to do the tuning and then back to HS400. As part of sequence to switch from HS400 to HS200 the system is temporarily put into HS mode. When switching to HS mode, sdhci_get_preset_value() is called and does not have support for HS mode and prints the warning message and returns the preset for SDR12. The fix is to add support for MMC and SD HS modes to sdhci_get_preset_value().
This can be reproduced on any system running eMMC in HS400 mode (not HS400ES) by using the "mmc" utility to run the following command: "mmc rpmb read-counter /dev/mmcblk0rpmb".
Signed-off-by: Al Cooper alcooperx@gmail.com Acked-by: Adrian Hunter adrian.hunter@intel.com Fixes: 52983382c74f ("mmc: sdhci: enhance preset value function") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210624163045.33651-1-alcooperx@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/mmc/host/sdhci.c | 4 ++++ drivers/mmc/host/sdhci.h | 1 + 2 files changed, 5 insertions(+)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 499a3d2a8e315..5cb7c2cc501af 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1371,6 +1371,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host) u16 preset = 0;
switch (host->timing) { + case MMC_TIMING_MMC_HS: + case MMC_TIMING_SD_HS: + preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED); + break; case MMC_TIMING_UHS_SDR12: preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); break; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index c0372e3443fdf..2959fed39a385 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -252,6 +252,7 @@
/* 60-FB reserved */
+#define SDHCI_PRESET_FOR_HIGH_SPEED 0x64 #define SDHCI_PRESET_FOR_SDR12 0x66 #define SDHCI_PRESET_FOR_SDR25 0x68 #define SDHCI_PRESET_FOR_SDR50 0x6A