summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2010-07-23 11:11:40 +0800
committerJustin Waters <justin.waters@timesys.com>2010-12-17 12:10:54 -0500
commitadb7c7e723616d28c9e21d4cf2b176d0c5ecc0e0 (patch)
tree46805ae856fcdf695de95de147349370637bb34a /drivers
parent5a312f97a168475787230a17ae69661033ef9ee7 (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>
Diffstat (limited to 'drivers')
-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