From 7a9a5e1d912fbdcdf80b51a60dfd45214f65ddc8 Mon Sep 17 00:00:00 2001 From: Anish Trivedi Date: Wed, 10 Nov 2010 17:07:12 -0600 Subject: 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 Signed-off-by: Terry Lv --- drivers/mmc/imx_esdhc.c | 51 ++++++++++++++++++++++++++++++++++++++++--------- include/fsl_esdhc.h | 4 ++++ 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(®s->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, ®s->dllctrl); + } else { + /* Disable auto clock gating for PERCLK, HCLK, and IPGCLK */ + writel(readl(®s->sysctl) | 0x7, ®s->sysctl); + /* Stop SDCLK while delay line is calibrated */ + writel(readl(®s->sysctl) &= ~SYSCTL_SDCLKEN, ®s->sysctl); + + /* Reset DLL */ + writel(readl(®s->dllctrl) | 0x2, ®s->dllctrl); + + /* Enable DLL */ + writel(readl(®s->dllctrl) | 0x1, ®s->dllctrl); + + dll_control = readl(®s->dllctrl); + + /* Set target delay */ + dll_control &= ~ESDHC_DLLCTRL_TARGET_MASK; + dll_control |= (ESDHC_DLL_TARGET_DEFAULT_VAL << + ESDHC_DLLCTRL_TARGET_SHIFT); + writel(dll_control, ®s->dllctrl); + + /* Wait for slave lock */ + while ((readl(®s->dllstatus) & ESDHC_DLLSTS_SLV_LOCK_MASK) != + ESDHC_DLLSTS_SLV_LOCK_MASK) + ; - uint dll_control = readl(®s->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, ®s->dllctrl); - + /* Re-enable auto clock gating */ + writel(readl(®s->sysctl) | SYSCTL_SDCLKEN, ®s->sysctl); + /* Re-enable SDCLK */ + writel(readl(®s->sysctl) &= ~0x7, ®s->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; -- cgit v1.2.3