From 6919f81092e9c5ce35ff2c3e06e139c17bed86f8 Mon Sep 17 00:00:00 2001 From: Can Guo Date: Sat, 9 Mar 2019 13:19:47 +0800 Subject: [PATCH 1/2] mmc: core: Init mmc host clock scaling suspend state We track the mmc clock scaling state using mmc host's flag is_suspended. During the first SD card removal event, the mmc driver suspends the clock scaling to cancel any pending scaling work; however, the is_suspended flag value remains set to TRUE. When the SD card is inserted and removed again, the mmc shall not suspend the clock scaling because the is_suspended flag is set to TRUE. Resetting the mmc host clock scaling's is_suspended to FALSE during the clock scaling initialization to ensure that the driver suspend the clock scaling properly for subsequent card removal events. Change-Id: If8bc6c3f4a545900dd1d783d2cfdf2bfd164073d Signed-off-by: Can Guo --- drivers/mmc/core/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 5c9ee93ac10b..6c887347d3a2 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -627,6 +627,7 @@ int mmc_init_clk_scaling(struct mmc_host *host) host->ios.clock); host->clk_scaling.enable = true; + host->clk_scaling.is_suspended = false; return err; } From 08115536e9694424b86a2df1d1949e2a29f28839 Mon Sep 17 00:00:00 2001 From: Jun Li Date: Fri, 6 Nov 2020 10:56:21 +0800 Subject: [PATCH 2/2] mmc: sdhci-msm: Set PWRSAVE bit to '0' during tuning Set PWRSAVE bit to '0' before tuning, and set it to the initial value after completion of tuning. Make sure that PWRSAVE bit is set to '0' during tuning according to HPG. Change-Id: Id32213f435b8b73cbaebff8b6068f37b93259925 Signed-off-by: Jun Li --- drivers/mmc/host/sdhci-msm.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 203a0f3d0f3a..b2c1fdffbf6e 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1403,10 +1403,16 @@ static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) struct sdhci_host *host = mmc_priv(mmc); int tuning_seq_cnt = 3; u8 phase, tuned_phases[16], tuned_phase_cnt = 0; - int rc; + int rc = 0; struct mmc_ios ios = host->mmc->ios; + u32 core_vendor_spec; struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); + const struct sdhci_msm_offset *msm_offset = + sdhci_priv_msm_offset(host); + + core_vendor_spec = readl_relaxed(host->ioaddr + + msm_offset->core_vendor_spec); if (!sdhci_msm_is_tuning_needed(host)) { msm_host->use_cdr = false; @@ -1434,19 +1440,23 @@ static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) host->flags &= ~SDHCI_HS400_TUNING; } + /* Make sure that PWRSAVE bit is set to '0' during tuning */ + writel_relaxed((core_vendor_spec & ~CORE_CLK_PWRSAVE), + host->ioaddr + + msm_offset->core_vendor_spec); + retry: /* First of all reset the tuning block */ rc = msm_init_cm_dll(host, DLL_INIT_NORMAL); if (rc) - return rc; + goto out; phase = 0; do { /* Set the phase in delay line hw block */ rc = msm_config_cm_dll_phase(host, phase); if (rc) - return rc; - + goto out; rc = mmc_send_tuning(mmc, opcode, NULL); if (!rc) { /* Tuning is successful at this tuning point */ @@ -1460,7 +1470,7 @@ retry: rc = msm_find_most_appropriate_phase(host, tuned_phases, tuned_phase_cnt); if (rc < 0) - return rc; + goto out; else phase = rc; @@ -1470,7 +1480,7 @@ retry: */ rc = msm_config_cm_dll_phase(host, phase); if (rc) - return rc; + goto out; msm_host->saved_tuning_phase = phase; dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", mmc_hostname(mmc), phase); @@ -1485,6 +1495,15 @@ retry: if (!rc) msm_host->tuning_done = true; +out: + /* Set PWRSAVE bit to '1' after completion of tuning as needed */ + if (core_vendor_spec & CORE_CLK_PWRSAVE) { + writel_relaxed((readl_relaxed(host->ioaddr + + msm_offset->core_vendor_spec) + | CORE_CLK_PWRSAVE), host->ioaddr + + msm_offset->core_vendor_spec); + } + return rc; }