[U-Boot] [PATCH V3 1/4] mmc: fsl_esdhc: introduce vs18_enable for 1.8V fix I/O

When using eMMC with 1.8V I/O, the VSELECT bit need to be set in the USDHC controller when init.
This patch adds a parameter "vs18_enable" in fsl_esdhc_cfg structure and priv data, so each controller can have different settings.
We could not use CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT, it has problem that it will apply to all USDHC controllers and it only set the 1.8V at init phase. So if user does not select to the eMMC device, the voltage on the I/O pins are not correct.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: York Sun york.sun@nxp.com Cc: Stefano Babic sbabic@denx.de ---
V3: none V2: none
drivers/mmc/fsl_esdhc.c | 9 +++++++++ include/fsl_esdhc.h | 1 + 2 files changed, 10 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index f3c6358..bddfe24 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -92,6 +92,7 @@ struct fsl_esdhc { * @dev: pointer for the device * @non_removable: 0: removable; 1: non-removable * @wp_enable: 1: enable checking wp; 0: no check + * @vs18_enable: 1: use 1.8V voltage; 0: use 3.3V * @cd_gpio: gpio for card detection * @wp_gpio: gpio for write protection */ @@ -104,6 +105,7 @@ struct fsl_esdhc_priv { struct udevice *dev; int non_removable; int wp_enable; + int vs18_enable; #ifdef CONFIG_DM_GPIO struct gpio_desc cd_gpio; struct gpio_desc wp_gpio; @@ -673,6 +675,9 @@ static int esdhc_init(struct mmc *mmc) esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); #endif
+ if (priv->vs18_enable) + esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); + return 0; }
@@ -733,6 +738,7 @@ static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, priv->bus_width = cfg->max_bus_width; priv->sdhc_clk = cfg->sdhc_clk; priv->wp_enable = cfg->wp_enable; + priv->vs18_enable = cfg->vs18_enable;
return 0; }; @@ -759,6 +765,9 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) VENDORSPEC_HCKEN | VENDORSPEC_IPGEN | VENDORSPEC_CKEN); #endif
+ if (priv->vs18_enable) + esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); + writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten); memset(&priv->cfg, 0, sizeof(priv->cfg));
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index e15d3ae..7a5d653 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -178,6 +178,7 @@ struct fsl_esdhc_cfg { u32 sdhc_clk; u8 max_bus_width; u8 wp_enable; + u8 vs18_enable; /* Use 1.8V if set to 1 */ struct mmc_config cfg; };

Handle vqmmc supply. Some boards have a fixed I/O voltage at 1.8V for emmc, so the usdhc also needs to be configured as 1.8V by setting VSELECT bit. The vs18_enable is the one that used to checking whether setting VSELECT or not in the driver. So if vqmmc supply is 1.8V, set vs18_enable, the driver will set VSELECT.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: York Sun york.sun@nxp.com Cc: Stefano Babic sbabic@denx.de ---
V3: add regulator enable V2: include header file, fix dev_dbg
drivers/mmc/fsl_esdhc.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index bddfe24..20f0b40 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -16,6 +16,7 @@ #include <hwconfig.h> #include <mmc.h> #include <part.h> +#include <power/regulator.h> #include <malloc.h> #include <fsl_esdhc.h> #include <fdt_support.h> @@ -968,6 +969,7 @@ static int fsl_esdhc_probe(struct udevice *dev) struct fsl_esdhc_priv *priv = dev_get_priv(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev); + struct udevice *vqmmc_dev; fdt_addr_t addr; unsigned int val; int ret; @@ -1005,6 +1007,29 @@ static int fsl_esdhc_probe(struct udevice *dev) if (ret) priv->wp_enable = 0; #endif + + priv->vs18_enable = 0; + +#ifdef CONFIG_DM_REGULATOR + /* + * If emmc I/O has a fixed voltage at 1.8V, this must be provided, + * otherwise, emmc will work abnormally. + */ + ret = device_get_supply_regulator(dev, "vqmmc-supply", &vqmmc_dev); + if (ret) { + dev_dbg(dev, "no vqmmc-supply\n"); + } else { + ret = regulator_set_enable(vqmmc_dev, true); + if (ret) { + dev_err(dev, "fail to enable vqmmc-supply\n"); + return ret; + } + + if (regulator_get_value(vqmmc_dev) == 1800000) + priv->vs18_enable = 1; + } +#endif + /* * TODO: * Because lack of clk driver, if SDHC clk is not enabled,

On 05/11/2017 11:28 AM, Peng Fan wrote:
Handle vqmmc supply. Some boards have a fixed I/O voltage at 1.8V for emmc, so the usdhc also needs to be configured as 1.8V by setting VSELECT bit. The vs18_enable is the one that used to checking whether setting VSELECT or not in the driver. So if vqmmc supply is 1.8V, set vs18_enable, the driver will set VSELECT.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: York Sun york.sun@nxp.com Cc: Stefano Babic sbabic@denx.de
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
V3: add regulator enable V2: include header file, fix dev_dbg
drivers/mmc/fsl_esdhc.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index bddfe24..20f0b40 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -16,6 +16,7 @@ #include <hwconfig.h> #include <mmc.h> #include <part.h> +#include <power/regulator.h> #include <malloc.h> #include <fsl_esdhc.h> #include <fdt_support.h> @@ -968,6 +969,7 @@ static int fsl_esdhc_probe(struct udevice *dev) struct fsl_esdhc_priv *priv = dev_get_priv(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev);
- struct udevice *vqmmc_dev; fdt_addr_t addr; unsigned int val; int ret;
@@ -1005,6 +1007,29 @@ static int fsl_esdhc_probe(struct udevice *dev) if (ret) priv->wp_enable = 0; #endif
- priv->vs18_enable = 0;
+#ifdef CONFIG_DM_REGULATOR
- /*
* If emmc I/O has a fixed voltage at 1.8V, this must be provided,
* otherwise, emmc will work abnormally.
*/
- ret = device_get_supply_regulator(dev, "vqmmc-supply", &vqmmc_dev);
- if (ret) {
dev_dbg(dev, "no vqmmc-supply\n");
- } else {
ret = regulator_set_enable(vqmmc_dev, true);
if (ret) {
dev_err(dev, "fail to enable vqmmc-supply\n");
return ret;
}
if (regulator_get_value(vqmmc_dev) == 1800000)
priv->vs18_enable = 1;
- }
+#endif
- /*
- TODO:
- Because lack of clk driver, if SDHC clk is not enabled,

Use vs18_enable, and drop CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Otavio Salvador otavio@ossystems.com.br Cc: Stefano Babic sbabic@denx.de Cc: Jaehoon Chung jh80.chung@samsung.com ---
V3: none V2: none
board/warp/warp.c | 2 +- include/configs/warp.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/board/warp/warp.c b/board/warp/warp.c index 0bc0a6a..b1b528a 100644 --- a/board/warp/warp.c +++ b/board/warp/warp.c @@ -62,7 +62,7 @@ static void setup_iomux_uart(void) }
static struct fsl_esdhc_cfg usdhc_cfg[1] = { - {USDHC2_BASE_ADDR}, + {USDHC2_BASE_ADDR, 0, 0, 0, 1}, };
int board_mmc_getcd(struct mmc *mmc) diff --git a/include/configs/warp.h b/include/configs/warp.h index 5274b27..387a079 100644 --- a/include/configs/warp.h +++ b/include/configs/warp.h @@ -23,7 +23,6 @@
/* MMC Configs */ #define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR -#define CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT #define CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE #define CONFIG_SUPPORT_EMMC_BOOT

On 05/11/2017 11:28 AM, Peng Fan wrote:
Use vs18_enable, and drop CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Otavio Salvador otavio@ossystems.com.br Cc: Stefano Babic sbabic@denx.de Cc: Jaehoon Chung jh80.chung@samsung.com
V3: none V2: none
board/warp/warp.c | 2 +- include/configs/warp.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/board/warp/warp.c b/board/warp/warp.c index 0bc0a6a..b1b528a 100644 --- a/board/warp/warp.c +++ b/board/warp/warp.c @@ -62,7 +62,7 @@ static void setup_iomux_uart(void) }
static struct fsl_esdhc_cfg usdhc_cfg[1] = {
- {USDHC2_BASE_ADDR},
- {USDHC2_BASE_ADDR, 0, 0, 0, 1},
};
int board_mmc_getcd(struct mmc *mmc) diff --git a/include/configs/warp.h b/include/configs/warp.h index 5274b27..387a079 100644 --- a/include/configs/warp.h +++ b/include/configs/warp.h @@ -23,7 +23,6 @@
/* MMC Configs */ #define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR -#define CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT
This change can be moved to [PATCH 4/4].
#define CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE #define CONFIG_SUPPORT_EMMC_BOOT

CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT is not the correct method to set I/O to 1.8. To boards that does not support vqmmc-supply, use vs18_enable in fsl_esdhc_cfg. If regulator is supported, use fixed 1.8V regulator for vqmmc-supply.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: York Sun york.sun@nxp.com Cc: Stefano Babic sbabic@denx.de ---
V3: none V2: none
doc/README.fsl-esdhc | 2 -- drivers/mmc/fsl_esdhc.c | 4 ---- scripts/config_whitelist.txt | 1 - 3 files changed, 7 deletions(-)
diff --git a/doc/README.fsl-esdhc b/doc/README.fsl-esdhc index 7e71387..29cc661 100644 --- a/doc/README.fsl-esdhc +++ b/doc/README.fsl-esdhc @@ -20,5 +20,3 @@ Freescale esdhc-specific options - CONFIG_SYS_FSL_ESDHC_BE ESDHC IP is in big-endian mode. Accessing ESDHC registers can be determined by ESDHC IP's endian mode or processor's endian mode. - - - CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT forces to run at 1.8V. diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 20f0b40..efa992e 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -672,10 +672,6 @@ static int esdhc_init(struct mmc *mmc) /* Set timout to the maximum value */ esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
-#ifdef CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT - esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); -#endif - if (priv->vs18_enable) esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT);
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index ed349b9..255e22f 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -3870,7 +3870,6 @@ CONFIG_SYS_FSL_ERRATUM_A_004934 CONFIG_SYS_FSL_ESDHC_ADDR CONFIG_SYS_FSL_ESDHC_BE CONFIG_SYS_FSL_ESDHC_BROKEN_TIMEOUT -CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE CONFIG_SYS_FSL_ESDHC_LE CONFIG_SYS_FSL_ESDHC_NUM

On 05/11/2017 11:28 AM, Peng Fan wrote:
When using eMMC with 1.8V I/O, the VSELECT bit need to be set in the USDHC controller when init.
This patch adds a parameter "vs18_enable" in fsl_esdhc_cfg structure and priv data, so each controller can have different settings.
We could not use CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT, it has problem that it will apply to all USDHC controllers and it only set the 1.8V at init phase. So if user does not select to the eMMC device, the voltage on the I/O pins are not correct.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: York Sun york.sun@nxp.com Cc: Stefano Babic sbabic@denx.de
V3: none V2: none
drivers/mmc/fsl_esdhc.c | 9 +++++++++ include/fsl_esdhc.h | 1 + 2 files changed, 10 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index f3c6358..bddfe24 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -92,6 +92,7 @@ struct fsl_esdhc {
- @dev: pointer for the device
- @non_removable: 0: removable; 1: non-removable
- @wp_enable: 1: enable checking wp; 0: no check
*/
- @vs18_enable: 1: use 1.8V voltage; 0: use 3.3V
- @cd_gpio: gpio for card detection
- @wp_gpio: gpio for write protection
@@ -104,6 +105,7 @@ struct fsl_esdhc_priv { struct udevice *dev; int non_removable; int wp_enable;
- int vs18_enable;
#ifdef CONFIG_DM_GPIO struct gpio_desc cd_gpio; struct gpio_desc wp_gpio; @@ -673,6 +675,9 @@ static int esdhc_init(struct mmc *mmc) esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); #endif
- if (priv->vs18_enable)
esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT);
- return 0;
}
@@ -733,6 +738,7 @@ static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, priv->bus_width = cfg->max_bus_width; priv->sdhc_clk = cfg->sdhc_clk; priv->wp_enable = cfg->wp_enable;
- priv->vs18_enable = cfg->vs18_enable;
cfg->vs18_enable is u8, but priv->vs18_enable is int..
return 0; }; @@ -759,6 +765,9 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) VENDORSPEC_HCKEN | VENDORSPEC_IPGEN | VENDORSPEC_CKEN); #endif
- if (priv->vs18_enable)
esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT);
- writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten); memset(&priv->cfg, 0, sizeof(priv->cfg));
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index e15d3ae..7a5d653 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -178,6 +178,7 @@ struct fsl_esdhc_cfg { u32 sdhc_clk; u8 max_bus_width; u8 wp_enable;
- u8 vs18_enable; /* Use 1.8V if set to 1 */ struct mmc_config cfg;
};
participants (2)
-
Jaehoon Chung
-
Peng Fan