diff options
-rw-r--r-- | drivers/mmc/host/mx_sdhci.c | 24 | ||||
-rw-r--r-- | drivers/mmc/host/mx_sdhci.h | 3 |
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 |