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,12 +1005,34 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) ...@@ -1005,12 +1005,34 @@ 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)
pwr = 0;
else {
switch (1 << power) {
case MMC_VDD_165_195:
pwr = SDHCI_POWER_180;
break;
case MMC_VDD_29_30:
case MMC_VDD_30_31:
pwr = SDHCI_POWER_300;
break;
case MMC_VDD_32_33:
case MMC_VDD_33_34:
pwr = SDHCI_POWER_330;
break;
default:
BUG();
}
}
if (host->pwr == pwr)
return; return;
if (power == (unsigned short)-1) { host->pwr = pwr;
if (pwr == 0) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
goto out; return;
} }
/* /*
...@@ -1020,35 +1042,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) ...@@ -1020,35 +1042,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
pwr = SDHCI_POWER_ON;
switch (1 << power) {
case MMC_VDD_165_195:
pwr |= SDHCI_POWER_180;
break;
case MMC_VDD_29_30:
case MMC_VDD_30_31:
pwr |= SDHCI_POWER_300;
break;
case MMC_VDD_32_33:
case MMC_VDD_33_34:
pwr |= SDHCI_POWER_330;
break;
default:
BUG();
}
/* /*
* 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); pwr |= SDHCI_POWER_ON;
out: sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
host->power = power;
} }
/*****************************************************************************\ /*****************************************************************************\
......
...@@ -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