mmc: sdhci: cache timing information locally
authorRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 25 Apr 2014 11:59:31 +0000 (12:59 +0100)
committerChris Ball <chris@printf.net>
Thu, 22 May 2014 12:33:25 +0000 (08:33 -0400)
Rather than reading back the timing information from the registers,
cache it locally.  This allows implementations to translate the UHS
timing by overriding the set_uhs_signaling() method as required
without also having to emulate the SDHCI_HOST_CONTROL2 register.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Stephen Warren <swarren@nvidia.com>
[Ulf Hansson] Resolved conflict
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
drivers/mmc/host/sdhci.c
include/linux/mmc/sdhci.h

index 0073aae0adcbb6c892879cbcb3ff6c87a001cc1f..956799c75df27cab91b2caa1587251bc2b2e2ff4 100644 (file)
@@ -1083,24 +1083,23 @@ static void sdhci_finish_command(struct sdhci_host *host)
 
 static u16 sdhci_get_preset_value(struct sdhci_host *host)
 {
-       u16 ctrl, preset = 0;
+       u16 preset = 0;
 
-       ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-
-       switch (ctrl & SDHCI_CTRL_UHS_MASK) {
-       case SDHCI_CTRL_UHS_SDR12:
+       switch (host->timing) {
+       case MMC_TIMING_UHS_SDR12:
                preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
                break;
-       case SDHCI_CTRL_UHS_SDR25:
+       case MMC_TIMING_UHS_SDR25:
                preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
                break;
-       case SDHCI_CTRL_UHS_SDR50:
+       case MMC_TIMING_UHS_SDR50:
                preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
                break;
-       case SDHCI_CTRL_UHS_SDR104:
+       case MMC_TIMING_UHS_SDR104:
+       case MMC_TIMING_MMC_HS200:
                preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
                break;
-       case SDHCI_CTRL_UHS_DDR50:
+       case MMC_TIMING_UHS_DDR50:
                preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
                break;
        default:
@@ -1538,6 +1537,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
                sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
                host->ops->set_uhs_signaling(host, ios->timing);
+               host->timing = ios->timing;
 
                if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
                                ((ios->timing == MMC_TIMING_UHS_SDR12) ||
@@ -1842,12 +1842,13 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
         * If the Host Controller supports the HS200 mode then the
         * tuning function has to be executed.
         */
-       if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
+       if (host->timing == MMC_TIMING_UHS_SDR50 &&
            (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
             host->flags & SDHCI_SDR104_NEEDS_TUNING))
                requires_tuning_nonuhs = true;
 
-       if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
+       if (host->timing == MMC_TIMING_MMC_HS200 ||
+           host->timing == MMC_TIMING_UHS_SDR104 ||
            requires_tuning_nonuhs)
                ctrl |= SDHCI_CTRL_EXEC_TUNING;
        else {
index 72a90baf111f1bfbc2fca7e5fc6e6ace8fe4b6ec..7f3efbab87327916e1e8a9dd52977054c36ae5a5 100644 (file)
@@ -172,6 +172,8 @@ struct sdhci_host {
        unsigned int            ocr_avail_mmc;
        u32 ocr_mask;           /* available voltages */
 
+       unsigned                timing;         /* Current timing */
+
        u32                     thread_isr;
 
        /* cached registers */