mmc: sdhci-msm: Enable controller power save feature
Enable power save feature within controller by setting bit 1
in vendor specific register (0x10C). This allows controller to
disable SD clock when bus is idle to save power.
Change-Id: I916a5a414adb3f21dc3a75f3f86c3a81d6956dc8
Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
[xiaonian@codeaurora.org: fix trivial merge conflict]
Signed-off-by: Xiaonian Wang <xiaonian@codeaurora.org>
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 0cd7c12..3d79ad6 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2158,6 +2158,7 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
struct sdhci_msm_host *msm_host = pltfm_host->priv;
struct mmc_ios curr_ios = host->mmc->ios;
u32 sup_clock, ddr_clock;
+ bool curr_pwrsave;
if (!clock) {
sdhci_msm_prepare_clocks(host, false);
@@ -2169,6 +2170,22 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
if (rc)
goto out;
+ curr_pwrsave = !!(readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) &
+ CORE_CLK_PWRSAVE);
+ if ((msm_host->clk_rate > 400000) &&
+ !curr_pwrsave && mmc_host_may_gate_card(host->mmc->card))
+ writel_relaxed(readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC)
+ | CORE_CLK_PWRSAVE,
+ host->ioaddr + CORE_VENDOR_SPEC);
+ /*
+ * Disable pwrsave for a newly added card if doesn't allow clock
+ * gating.
+ */
+ else if (curr_pwrsave && !mmc_host_may_gate_card(host->mmc->card))
+ writel_relaxed(readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC)
+ & ~CORE_CLK_PWRSAVE,
+ host->ioaddr + CORE_VENDOR_SPEC);
+
sup_clock = sdhci_msm_get_sup_clk_rate(host, clock);
if ((curr_ios.timing == MMC_TIMING_UHS_DDR50) ||
(curr_ios.timing == MMC_TIMING_MMC_HS400)) {