summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2010-07-23 11:11:40 +0800
committerRichard Zhu <r65037@freescale.com>2010-07-23 14:42:05 +0800
commitf9d77737b87700e8b8c428a47658cd931b08ca43 (patch)
tree46805ae856fcdf695de95de147349370637bb34a
parent35614ae9dc6feb6a1a5f1ec2d8a2d1ff9b6f6c4b (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