summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Nelson <eric@nelint.com>2015-12-04 12:32:48 -0700
committerStefano Babic <sbabic@denx.de>2016-01-03 15:21:21 +0100
commitf0b5f23f32adfb790293c4f1722042026fa98416 (patch)
treeaf067eff7e525a63c19c32459d496068218c0d36
parent839479dda6b449d911d1d56c599f2a9538bb2215 (diff)
ARM: imx: fsl_esdhc: fix usage of low 4 bits of sysctl register
The low four bits of the SYSCTL register are reserved on the USDHC controller on i.MX6 and i.MX7 processors, but are used for clocking operations on earlier models. Guard against their usage by hiding the bit mask macros on those processors. These bits are used to prevent glitches when changing clocks on i.MX35 et al. Use the RSTA bit instead for i.MX6 and i.MX7. >From the i.MX6DQ RM: To prevent possible glitch on the card clock, clear the FRC_SDCLK_ON bit when changing clock divisor value(SDCLKFS or DVS in System Control Register) or setting RSTA bit. Signed-off-by: Eric Nelson <eric@nelint.com> Reviewed-by: Fabio Estevam <fabio.estevam@freescale.com> Reviewed-by: Stefano Babic <sbabic@denx.de> Reviewed-by: Hector Palacios <hector.palacios@digi.com>
-rw-r--r--drivers/mmc/fsl_esdhc.c15
-rw-r--r--include/fsl_esdhc.h2
2 files changed, 15 insertions, 2 deletions
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c5054d66bd..1ccc576c34 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -502,15 +502,22 @@ static void set_sysctl(struct mmc *mmc, uint clock)
clk = (pre_div << 8) | (div << 4);
+#ifdef CONFIG_FSL_USDHC
+ esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);
+#else
esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
+#endif
esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
udelay(10000);
- clk = SYSCTL_PEREN | SYSCTL_CKEN;
+#ifdef CONFIG_FSL_USDHC
+ esdhc_clrbits32(&regs->sysctl, SYSCTL_RSTA);
+#else
+ esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
+#endif
- esdhc_setbits32(&regs->sysctl, clk);
}
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
@@ -585,7 +592,9 @@ static int esdhc_init(struct mmc *mmc)
esdhc_write32(&regs->scr, 0x00000040);
#endif
+#ifndef CONFIG_FSL_USDHC
esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
+#endif
/* Set the initial clock speed */
mmc_set_clock(mmc, 400000);
@@ -657,8 +666,10 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
/* First reset the eSDHC controller */
esdhc_reset(regs);
+#ifndef CONFIG_FSL_USDHC
esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
| SYSCTL_IPGEN | SYSCTL_CKEN);
+#endif
writel(SDHCI_IRQ_EN_BITS, &regs->irqstaten);
memset(&cfg->cfg, 0, sizeof(cfg->cfg));
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index aa1b4cf1e4..073048fb4b 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -25,10 +25,12 @@
#define SYSCTL_INITA 0x08000000
#define SYSCTL_TIMEOUT_MASK 0x000f0000
#define SYSCTL_CLOCK_MASK 0x0000fff0
+#if !defined(CONFIG_FSL_USDHC)
#define SYSCTL_CKEN 0x00000008
#define SYSCTL_PEREN 0x00000004
#define SYSCTL_HCKEN 0x00000002
#define SYSCTL_IPGEN 0x00000001
+#endif
#define SYSCTL_RSTA 0x01000000
#define SYSCTL_RSTC 0x02000000
#define SYSCTL_RSTD 0x04000000