Skip to content

Commit

Permalink
mmc: sdhci-esdhc: calculate sdclk divider from controller clock
Browse files Browse the repository at this point in the history
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: Lucas Stach <l.stach@pengutronix.de>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
  • Loading branch information
lynxeye-dev authored and cjb committed Jun 27, 2013
1 parent a82e484 commit 8ba9580
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
10 changes: 9 additions & 1 deletion drivers/mmc/host/sdhci-esdhc-imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

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)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
Expand Down Expand Up @@ -438,7 +446,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
.write_l = esdhc_writel_le,
.write_w = esdhc_writew_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_min_clock = esdhc_pltfm_get_min_clock,
.get_ro = esdhc_pltfm_get_ro,
Expand Down
9 changes: 5 additions & 4 deletions drivers/mmc/host/sdhci-esdhc.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@

#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 div = 1;
Expand All @@ -56,14 +57,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
| ESDHC_CLOCK_MASK);
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;

while (host->max_clk / pre_div / div > clock && div < 16)
while (host_clock / pre_div / div > clock && div < 16)
div++;

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;
div--;
Expand Down
2 changes: 1 addition & 1 deletion drivers/mmc/host/sdhci-of-esdhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
}

/* Set the clock */
esdhc_set_clock(host, clock);
esdhc_set_clock(host, clock, host->max_clk);
}

#ifdef CONFIG_PM
Expand Down

0 comments on commit 8ba9580

Please sign in to comment.