aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-04-25 08:00:12 -0400
committerChris Ball <chris@printf.net>2014-05-22 08:33:30 -0400
commitda91a8f9c0f56d75b35bfe2e2456187ab55b3639 (patch)
tree0b1eb88167d37461dc1d9aa56919f715e61095b1
parent24fbb3ca1468861e5ac33a26c4130610ae8d0e20 (diff)
mmc: sdhci: track whether preset mode is currently enabled in hardware
Track whether preset mode is currently enabled in hardware, and use that when making decisions elsewhere in the code rather than reading the register and checking the bit. 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> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
-rw-r--r--drivers/mmc/host/sdhci.c44
-rw-r--r--include/linux/mmc/sdhci.h1
2 files changed, 27 insertions, 18 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index effd9e5d1d81..447eef8217c7 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -205,9 +205,14 @@ static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
205 205
206 host->ops->reset(host, mask); 206 host->ops->reset(host, mask);
207 207
208 if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 208 if (mask & SDHCI_RESET_ALL) {
209 if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL)) 209 if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
210 host->ops->enable_dma(host); 210 if (host->ops->enable_dma)
211 host->ops->enable_dma(host);
212 }
213
214 /* Resetting the controller clears many */
215 host->preset_enabled = false;
211 } 216 }
212} 217}
213 218
@@ -1126,8 +1131,7 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
1126 return; 1131 return;
1127 1132
1128 if (host->version >= SDHCI_SPEC_300) { 1133 if (host->version >= SDHCI_SPEC_300) {
1129 if (sdhci_readw(host, SDHCI_HOST_CONTROL2) & 1134 if (host->preset_enabled) {
1130 SDHCI_CTRL_PRESET_VAL_ENABLE) {
1131 u16 pre_val; 1135 u16 pre_val;
1132 1136
1133 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 1137 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
@@ -1493,13 +1497,13 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1493 (ios->timing == MMC_TIMING_UHS_SDR25)) 1497 (ios->timing == MMC_TIMING_UHS_SDR25))
1494 ctrl |= SDHCI_CTRL_HISPD; 1498 ctrl |= SDHCI_CTRL_HISPD;
1495 1499
1496 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1500 if (!host->preset_enabled) {
1497 if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
1498 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1501 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1499 /* 1502 /*
1500 * We only need to set Driver Strength if the 1503 * We only need to set Driver Strength if the
1501 * preset value enable is not set. 1504 * preset value enable is not set.
1502 */ 1505 */
1506 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1503 ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; 1507 ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
1504 if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) 1508 if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
1505 ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; 1509 ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
@@ -2018,26 +2022,30 @@ out:
2018 2022
2019static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) 2023static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
2020{ 2024{
2021 u16 ctrl;
2022
2023 /* Host Controller v3.00 defines preset value registers */ 2025 /* Host Controller v3.00 defines preset value registers */
2024 if (host->version < SDHCI_SPEC_300) 2026 if (host->version < SDHCI_SPEC_300)
2025 return; 2027 return;
2026 2028
2027 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
2028
2029 /* 2029 /*
2030 * We only enable or disable Preset Value if they are not already 2030 * We only enable or disable Preset Value if they are not already
2031 * enabled or disabled respectively. Otherwise, we bail out. 2031 * enabled or disabled respectively. Otherwise, we bail out.
2032 */ 2032 */
2033 if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { 2033 if (host->preset_enabled != enable) {
2034 ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE; 2034 u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
2035 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 2035
2036 host->flags |= SDHCI_PV_ENABLED; 2036 if (enable)
2037 } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { 2037 ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
2038 ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE; 2038 else
2039 ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
2040
2039 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 2041 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
2040 host->flags &= ~SDHCI_PV_ENABLED; 2042
2043 if (enable)
2044 host->flags |= SDHCI_PV_ENABLED;
2045 else
2046 host->flags &= ~SDHCI_PV_ENABLED;
2047
2048 host->preset_enabled = enable;
2041 } 2049 }
2042} 2050}
2043 2051
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 7f3efbab8732..08abe9941884 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -143,6 +143,7 @@ struct sdhci_host {
143 143
144 bool runtime_suspended; /* Host is runtime suspended */ 144 bool runtime_suspended; /* Host is runtime suspended */
145 bool bus_on; /* Bus power prevents runtime suspend */ 145 bool bus_on; /* Bus power prevents runtime suspend */
146 bool preset_enabled; /* Preset is enabled */
146 147
147 struct mmc_request *mrq; /* Current request */ 148 struct mmc_request *mrq; /* Current request */
148 struct mmc_command *cmd; /* Current command */ 149 struct mmc_command *cmd; /* Current command */