Commit ae628903 authored by Pierre Ossman's avatar Pierre Ossman

sdhci: avoid changing voltage needlessly

Because of granularity issues, sometimes we told the hardware to change
to the voltage we were already at. Rework the logic so this doesn't
happen.
Signed-off-by: default avatarPierre Ossman <pierre@ossman.eu>
parent 7ceeb6a4
...@@ -1005,50 +1005,53 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) ...@@ -1005,50 +1005,53 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
{ {
u8 pwr; u8 pwr;
if (host->power == power) if (power == (unsigned short)-1)
return; pwr = 0;
else {
if (power == (unsigned short)-1) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
goto out;
}
/*
* Spec says that we should clear the power reg before setting
* a new value. Some controllers don't seem to like this though.
*/
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
pwr = SDHCI_POWER_ON;
switch (1 << power) { switch (1 << power) {
case MMC_VDD_165_195: case MMC_VDD_165_195:
pwr |= SDHCI_POWER_180; pwr = SDHCI_POWER_180;
break; break;
case MMC_VDD_29_30: case MMC_VDD_29_30:
case MMC_VDD_30_31: case MMC_VDD_30_31:
pwr |= SDHCI_POWER_300; pwr = SDHCI_POWER_300;
break; break;
case MMC_VDD_32_33: case MMC_VDD_32_33:
case MMC_VDD_33_34: case MMC_VDD_33_34:
pwr |= SDHCI_POWER_330; pwr = SDHCI_POWER_330;
break; break;
default: default:
BUG(); BUG();
} }
}
if (host->pwr == pwr)
return;
host->pwr = pwr;
if (pwr == 0) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
return;
}
/*
* Spec says that we should clear the power reg before setting
* a new value. Some controllers don't seem to like this though.
*/
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
/* /*
* At least the Marvell CaFe chip gets confused if we set the voltage * At least the Marvell CaFe chip gets confused if we set the voltage
* and set turn on power at the same time, so set the voltage first. * and set turn on power at the same time, so set the voltage first.
*/ */
if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
out: pwr |= SDHCI_POWER_ON;
host->power = power;
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
} }
/*****************************************************************************\ /*****************************************************************************\
......
...@@ -255,7 +255,7 @@ struct sdhci_host { ...@@ -255,7 +255,7 @@ struct sdhci_host {
unsigned int timeout_clk; /* Timeout freq (KHz) */ unsigned int timeout_clk; /* Timeout freq (KHz) */
unsigned int clock; /* Current clock (MHz) */ unsigned int clock; /* Current clock (MHz) */
unsigned short power; /* Current voltage */ u8 pwr; /* Current voltage */
struct mmc_request *mrq; /* Current request */ struct mmc_request *mrq; /* Current request */
struct mmc_command *cmd; /* Current command */ struct mmc_command *cmd; /* Current command */
......
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