mmc: sdhci-msm: fix pwrsave bit handling
SDCC controller provides the PWRSAVE control bit to automatically disable the clock to card when there is no activity with card. During the SDCC DLL tuning, PWRSAVE is disabled to make sure that clock is always running but once the DLL tuning is completed, currently we enable the PWRSAVE unconditionally irrespective of its previous state. This change ensures that we always check if the previous state of pwrsave before really enabling it. Change-Id: I464ab1e0db41af50550bb5a9ea9b909ee0d27dd9 Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
parent
5af7b3e981
commit
cec2ab9ba3
1 changed files with 22 additions and 8 deletions
|
@ -483,19 +483,25 @@ static int msm_init_cm_dll(struct sdhci_host *host)
|
|||
int rc = 0;
|
||||
unsigned long flags;
|
||||
u32 wait_cnt;
|
||||
bool prev_pwrsave, curr_pwrsave;
|
||||
|
||||
pr_debug("%s: Enter %s\n", mmc_hostname(mmc), __func__);
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
prev_pwrsave = !!(readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) &
|
||||
CORE_CLK_PWRSAVE);
|
||||
curr_pwrsave = prev_pwrsave;
|
||||
/*
|
||||
* Make sure that clock is always enabled when DLL
|
||||
* tuning is in progress. Keeping PWRSAVE ON may
|
||||
* turn off the clock. So let's disable the PWRSAVE
|
||||
* here and re-enable it once tuning is completed.
|
||||
*/
|
||||
writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC)
|
||||
& ~CORE_CLK_PWRSAVE),
|
||||
host->ioaddr + CORE_VENDOR_SPEC);
|
||||
if (prev_pwrsave) {
|
||||
writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC)
|
||||
& ~CORE_CLK_PWRSAVE),
|
||||
host->ioaddr + CORE_VENDOR_SPEC);
|
||||
curr_pwrsave = false;
|
||||
}
|
||||
|
||||
/* Write 1 to DLL_RST bit of DLL_CONFIG register */
|
||||
writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
|
||||
|
@ -538,10 +544,18 @@ static int msm_init_cm_dll(struct sdhci_host *host)
|
|||
}
|
||||
|
||||
out:
|
||||
/* re-enable PWRSAVE */
|
||||
writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) |
|
||||
CORE_CLK_PWRSAVE),
|
||||
host->ioaddr + CORE_VENDOR_SPEC);
|
||||
/* Restore the correct PWRSAVE state */
|
||||
if (prev_pwrsave ^ curr_pwrsave) {
|
||||
u32 reg = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
|
||||
|
||||
if (prev_pwrsave)
|
||||
reg |= CORE_CLK_PWRSAVE;
|
||||
else
|
||||
reg &= ~CORE_CLK_PWRSAVE;
|
||||
|
||||
writel_relaxed(reg, host->ioaddr + CORE_VENDOR_SPEC);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
pr_debug("%s: Exit %s\n", mmc_hostname(mmc), __func__);
|
||||
return rc;
|
||||
|
|
Loading…
Add table
Reference in a new issue