summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAisheng.Dong <b29396@freescale.com>2010-07-30 11:31:31 +0800
committerAisheng.Dong <b29396@freescale.com>2010-08-02 11:02:23 +0800
commite94064f4d690da9bf565c3dffe2a0aa18dffd9e3 (patch)
treea9d329d357e7722a9df8053a017aba207ed389ee
parentb7753c7679c4fbae26e145df246529cdf5df6c6f (diff)
ENGR00125731-2 esdhc: add dll override delay line support
For esdhc v3, we can manually regulate the clock delay line to get better compatibiliy with some cards requiring good signal and working on high speed such as eMMC 4.4 cards. Currently we only support override mode to regulate delay line. DLL mode will be removed first caused by some HW issue. Signed-off-by: Aisheng.Dong <b29396@freescale.com>
-rw-r--r--drivers/mmc/host/mx_sdhci.c85
-rw-r--r--drivers/mmc/host/mx_sdhci.h2
2 files changed, 8 insertions, 79 deletions
diff --git a/drivers/mmc/host/mx_sdhci.c b/drivers/mmc/host/mx_sdhci.c
index 7eb28a279894..8ee825a9af9d 100644
--- a/drivers/mmc/host/mx_sdhci.c
+++ b/drivers/mmc/host/mx_sdhci.c
@@ -852,85 +852,12 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
DBG("prescaler = 0x%x, divider = 0x%x\n", prescaler, div);
clk |= (prescaler << 8) | (div << 4);
- /* 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,
- host->ioaddr + SDHCI_DLL_CONTROL);
-
- timeout = 1000000;
- while (timeout > 0) {
- timeout--;
- if (readl(host->ioaddr + SDHCI_DLL_STATUS)
- & DLL_STS_REF_LOCK)
- break;
- else if (timeout == 0)
- printk(KERN_ERR "DLL REF LOCK Timeout!\n");
- };
- 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
- | DLL_CTRL_SLV_DLY_TAR,
- host->ioaddr + SDHCI_DLL_CONTROL);
-
- timeout = 1000000;
- while (timeout > 0) {
- timeout--;
- if (readl(host->ioaddr + SDHCI_DLL_STATUS)
- & DLL_STS_SLV_LOCK)
- break;
- else if (timeout == 0)
- printk(KERN_ERR "DLL SLV LOCK Timeout!\n");
- };
-
- writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
- | DLL_CTRL_SLV_FORCE_UPD,
- host->ioaddr + SDHCI_DLL_CONTROL);
-
- writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
- & (~DLL_CTRL_SLV_FORCE_UPD),
- host->ioaddr + SDHCI_DLL_CONTROL);
-
- timeout = 1000000;
- while (timeout > 0) {
- timeout--;
- if (readl(host->ioaddr + SDHCI_DLL_STATUS)
- & DLL_STS_REF_LOCK)
- break;
- else if (timeout == 0)
- printk(KERN_ERR "DLL REF LOCK Timeout!\n");
- };
- timeout = 1000000;
- while (timeout > 0) {
- timeout--;
- if (readl(host->ioaddr + SDHCI_DLL_STATUS)
- & DLL_STS_SLV_LOCK)
- break;
- else if (timeout == 0)
- 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,
- host->ioaddr + SDHCI_DLL_CONTROL);
- }
+ /* Configure the clock delay line */
+ if ((host->plat_data->vendor_ver >= ESDHC_VENDOR_V3)
+ && host->plat_data->dll_override_en)
+ writel((host->plat_data->dll_delay_cells << 10)
+ | DLL_CTRL_SLV_OVERRIDE,
+ host->ioaddr + SDHCI_DLL_CONTROL);
/* Configure the clock control register */
clk |=
diff --git a/drivers/mmc/host/mx_sdhci.h b/drivers/mmc/host/mx_sdhci.h
index fa36dff0fd9a..a212cb2bb03a 100644
--- a/drivers/mmc/host/mx_sdhci.h
+++ b/drivers/mmc/host/mx_sdhci.h
@@ -193,6 +193,7 @@
#define DLL_CTRL_ENABLE 0x00000001
#define DLL_CTRL_RESET 0x00000002
#define DLL_CTRL_SLV_FORCE_UPD 0x00000004
+#define DLL_CTRL_SLV_OVERRIDE 0x00000200
#define DLL_CTRL_SLV_DLY_TAR 0x00000000
#define DLL_CTRL_SLV_UP_INT 0x00200000
#define DLL_CTRL_REF_UP_INT 0x20000000
@@ -219,6 +220,7 @@ enum {
#define SDHCI_SPEC_100 0
#define SDHCI_SPEC_200 1
#define ESDHC_VENDOR_V22 0x12
+#define ESDHC_VENDOR_V3 0x13
struct sdhci_chip;