summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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