Commit 8ba9580a authored by Lucas Stach's avatar Lucas Stach Committed by Chris Ball

mmc: sdhci-esdhc: calculate sdclk divider from controller clock

The SDCLK is divided down from the host controller clock. Host
controller clock may be different from the maximum SDCLK, so
get it from the platform, instead of just using the max SDCLK.
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Acked-by: default avatarShawn Guo <shawn.guo@linaro.org>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent a82e484e
...@@ -391,6 +391,14 @@ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host) ...@@ -391,6 +391,14 @@ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk) / 256 / 16; return clk_get_rate(pltfm_host->clk) / 256 / 16;
} }
static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
unsigned int clock)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
esdhc_set_clock(host, clock, clk_get_rate(pltfm_host->clk));
}
static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host) static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
{ {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
...@@ -438,7 +446,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = { ...@@ -438,7 +446,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
.write_l = esdhc_writel_le, .write_l = esdhc_writel_le,
.write_w = esdhc_writew_le, .write_w = esdhc_writew_le,
.write_b = esdhc_writeb_le, .write_b = esdhc_writeb_le,
.set_clock = esdhc_set_clock, .set_clock = esdhc_pltfm_set_clock,
.get_max_clock = sdhci_pltfm_clk_get_max_clock, .get_max_clock = sdhci_pltfm_clk_get_max_clock,
.get_min_clock = esdhc_pltfm_get_min_clock, .get_min_clock = esdhc_pltfm_get_min_clock,
.get_ro = esdhc_pltfm_get_ro, .get_ro = esdhc_pltfm_get_ro,
......
...@@ -42,7 +42,8 @@ ...@@ -42,7 +42,8 @@
#define ESDHC_HOST_CONTROL_RES 0x05 #define ESDHC_HOST_CONTROL_RES 0x05
static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock,
unsigned int host_clock)
{ {
int pre_div = 2; int pre_div = 2;
int div = 1; int div = 1;
...@@ -56,14 +57,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) ...@@ -56,14 +57,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
| ESDHC_CLOCK_MASK); | ESDHC_CLOCK_MASK);
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
while (host->max_clk / pre_div / 16 > clock && pre_div < 256) while (host_clock / pre_div / 16 > clock && pre_div < 256)
pre_div *= 2; pre_div *= 2;
while (host->max_clk / pre_div / div > clock && div < 16) while (host_clock / pre_div / div > clock && div < 16)
div++; div++;
dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
clock, host->max_clk / pre_div / div); clock, host_clock / pre_div / div);
pre_div >>= 1; pre_div >>= 1;
div--; div--;
......
...@@ -200,7 +200,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) ...@@ -200,7 +200,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
} }
/* Set the clock */ /* Set the clock */
esdhc_set_clock(host, clock); esdhc_set_clock(host, clock, host->max_clk);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment