From c927d65873c7706f436ab59a78d44a0eb80fe939 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 19 May 2020 11:06:44 +0800 Subject: [PATCH] mmc: fsl_esdhc: workaround for hardware 3.3v IO reliability issue 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 Acked-by: Peng Fan --- drivers/mmc/Kconfig | 15 +++++++++++++++ drivers/mmc/fsl_esdhc.c | 38 ++++++++++++++++++++++++++++++++++++-- include/fsl_esdhc.h | 2 ++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 3c4f057373..8f56572c39 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 704407981b..a4b923ab99 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -723,13 +723,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); } @@ -848,6 +873,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) @@ -881,7 +907,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 8e8cd2cc1a..e148eaa880 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -4,6 +4,7 @@ *------------------------------------------------------------------- * * Copyright 2007-2008,2010-2011 Freescale Semiconductor, Inc + * Copyright 2020 NXP */ #ifndef __FSL_ESDHC_H__ @@ -98,6 +99,7 @@ #define PROCTL_DTW_4 0x00000002 #define PROCTL_DTW_8 0x00000004 #define PROCTL_D3CD 0x00000008 +#define PROCTL_VOLT_SEL 0x00000400 #define CMDARG 0x0002e008 -- 2.39.5