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: Pierre Ossman <pierre@ossman.eu>
This commit is contained in:
@@ -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)
|
|||||||
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);
|
||||||
|
|
||||||
|
pwr |= SDHCI_POWER_ON;
|
||||||
|
|
||||||
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
|
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
|
||||||
|
|
||||||
out:
|
|
||||||
host->power = power;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************\
|
/*****************************************************************************\
|
||||||
|
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user