diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2014-11-06 15:19:06 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-11-26 14:30:52 +0100 |
commit | e9fb05d5bca7428f2749d059559e9657c710fe53 (patch) | |
tree | c40a0e88bb11bf805453d651df9dc451d12acab5 /drivers/mmc/host/sdhci.c | |
parent | 549c0b18485d10bb419a81b24efe719df75089bd (diff) | |
download | blackbird-op-linux-e9fb05d5bca7428f2749d059559e9657c710fe53.tar.gz blackbird-op-linux-e9fb05d5bca7428f2749d059559e9657c710fe53.zip |
mmc: sdhci: Add HS400 support to SDHCI driver
MMC core already has support for HS400. Add HS400
support to SDHCI driver. The SDHC Standard specification
does not define HS400 so consequently HS400 support is
non-standard. However HS400 is not selected without
the host controller setting the corresponding capability
flags so host controllers not yet supporting HS400
will not be affected. To support that, a quirk
SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 is introduced to
enable the use of capabilities register reserved bit-63
to indicate HS400 support.
Because HS400 is non-standard for SDHCI, it is possible
that different vendors will do things in different ways.
However HS200 support faced the same issue but currently
there is only one solution. As such, no attempt has
been made to provide for alternate HS400 solutions except
for SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 5589563761f8..73de62a58d70 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1148,6 +1148,9 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host) case MMC_TIMING_UHS_DDR50: preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50); break; + case MMC_TIMING_MMC_HS400: + preset = sdhci_readw(host, SDHCI_PRESET_FOR_HS400); + break; default: pr_warn("%s: Invalid UHS-I mode selected\n", 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) || (timing == MMC_TIMING_MMC_DDR52)) 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); } 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; /* 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_UHS_SDR50) || (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. */ switch (host->timing) { + case MMC_TIMING_MMC_HS400: case MMC_TIMING_MMC_HS200: case MMC_TIMING_UHS_SDR104: break; @@ -3120,6 +3127,10 @@ int sdhci_add_host(struct sdhci_host *host) } else if (caps[1] & SDHCI_SUPPORT_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) && (IS_ERR(mmc->supply.vqmmc) || !regulator_is_supported_voltage(mmc->supply.vqmmc, 1100000, |