Commit 758535c4 authored by Arindam Nath's avatar Arindam Nath Committed by Chris Ball

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: default avatarArindam Nath <arindam.nath@amd.com>
Reviewed-by: default avatarPhilip Rakity <prakity@marvell.com>
Tested-by: default avatarPhilip Rakity <prakity@marvell.com>
Acked-by: default avatarZhangfei Gao <zhangfei.gao@marvell.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent d6d50a15
...@@ -1243,13 +1243,12 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -1243,13 +1243,12 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else else
ctrl &= ~SDHCI_CTRL_HISPD; ctrl &= ~SDHCI_CTRL_HISPD;
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
if (host->version >= SDHCI_SPEC_300) { if (host->version >= SDHCI_SPEC_300) {
u16 ctrl_2; u16 ctrl_2;
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) { if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/* /*
* We only need to set Driver Strength if the * We only need to set Driver Strength if the
* preset value enable is not set. * preset value enable is not set.
...@@ -1261,8 +1260,30 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -1261,8 +1260,30 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C;
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
} else {
/*
* According to SDHC Spec v3.00, if the Preset Value
* Enable in the Host Control 2 register is set, we
* need to reset SD Clock Enable before changing High
* Speed Enable to avoid generating clock gliches.
*/
u16 clk;
unsigned int clock;
/* Reset SD Clock Enable */
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
clk &= ~SDHCI_CLOCK_CARD_EN;
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/* Re-enable SD Clock */
clock = host->clock;
host->clock = 0;
sdhci_set_clock(host, clock);
} }
} } else
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/* /*
* Some (ENE) controllers go apeshit on some ios operation, * Some (ENE) controllers go apeshit on some ios operation,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment