summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1c828e0e9905..1b3fbd9bd5c5 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1029,7 +1029,9 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
if (data == NULL) {
if (host->quirks2 &
SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD) {
- sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE);
+ /* must not clear SDHCI_TRANSFER_MODE when tuning */
+ if (cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200)
+ sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE);
} else {
/* clear Auto CMD settings for no data CMDs */
mode = sdhci_readw(host, SDHCI_TRANSFER_MODE);
@@ -2103,7 +2105,7 @@ static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
return 0;
}
-static void sdhci_start_tuning(struct sdhci_host *host)
+void sdhci_start_tuning(struct sdhci_host *host)
{
u16 ctrl;
@@ -2126,14 +2128,16 @@ static void sdhci_start_tuning(struct sdhci_host *host)
sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
}
+EXPORT_SYMBOL_GPL(sdhci_start_tuning);
-static void sdhci_end_tuning(struct sdhci_host *host)
+void sdhci_end_tuning(struct sdhci_host *host)
{
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
}
+EXPORT_SYMBOL_GPL(sdhci_end_tuning);
-static void sdhci_reset_tuning(struct sdhci_host *host)
+void sdhci_reset_tuning(struct sdhci_host *host)
{
u16 ctrl;
@@ -2142,6 +2146,7 @@ static void sdhci_reset_tuning(struct sdhci_host *host)
ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
}
+EXPORT_SYMBOL_GPL(sdhci_reset_tuning);
static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode)
{
@@ -2162,7 +2167,7 @@ static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode)
* interrupt setup is different to other commands and there is no timeout
* interrupt so special handling is needed.
*/
-static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
+void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
{
struct mmc_host *mmc = host->mmc;
struct mmc_command cmd = {};
@@ -2212,6 +2217,7 @@ static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
msecs_to_jiffies(50));
}
+EXPORT_SYMBOL_GPL(sdhci_send_tuning);
static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
{
@@ -3734,14 +3740,21 @@ int sdhci_setup_host(struct sdhci_host *host)
mmc_gpio_get_cd(host->mmc) < 0)
mmc->caps |= MMC_CAP_NEEDS_POLL;
- /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
if (!IS_ERR(mmc->supply.vqmmc)) {
ret = regulator_enable(mmc->supply.vqmmc);
+
+ /* If vqmmc provides no 1.8V signalling, then there's no UHS */
if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000,
1950000))
host->caps1 &= ~(SDHCI_SUPPORT_SDR104 |
SDHCI_SUPPORT_SDR50 |
SDHCI_SUPPORT_DDR50);
+
+ /* In eMMC case vqmmc might be a fixed 1.8V regulator */
+ if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 2700000,
+ 3600000))
+ host->flags &= ~SDHCI_SIGNALING_330;
+
if (ret) {
pr_warn("%s: Failed to enable vqmmc regulator: %d\n",
mmc_hostname(mmc), ret);