From 02dcd667389aa5143a43d245ac5ecc1559a956ed Mon Sep 17 00:00:00 2001
From: Tonyliu <Bo.Liu@windriver.com>
Date: Mon, 18 Oct 2010 16:24:21 +0800
Subject: [PATCH] esdhci: fix clock-frequency for e300
The DTB clock-frequency property of esdhci is not fixed in u-boot by default for most
e300 platforms.So has to caculate the input clock frequency explicitly from CPU's
bus-frequency property.
Signed-off-by: Tonyliu <Bo.Liu@windriver.com>
---
drivers/mmc/host/sdhci-of-core.c | 43 ++++++++++++++++++++++++++++++++++++++
1 files changed, 43 insertions(+), 0 deletions(-)
@@ -167,6 +167,49 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev,
clk = of_get_property(np, "clock-frequency", &size);
if (clk && size == sizeof(*clk) && *clk)
of_host->clock = *clk;
+ else {
+ /* clock frequency of peripherals maybe not fixed by u-boot
+ * on some platforms, then need to find proper clock of
+ * SDHCI controller by CPU's bus frequency.*/
+ struct device_node *cpu;
+
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu) {
+ unsigned int size;
+ const u32 *prop = of_get_property(cpu, "bus-frequency", &size);
+ of_host->clock = *prop;
+ of_node_put(cpu);
+ } else {
+ ret = -EINVAL;
+ goto err_bad_freq;
+ }
+
+ /*
+ * SDHCI input clock can be scaled against platform bus frequency.
+ */
+ if (of_get_property(np, "sdhci,clk-scale", NULL)) {
+ void __iomem *immap = NULL;
+ unsigned int sdhccm;
+
+ immap = ioremap(get_immrbase(), 0x1000);
+ if (!immap) {
+ ret = -ENOMEM;
+ goto err_bad_freq;
+ }
+
+ sdhccm = (in_be32(immap + SDHCI_SCCR_OFFS) & SDHCI_SDHCCM_MASK)
+ >> SDHCI_SDHCCM_SHIFT;
+
+ iounmap(immap);
+
+ if (sdhccm == 0) {
+ printk(KERN_ERR "The eSDHC clock was disable!\n");
+ ret = -EBADSLT;
+ goto err_bad_freq;
+ } else
+ of_host->clock /= sdhccm;
+ }
+ }
ret = sdhci_add_host(host);
if (ret)
--
1.6.0.4