summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2010-07-23 11:11:40 +0800
committerAlan Tull <r80115@freescale.com>2010-07-23 09:54:03 -0500
commit3bc4ee85b4784415b103e88e8420fb30c53b3287 (patch)
treeed2160a3ff3801c8bcb8f98756675240cc9c0c8c
parentc5d7f63d4d63a0986c3e50b81bb26cb899ca495e (diff)
ENGR00125489 esdhc: Fix the failure in DLL configurations
Adjust the Target dll value to support the TOSHIBA eMMC44 card. Make sure that IPG, HLK, PER are enabled, and SDCLK is disabled. SDCLKFS can't be set to zero on esdhc V3 IP. Signed-off-by: Richard Zhu <r65037@freescale.com>
-rw-r--r--drivers/mmc/host/mx_sdhci.c24
-rw-r--r--drivers/mmc/host/mx_sdhci.h3
2 files changed, 21 insertions, 6 deletions
diff --git a/drivers/mmc/host/mx_sdhci.c b/drivers/mmc/host/mx_sdhci.c
index 036b8cd19eb9..7eb28a279894 100644
--- a/drivers/mmc/host/mx_sdhci.c
+++ b/drivers/mmc/host/mx_sdhci.c
@@ -818,7 +818,10 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
clk_rate = clk_get_rate(host->clk);
clk = readl(host->ioaddr + SDHCI_CLOCK_CONTROL) & ~SDHCI_CLOCK_MASK;
- if (!cpu_is_mx53())
+ if (cpu_is_mx53() || cpu_is_mx50())
+ writel(clk | SDHCI_CLOCK_SDCLKFS1,
+ host->ioaddr + SDHCI_CLOCK_CONTROL);
+ else
writel(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
if (clock == host->min_clk)
@@ -851,6 +854,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
/* Configure the DLL when DDR mode is enabled */
if (ios.bus_width & MMC_BUS_WIDTH_DDR) {
+ /* Make sure that the PER, HLK, IPG are all enabled */
+ writel(readl(host->ioaddr + SDHCI_CLOCK_CONTROL)
+ | SDHCI_CLOCK_IPG_EN
+ | SDHCI_CLOCK_HLK_EN
+ | SDHCI_CLOCK_PER_EN,
+ host->ioaddr + SDHCI_CLOCK_CONTROL);
+
/* Enable the DLL and delay chain */
writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
| DLL_CTRL_ENABLE,
@@ -868,10 +878,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
DBG("dll stat: 0x%x\n", readl(host->ioaddr + SDHCI_DLL_STATUS));
writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
- | DLL_CTRL_SLV_UP_INT | DLL_CTRL_REF_UP_INT,
- host->ioaddr + SDHCI_DLL_CONTROL);
-
- writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
+ | DLL_CTRL_SLV_UP_INT | DLL_CTRL_REF_UP_INT
| DLL_CTRL_SLV_DLY_TAR,
host->ioaddr + SDHCI_DLL_CONTROL);
@@ -912,6 +919,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
printk(KERN_ERR "DLL SLV LOCK Timeout!\n");
};
DBG("dll stat: 0x%x\n", readl(host->ioaddr + SDHCI_DLL_STATUS));
+
+ /* Let the PER, HLK, IPG to be auto-gate */
+ writel(readl(host->ioaddr + SDHCI_CLOCK_CONTROL)
+ & ~(SDHCI_CLOCK_IPG_EN | SDHCI_CLOCK_HLK_EN
+ | SDHCI_CLOCK_PER_EN),
+ host->ioaddr + SDHCI_CLOCK_CONTROL);
+
} else if (readl(host->ioaddr + SDHCI_DLL_STATUS) & DLL_STS_SLV_LOCK) {
/* reset DLL CTRL */
writel(readl(host->ioaddr + SDHCI_DLL_CONTROL) | DLL_CTRL_RESET,
diff --git a/drivers/mmc/host/mx_sdhci.h b/drivers/mmc/host/mx_sdhci.h
index 358050501cac..fa36dff0fd9a 100644
--- a/drivers/mmc/host/mx_sdhci.h
+++ b/drivers/mmc/host/mx_sdhci.h
@@ -95,6 +95,7 @@
#define SDHCI_CLOCK_PER_EN 0x00000004
#define SDHCI_CLOCK_HLK_EN 0x00000002
#define SDHCI_CLOCK_IPG_EN 0x00000001
+#define SDHCI_CLOCK_SDCLKFS1 0x00000100
#define SDHCI_CLOCK_MASK 0x0000FFFF
#define SDHCI_TIMEOUT_CONTROL 0x2E
@@ -192,7 +193,7 @@
#define DLL_CTRL_ENABLE 0x00000001
#define DLL_CTRL_RESET 0x00000002
#define DLL_CTRL_SLV_FORCE_UPD 0x00000004
-#define DLL_CTRL_SLV_DLY_TAR 0x00000020
+#define DLL_CTRL_SLV_DLY_TAR 0x00000000
#define DLL_CTRL_SLV_UP_INT 0x00200000
#define DLL_CTRL_REF_UP_INT 0x20000000