aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnish Trivedi <anish@freescale.com>2010-11-10 17:07:12 -0600
committerTerry Lv <r65388@freescale.com>2010-12-01 18:02:07 +0800
commit7a9a5e1d912fbdcdf80b51a60dfd45214f65ddc8 (patch)
treeccc430cdc41a8b633fb6ad71aedcf7d051db059e
parent7a047737bdd06e9fb44b055ecd8a4cdb27e72711 (diff)
ENGR00133579 Uboot ESDHCv3 Remove workaround for DLL
On MX50 TO 1.0, DLL did not work in slave mode, so slave override mode was used instead. Removed this workaround, except for TO 1.0. Starting with TO 1.1, the DLL in slave mode is working as expected. Signed-off-by: Anish Trivedi <anish@freescale.com> Signed-off-by: Terry Lv <r65388@freescale.com>
-rw-r--r--drivers/mmc/imx_esdhc.c51
-rw-r--r--include/fsl_esdhc.h4
2 files changed, 46 insertions, 9 deletions
diff --git a/drivers/mmc/imx_esdhc.c b/drivers/mmc/imx_esdhc.c
index a57aa7449..f9a3ad684 100644
--- a/drivers/mmc/imx_esdhc.c
+++ b/drivers/mmc/imx_esdhc.c
@@ -337,16 +337,49 @@ static void esdhc_dll_setup(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+ uint dll_control;
+
+ /* For i.MX50 TO1, need to force slave override mode */
+ if (get_board_rev() == (0x50000 | CHIP_REV_1_0)) {
+ dll_control = readl(&regs->dllctrl);
+
+ dll_control &= ~(ESDHC_DLLCTRL_SLV_OVERRIDE_VAL_MASK |
+ ESDHC_DLLCTRL_SLV_OVERRIDE);
+ dll_control |= ((ESDHC_DLLCTRL_SLV_OVERRIDE_VAL <<
+ ESDHC_DLLCTRL_SLV_OVERRIDE_VAL_SHIFT) |
+ ESDHC_DLLCTRL_SLV_OVERRIDE);
+
+ writel(dll_control, &regs->dllctrl);
+ } else {
+ /* Disable auto clock gating for PERCLK, HCLK, and IPGCLK */
+ writel(readl(&regs->sysctl) | 0x7, &regs->sysctl);
+ /* Stop SDCLK while delay line is calibrated */
+ writel(readl(&regs->sysctl) &= ~SYSCTL_SDCLKEN, &regs->sysctl);
+
+ /* Reset DLL */
+ writel(readl(&regs->dllctrl) | 0x2, &regs->dllctrl);
+
+ /* Enable DLL */
+ writel(readl(&regs->dllctrl) | 0x1, &regs->dllctrl);
+
+ dll_control = readl(&regs->dllctrl);
+
+ /* Set target delay */
+ dll_control &= ~ESDHC_DLLCTRL_TARGET_MASK;
+ dll_control |= (ESDHC_DLL_TARGET_DEFAULT_VAL <<
+ ESDHC_DLLCTRL_TARGET_SHIFT);
+ writel(dll_control, &regs->dllctrl);
+
+ /* Wait for slave lock */
+ while ((readl(&regs->dllstatus) & ESDHC_DLLSTS_SLV_LOCK_MASK) !=
+ ESDHC_DLLSTS_SLV_LOCK_MASK)
+ ;
- uint dll_control = readl(&regs->dllctrl);
- dll_control &= ~(ESDHC_DLLCTRL_SLV_OVERRIDE_VAL_MASK |
- ESDHC_DLLCTRL_SLV_OVERRIDE);
- dll_control |= ((ESDHC_DLLCTRL_SLV_OVERRIDE_VAL <<
- ESDHC_DLLCTRL_SLV_OVERRIDE_VAL_SHIFT) |
- ESDHC_DLLCTRL_SLV_OVERRIDE);
-
- writel(dll_control, &regs->dllctrl);
-
+ /* Re-enable auto clock gating */
+ writel(readl(&regs->sysctl) | SYSCTL_SDCLKEN, &regs->sysctl);
+ /* Re-enable SDCLK */
+ writel(readl(&regs->sysctl) &= ~0x7, &regs->sysctl);
+ }
}
static void esdhc_set_ios(struct mmc *mmc)
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index a0b1f5cf3..e32d7d26c 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -155,6 +155,10 @@
#define ESDHC_DLLCTRL_SLV_OVERRIDE_VAL_MASK 0x0000FC00
#define ESDHC_DLLCTRL_SLV_OVERRIDE_VAL_SHIFT 10
#define ESDHC_DLLCTRL_SLV_OVERRIDE 0x200
+#define ESDHC_DLLCTRL_TARGET_MASK 0x00000078
+#define ESDHC_DLLCTRL_TARGET_SHIFT 3
+#define ESDHC_DLL_TARGET_DEFAULT_VAL 4
+#define ESDHC_DLLSTS_SLV_LOCK_MASK 0x00000001
struct fsl_esdhc_cfg {
u32 esdhc_base;