aboutsummaryrefslogtreecommitdiff
path: root/drivers
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 /drivers
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/imx_esdhc.c51
1 files changed, 42 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)