aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2013-09-13 07:11:32 -0400
committerChris Ball <cjb@laptop.org>2013-09-26 07:57:12 -0400
commitd31fc00a71b4f3a52d23c5a995ccd63e50a2c877 (patch)
tree01abef4ac1da7dffe7230d458badafabce7b834a
parentc0e55129b09f3b9fee271e5fe23332393ab4c2a9 (diff)
mmc: sdhci-esdhc: move common esdhc_set_clock to platform driver
We need a lot of imx6 specific things into common esdhc_set_clock for support SD3.0 and eMMC DDR mode which is not needed for power pc platforms, so esdhc_set_clock seems not so common anymore. Instead of keeping add platform specfics things into this common API, we choose to move that code into platform driver itself to handle. This can also exclude the dependency between imx and power pc on this headfile and is easy for maintain in the future. Signed-off-by: Dong Aisheng <b29396@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c35
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h37
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c35
3 files changed, 66 insertions, 41 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index abc8cf01e6e3..67eaec92e333 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -409,8 +409,39 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
409 unsigned int clock) 409 unsigned int clock)
410{ 410{
411 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 411 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
412 412 unsigned int host_clock = clk_get_rate(pltfm_host->clk);
413 esdhc_set_clock(host, clock, clk_get_rate(pltfm_host->clk)); 413 int pre_div = 2;
414 int div = 1;
415 u32 temp;
416
417 if (clock == 0)
418 goto out;
419
420 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
421 temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
422 | ESDHC_CLOCK_MASK);
423 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
424
425 while (host_clock / pre_div / 16 > clock && pre_div < 256)
426 pre_div *= 2;
427
428 while (host_clock / pre_div / div > clock && div < 16)
429 div++;
430
431 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
432 clock, host_clock / pre_div / div);
433
434 pre_div >>= 1;
435 div--;
436
437 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
438 temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
439 | (div << ESDHC_DIVIDER_SHIFT)
440 | (pre_div << ESDHC_PREDIV_SHIFT));
441 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
442 mdelay(1);
443out:
444 host->clock = clock;
414} 445}
415 446
416static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host) 447static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index a2a06420e463..a7d9f95a7b03 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -49,41 +49,4 @@
49 49
50#define ESDHC_HOST_CONTROL_RES 0x05 50#define ESDHC_HOST_CONTROL_RES 0x05
51 51
52static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock,
53 unsigned int host_clock)
54{
55 int pre_div = 2;
56 int div = 1;
57 u32 temp;
58
59 if (clock == 0)
60 goto out;
61
62 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
63 temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
64 | ESDHC_CLOCK_MASK);
65 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
66
67 while (host_clock / pre_div / 16 > clock && pre_div < 256)
68 pre_div *= 2;
69
70 while (host_clock / pre_div / div > clock && div < 16)
71 div++;
72
73 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
74 clock, host_clock / pre_div / div);
75
76 pre_div >>= 1;
77 div--;
78
79 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
80 temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
81 | (div << ESDHC_DIVIDER_SHIFT)
82 | (pre_div << ESDHC_PREDIV_SHIFT));
83 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
84 mdelay(1);
85out:
86 host->clock = clock;
87}
88
89#endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */ 52#endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index e328252ebf2a..b1605a1747c4 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -199,6 +199,14 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
199 199
200static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) 200static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
201{ 201{
202
203 int pre_div = 2;
204 int div = 1;
205 u32 temp;
206
207 if (clock == 0)
208 goto out;
209
202 /* Workaround to reduce the clock frequency for p1010 esdhc */ 210 /* Workaround to reduce the clock frequency for p1010 esdhc */
203 if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) { 211 if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
204 if (clock > 20000000) 212 if (clock > 20000000)
@@ -207,8 +215,31 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
207 clock -= 5000000; 215 clock -= 5000000;
208 } 216 }
209 217
210 /* Set the clock */ 218 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
211 esdhc_set_clock(host, clock, host->max_clk); 219 temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
220 | ESDHC_CLOCK_MASK);
221 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
222
223 while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
224 pre_div *= 2;
225
226 while (host->max_clk / pre_div / div > clock && div < 16)
227 div++;
228
229 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
230 clock, host_clock / pre_div / div);
231
232 pre_div >>= 1;
233 div--;
234
235 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
236 temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
237 | (div << ESDHC_DIVIDER_SHIFT)
238 | (pre_div << ESDHC_PREDIV_SHIFT));
239 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
240 mdelay(1);
241out:
242 host->clock = clock;
212} 243}
213 244
214#ifdef CONFIG_PM 245#ifdef CONFIG_PM