writel_relaxed(val, host->ioaddr + offset);
}
-static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host,
- unsigned int clock)
+static unsigned int msm_get_clock_mult_for_bus_mode(struct sdhci_host *host)
{
struct mmc_ios ios = host->mmc->ios;
/*
ios.timing == MMC_TIMING_MMC_DDR52 ||
ios.timing == MMC_TIMING_MMC_HS400 ||
host->flags & SDHCI_HS400_TUNING)
- clock *= 2;
- return clock;
+ return 2;
+ return 1;
}
static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host,
struct mmc_ios curr_ios = host->mmc->ios;
struct clk *core_clk = msm_host->bulk_clks[0].clk;
unsigned long achieved_rate;
+ unsigned int desired_rate;
+ unsigned int mult;
int rc;
- clock = msm_get_clock_rate_for_bus_mode(host, clock);
- rc = dev_pm_opp_set_rate(mmc_dev(host->mmc), clock);
+ mult = msm_get_clock_mult_for_bus_mode(host);
+ desired_rate = clock * mult;
+ rc = dev_pm_opp_set_rate(mmc_dev(host->mmc), desired_rate);
if (rc) {
pr_err("%s: Failed to set clock at rate %u at timing %d\n",
- mmc_hostname(host->mmc), clock,
- curr_ios.timing);
+ mmc_hostname(host->mmc), desired_rate, curr_ios.timing);
return;
}
* encounter it.
*/
achieved_rate = clk_get_rate(core_clk);
- if (achieved_rate > clock)
+ if (achieved_rate > desired_rate)
pr_warn("%s: Card appears overclocked; req %u Hz, actual %lu Hz\n",
- mmc_hostname(host->mmc), clock, achieved_rate);
+ mmc_hostname(host->mmc), desired_rate, achieved_rate);
+ host->mmc->actual_clock = achieved_rate / mult;
+
+ /* Stash the rate we requested to use in sdhci_msm_runtime_resume() */
+ msm_host->clk_rate = desired_rate;
- msm_host->clk_rate = clock;
pr_debug("%s: Setting clock at rate %lu at timing %d\n",
mmc_hostname(host->mmc), achieved_rate, curr_ios.timing);
}
static void __sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
{
u16 clk;
- /*
- * Keep actual_clock as zero -
- * - since there is no divider used so no need of having actual_clock.
- * - MSM controller uses SDCLK for data timeout calculation. If
- * actual_clock is zero, host->clock is taken for calculation.
- */
- host->mmc->actual_clock = 0;
sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
if (!clock) {
- msm_host->clk_rate = clock;
+ host->mmc->actual_clock = msm_host->clk_rate = 0;
goto out;
}