|
@@ -1148,6 +1148,9 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
|
|
case MMC_TIMING_UHS_DDR50:
|
|
case MMC_TIMING_UHS_DDR50:
|
|
preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
|
|
preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
|
|
break;
|
|
break;
|
|
|
|
+ case MMC_TIMING_MMC_HS400:
|
|
|
|
+ preset = sdhci_readw(host, SDHCI_PRESET_FOR_HS400);
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
pr_warn("%s: Invalid UHS-I mode selected\n",
|
|
pr_warn("%s: Invalid UHS-I mode selected\n",
|
|
mmc_hostname(host->mmc));
|
|
mmc_hostname(host->mmc));
|
|
@@ -1475,6 +1478,8 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
|
|
else if ((timing == MMC_TIMING_UHS_DDR50) ||
|
|
else if ((timing == MMC_TIMING_UHS_DDR50) ||
|
|
(timing == MMC_TIMING_MMC_DDR52))
|
|
(timing == MMC_TIMING_MMC_DDR52))
|
|
ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
|
|
ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
|
|
|
|
+ else if (timing == MMC_TIMING_MMC_HS400)
|
|
|
|
+ ctrl_2 |= SDHCI_CTRL_HS400; /* Non-standard */
|
|
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
|
|
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
|
|
EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
|
|
@@ -1546,7 +1551,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
|
|
u16 clk, ctrl_2;
|
|
u16 clk, ctrl_2;
|
|
|
|
|
|
/* In case of UHS-I modes, set High Speed Enable */
|
|
/* In case of UHS-I modes, set High Speed Enable */
|
|
- if ((ios->timing == MMC_TIMING_MMC_HS200) ||
|
|
|
|
|
|
+ if ((ios->timing == MMC_TIMING_MMC_HS400) ||
|
|
|
|
+ (ios->timing == MMC_TIMING_MMC_HS200) ||
|
|
(ios->timing == MMC_TIMING_MMC_DDR52) ||
|
|
(ios->timing == MMC_TIMING_MMC_DDR52) ||
|
|
(ios->timing == MMC_TIMING_UHS_SDR50) ||
|
|
(ios->timing == MMC_TIMING_UHS_SDR50) ||
|
|
(ios->timing == MMC_TIMING_UHS_SDR104) ||
|
|
(ios->timing == MMC_TIMING_UHS_SDR104) ||
|
|
@@ -1893,6 +1899,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
|
* tuning function has to be executed.
|
|
* tuning function has to be executed.
|
|
*/
|
|
*/
|
|
switch (host->timing) {
|
|
switch (host->timing) {
|
|
|
|
+ case MMC_TIMING_MMC_HS400:
|
|
case MMC_TIMING_MMC_HS200:
|
|
case MMC_TIMING_MMC_HS200:
|
|
case MMC_TIMING_UHS_SDR104:
|
|
case MMC_TIMING_UHS_SDR104:
|
|
break;
|
|
break;
|
|
@@ -3120,6 +3127,10 @@ int sdhci_add_host(struct sdhci_host *host)
|
|
} else if (caps[1] & SDHCI_SUPPORT_SDR50)
|
|
} else if (caps[1] & SDHCI_SUPPORT_SDR50)
|
|
mmc->caps |= MMC_CAP_UHS_SDR50;
|
|
mmc->caps |= MMC_CAP_UHS_SDR50;
|
|
|
|
|
|
|
|
+ if (host->quirks2 & SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 &&
|
|
|
|
+ (caps[1] & SDHCI_SUPPORT_HS400))
|
|
|
|
+ mmc->caps2 |= MMC_CAP2_HS400;
|
|
|
|
+
|
|
if ((mmc->caps2 & MMC_CAP2_HSX00_1_2V) &&
|
|
if ((mmc->caps2 & MMC_CAP2_HSX00_1_2V) &&
|
|
(IS_ERR(mmc->supply.vqmmc) ||
|
|
(IS_ERR(mmc->supply.vqmmc) ||
|
|
!regulator_is_supported_voltage(mmc->supply.vqmmc, 1100000,
|
|
!regulator_is_supported_voltage(mmc->supply.vqmmc, 1100000,
|