aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArindam Nath <arindam.nath@amd.com>2011-05-05 02:49:00 -0400
committerChris Ball <cjb@laptop.org>2011-05-24 23:53:44 -0400
commit758535c4e3cdd2b5b09565d9651aaa541aac3de8 (patch)
tree68675c722181a7d83e19830ee5b1bd50399b8d64 /drivers
parentd6d50a15a2897d4133d536dd4343b5cf21163db3 (diff)
mmc: sdhci: reset sdclk before setting high speed enable
As per Host Controller spec v3.00, we reset SDCLK before setting High Speed Enable, and then set it back to avoid generating clock gliches. Before enabling SDCLK again, we make sure the clock is stable, so we use sdhci_set_clock(). Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath <arindam.nath@amd.com> Reviewed-by: Philip Rakity <prakity@marvell.com> Tested-by: Philip Rakity <prakity@marvell.com> Acked-by: Zhangfei Gao <zhangfei.gao@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/sdhci.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 8072e16d6d46..409cde5970ae 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1243,13 +1243,12 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1243 else 1243 else
1244 ctrl &= ~SDHCI_CTRL_HISPD; 1244 ctrl &= ~SDHCI_CTRL_HISPD;
1245 1245
1246 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1247
1248 if (host->version >= SDHCI_SPEC_300) { 1246 if (host->version >= SDHCI_SPEC_300) {
1249 u16 ctrl_2; 1247 u16 ctrl_2;
1250 1248
1251 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1249 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1252 if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) { 1250 if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
1251 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1253 /* 1252 /*
1254 * We only need to set Driver Strength if the 1253 * We only need to set Driver Strength if the
1255 * preset value enable is not set. 1254 * preset value enable is not set.
@@ -1261,8 +1260,30 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1261 ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; 1260 ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C;
1262 1261
1263 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 1262 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
1263 } else {
1264 /*
1265 * According to SDHC Spec v3.00, if the Preset Value
1266 * Enable in the Host Control 2 register is set, we
1267 * need to reset SD Clock Enable before changing High
1268 * Speed Enable to avoid generating clock gliches.
1269 */
1270 u16 clk;
1271 unsigned int clock;
1272
1273 /* Reset SD Clock Enable */
1274 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1275 clk &= ~SDHCI_CLOCK_CARD_EN;
1276 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1277
1278 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1279
1280 /* Re-enable SD Clock */
1281 clock = host->clock;
1282 host->clock = 0;
1283 sdhci_set_clock(host, clock);
1264 } 1284 }
1265 } 1285 } else
1286 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1266 1287
1267 /* 1288 /*
1268 * Some (ENE) controllers go apeshit on some ios operation, 1289 * Some (ENE) controllers go apeshit on some ios operation,