diff options
author | Tom Rini <trini@konsulko.com> | 2021-04-09 14:41:32 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-04-09 17:08:52 +0300 |
commit | a1e95e3805eacca1162f6049dceb9b1d2726cbf5 (patch) | |
tree | e4499db55ac8ee7b600a873a231b134d0adfc1a4 /drivers/mmc | |
parent | f6127db8cc8dec22cf9cd6d6363d812f659ce517 (diff) | |
parent | 2fc93e5bafdae7cf6373479e054e9f3943fde23c (diff) | |
download | u-boot-a1e95e3805eacca1162f6049dceb9b1d2726cbf5.tar.xz |
Merge tag 'u-boot-imx-20210409' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
u-boot-imx-20210409
-------------------
- Secure Boot :
- HAB for MX8M / MX7ULP
- CAAM fixes
- Fixes for imxrt1020
- Fixes for USDHC driver
- Fixes for Toradex (Colibri / Apalis)
- Switch to DM for several boards
- mx23 olinuxo
- usbarmory
- marsboard / riotboard
- Gateworks GW Ventana
- NXP upstream patches (LPDDR / CAAM / HAB)
CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/7089
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/fsl_esdhc_imx.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 09a5cd61e3..a4675838e5 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -146,6 +146,7 @@ struct esdhc_soc_data { * @start_tuning_tap: the start point for tuning in tuning_ctrl register * @strobe_dll_delay_target: settings in strobe_dllctrl * @signal_voltage: indicating the current voltage + * @signal_voltage_switch_extra_delay_ms: extra delay for IO voltage switch * @cd_gpio: gpio for card detection * @wp_gpio: gpio for write protection */ @@ -170,6 +171,7 @@ struct fsl_esdhc_priv { u32 tuning_start_tap; u32 strobe_dll_delay_target; u32 signal_voltage; + u32 signal_voltage_switch_extra_delay_ms; #if CONFIG_IS_ENABLED(DM_REGULATOR) struct udevice *vqmmc_dev; struct udevice *vmmc_dev; @@ -521,15 +523,6 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, goto out; } - /* Switch voltage to 1.8V if CMD11 succeeded */ - if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) { - esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); - - printf("Run CMD11 1.8V switch\n"); - /* Sleep for 5 ms - max time for card to switch to 1.8V */ - udelay(5000); - } - /* Workaround for ESDHC errata ENGcm03648 */ if (!data && (cmd->resp_type & MMC_RSP_BUSY)) { int timeout = 50000; @@ -660,7 +653,10 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) clk = (pre_div << 8) | (div << 4); #ifdef CONFIG_FSL_USDHC - esdhc_clrbits32(®s->vendorspec, VENDORSPEC_CKEN); + esdhc_clrbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); + ret = readx_poll_timeout(esdhc_read32, ®s->prsstat, tmp, tmp & PRSSTAT_SDOFF, 100); + if (ret) + pr_warn("fsl_esdhc_imx: Internal clock never gate off.\n"); #else esdhc_clrbits32(®s->sysctl, SYSCTL_CKEN); #endif @@ -672,7 +668,7 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) pr_warn("fsl_esdhc_imx: Internal clock never stabilised.\n"); #ifdef CONFIG_FSL_USDHC - esdhc_setbits32(®s->vendorspec, VENDORSPEC_PEREN | VENDORSPEC_CKEN); + esdhc_setbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); #else esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN); #endif @@ -727,8 +723,14 @@ static void esdhc_set_strobe_dll(struct mmc *mmc) struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev); struct fsl_esdhc *regs = priv->esdhc_regs; u32 val; + u32 tmp; + int ret; if (priv->clock > ESDHC_STROBE_DLL_CLK_FREQ) { + esdhc_clrbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); + ret = readx_poll_timeout(esdhc_read32, ®s->prsstat, tmp, tmp & PRSSTAT_SDOFF, 100); + if (ret) + pr_warn("fsl_esdhc_imx: Internal clock never gate off.\n"); esdhc_write32(®s->strobe_dllctrl, ESDHC_STROBE_DLL_CTRL_RESET); /* @@ -746,6 +748,7 @@ static void esdhc_set_strobe_dll(struct mmc *mmc) pr_warn("HS400 strobe DLL status REF not lock!\n"); if (!(val & ESDHC_STROBE_DLL_STS_SLV_LOCK)) pr_warn("HS400 strobe DLL status SLV not lock!\n"); + esdhc_setbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); } } @@ -835,6 +838,14 @@ static int esdhc_set_voltage(struct mmc *mmc) } #endif esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); + /* + * some board like imx8mm-evk need about 18ms to switch + * the IO voltage from 3.3v to 1.8v, common code only + * delay 10ms, so need to delay extra time to make sure + * the IO voltage change to 1.8v. + */ + if (priv->signal_voltage_switch_extra_delay_ms) + mdelay(priv->signal_voltage_switch_extra_delay_ms); if (esdhc_read32(®s->vendorspec) & ESDHC_VENDORSPEC_VSELECT) return 0; @@ -969,14 +980,18 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) #ifdef MMC_SUPPORTS_TUNING if (mmc->clk_disable) { #ifdef CONFIG_FSL_USDHC - esdhc_clrbits32(®s->vendorspec, VENDORSPEC_CKEN); + u32 tmp; + + esdhc_clrbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); + ret = readx_poll_timeout(esdhc_read32, ®s->prsstat, tmp, tmp & PRSSTAT_SDOFF, 100); + if (ret) + pr_warn("fsl_esdhc_imx: Internal clock never gate off.\n"); #else esdhc_clrbits32(®s->sysctl, SYSCTL_CKEN); #endif } else { #ifdef CONFIG_FSL_USDHC - esdhc_setbits32(®s->vendorspec, VENDORSPEC_PEREN | - VENDORSPEC_CKEN); + esdhc_setbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); #else esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN); #endif @@ -1052,7 +1067,7 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) #ifndef CONFIG_FSL_USDHC esdhc_setbits32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN); #else - esdhc_setbits32(®s->vendorspec, VENDORSPEC_HCKEN | VENDORSPEC_IPGEN); + esdhc_setbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); #endif /* Set the initial clock speed */ @@ -1190,8 +1205,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, esdhc_write32(®s->autoc12err, 0); esdhc_write32(®s->clktunectrlstatus, 0); #else - esdhc_setbits32(®s->vendorspec, VENDORSPEC_PEREN | - VENDORSPEC_HCKEN | VENDORSPEC_IPGEN | VENDORSPEC_CKEN); + esdhc_setbits32(®s->vendorspec, VENDORSPEC_FRC_SDCLK_ON); #endif if (priv->vs18_enable) @@ -1446,6 +1460,8 @@ static int fsl_esdhc_of_to_plat(struct udevice *dev) val = fdtdec_get_int(fdt, node, "fsl,strobe-dll-delay-target", ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT); priv->strobe_dll_delay_target = val; + val = fdtdec_get_int(fdt, node, "fsl,signal-voltage-switch-extra-delay-ms", 0); + priv->signal_voltage_switch_extra_delay_ms = val; if (dev_read_bool(dev, "broken-cd")) priv->broken_cd = 1; |