[PATCH] mmc: fsl_esdhc: workaround for hardware 3.3v IO reliability issue

Yangbo Lu yangbo.lu at nxp.com
Thu May 14 04:45:39 CEST 2020


When eSDHC operates at 3.3v, damage can accumulate in an internal
level shifter at a higher than expected rate. The faster the interface
runs, the more damage accumulates. This issue now is found on LX2160A
eSDHC1 for only SD card.

The hardware workaround is recommended to use an on-board level shifter
that is 1.8v on SoC side and 3.3v on SD card side.

For boards without hardware workaround, this option could be enabled,
ensuring 1.8v IO voltage and disabling eSDHC if no card.
This option assumes no hotplug, and u-boot has to make all the way to
to linux to use 1.8v UHS-I speed mode if has card.
If you do not want the workaround for better user experience, of course
you can choose to not select it running eSDHC in unsafe mode.

Signed-off-by: Yangbo Lu <yangbo.lu at nxp.com>
---
 drivers/mmc/Kconfig     | 15 +++++++++++++++
 drivers/mmc/fsl_esdhc.c | 38 ++++++++++++++++++++++++++++++++++++--
 include/fsl_esdhc.h     |  1 +
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 8f0df56..b783f3f 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -727,6 +727,21 @@ config FSL_ESDHC
 	  This selects support for the eSDHC (Enhanced Secure Digital Host
 	  Controller) found on numerous Freescale/NXP SoCs.
 
+config FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND
+	bool "enable eSDHC workaround for 3.3v IO reliability issue"
+	depends on FSL_ESDHC && DM_MMC
+	default n
+	help
+	  When eSDHC operates at 3.3v, damage can accumulate in an internal
+	  level shifter at a higher than expected rate. The faster the interface
+	  runs, the more damage accumulates. This issue now is found on LX2160A
+	  eSDHC1 for only SD card. The hardware workaround is recommended to use
+	  an on-board level shifter that is 1.8v on SoC side and 3.3v on SD card
+	  side. For boards without hardware workaround, this option could be
+	  enabled, ensuring 1.8v IO voltage and disabling eSDHC if no card.
+	  This option assumes no hotplug, and u-boot has to make all the way to
+	  to linux to use 1.8v UHS-I speed mode if has card.
+
 config FSL_ESDHC_IMX
 	bool "Freescale/NXP i.MX eSDHC controller support"
 	help
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 386781d..e64ea76 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -721,13 +721,38 @@ __weak int esdhc_status_fixup(void *blob, const char *compat)
 	return 0;
 }
 
+#ifdef CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND
+static int fsl_esdhc_get_cd(struct udevice *dev);
+
+static void esdhc_disable_for_no_card(void *blob)
+{
+	struct udevice *dev;
+
+	for (uclass_first_device(UCLASS_MMC, &dev);
+	     dev;
+	     uclass_next_device(&dev)) {
+		char esdhc_path[50];
+
+		if (fsl_esdhc_get_cd(dev))
+			continue;
+
+		snprintf(esdhc_path, sizeof(esdhc_path), "/soc/esdhc@%lx",
+			 (unsigned long)dev_read_addr(dev));
+		do_fixup_by_path(blob, esdhc_path, "status", "disabled",
+				 sizeof("disabled"), 1);
+	}
+}
+#endif
+
 void fdt_fixup_esdhc(void *blob, bd_t *bd)
 {
 	const char *compat = "fsl,esdhc";
 
 	if (esdhc_status_fixup(blob, compat))
 		return;
-
+#ifdef CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND
+	esdhc_disable_for_no_card(blob);
+#endif
 	do_fixup_by_compat_u32(blob, compat, "clock-frequency",
 			       gd->arch.sdhc_clk, 1);
 }
@@ -846,6 +871,7 @@ static int fsl_esdhc_probe(struct udevice *dev)
 	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
 	fdt_addr_t addr;
 	struct mmc *mmc;
+	int ret;
 
 	addr = dev_read_addr(dev);
 	if (addr == FDT_ADDR_T_NONE)
@@ -879,7 +905,15 @@ static int fsl_esdhc_probe(struct udevice *dev)
 
 	upriv->mmc = mmc;
 
-	return esdhc_init_common(priv, mmc);
+	ret = esdhc_init_common(priv, mmc);
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND
+	if (!fsl_esdhc_get_cd(dev))
+		esdhc_setbits32(&priv->esdhc_regs->proctl, PROCTL_VOLT_SEL);
+#endif
+	return 0;
 }
 
 static int fsl_esdhc_get_cd(struct udevice *dev)
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 8e8cd2c..865a214 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -98,6 +98,7 @@
 #define PROCTL_DTW_4		0x00000002
 #define PROCTL_DTW_8		0x00000004
 #define PROCTL_D3CD		0x00000008
+#define PROCTL_VOLT_SEL		0x00000400
 
 #define CMDARG			0x0002e008
 
-- 
2.7.4



More information about the U-Boot mailing list