aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */