aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Walle <michael@walle.cc>2021-03-17 15:01:37 +0100
committerPeng Fan <peng.fan@nxp.com>2021-04-06 18:36:04 +0800
commitd3b745f7d00d07767a0ed85a6b139feeb8df9aaf (patch)
tree3acce1e9caed60d740445948f654d35f6445e731
parentbd7b8505f2c0c87785488a040ff7d2711465b401 (diff)
downloadu-boot-d3b745f7d00d07767a0ed85a6b139feeb8df9aaf.zip
u-boot-d3b745f7d00d07767a0ed85a6b139feeb8df9aaf.tar.gz
u-boot-d3b745f7d00d07767a0ed85a6b139feeb8df9aaf.tar.bz2
mmc: fsl_esdhc: add pulse width detection workaround
HS400 mode on the LS1028A SoC isn't reliable. The linux driver has a workaroung for the pulse width detection. Apply this workaround in u-boot, too. This will make HS400 mode work reliably on the LS1028A SoC. Signed-off-by: Michael Walle <michael@walle.cc> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/Kconfig1
-rw-r--r--drivers/mmc/Kconfig3
-rw-r--r--drivers/mmc/fsl_esdhc.c6
-rw-r--r--include/fsl_esdhc.h3
4 files changed, 12 insertions, 1 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index c0190a2..9d1ba4c 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -48,6 +48,7 @@ config ARCH_LS1028A
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
select SYS_FSL_ERRATUM_A050382
select SYS_FSL_ERRATUM_A011334
+ select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
select RESV_RAM if GIC_V3_ITS
imply PANIC_HANG
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index b0ff92b..4925675 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -816,3 +816,6 @@ config SYS_FSL_ERRATUM_ESDHC_A001
config SYS_FSL_ERRATUM_A011334
bool
+
+config SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
+ bool
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 09ea1a9..7501fdb 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -71,7 +71,8 @@ struct fsl_esdhc {
uint sdtimingctl; /* SD timing control register */
char reserved8[20]; /* reserved */
uint dllcfg0; /* DLL config 0 register */
- char reserved9[12]; /* reserved */
+ uint dllcfg1; /* DLL config 1 register */
+ char reserved9[8]; /* reserved */
uint dllstat0; /* DLL status 0 register */
char reserved10[664];/* reserved */
uint esdhcctl; /* eSDHC control register */
@@ -767,6 +768,9 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
/* Set timout to the maximum value */
esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
+ if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND))
+ esdhc_clrbits32(&regs->dllcfg1, DLL_PD_PULSE_STRETCH_SEL);
+
return 0;
}
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 850a304..f86afe5 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -190,6 +190,9 @@
#define DLL_RESET 0x40000000
#define DLL_FREQ_SEL 0x08000000
+/* DLL config 1 register */
+#define DLL_PD_PULSE_STRETCH_SEL 0x80000000
+
/* DLL status 0 register */
#define DLL_STS_SLV_LOCK 0x08000000