diff options
Diffstat (limited to 'drivers/mmc/fsl_esdhc_imx.c')
-rw-r--r-- | drivers/mmc/fsl_esdhc_imx.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index c0d47ba378..43106dec75 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -101,7 +101,6 @@ struct fsl_esdhc_plat { struct esdhc_soc_data { u32 flags; - u32 caps; }; /** @@ -146,7 +145,7 @@ struct fsl_esdhc_priv { u32 tuning_start_tap; u32 strobe_dll_delay_target; u32 signal_voltage; -#if IS_ENABLED(CONFIG_DM_REGULATOR) +#if CONFIG_IS_ENABLED(DM_REGULATOR) struct udevice *vqmmc_dev; struct udevice *vmmc_dev; #endif @@ -514,9 +513,9 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, /* Workaround for ESDHC errata ENGcm03648 */ if (!data && (cmd->resp_type & MMC_RSP_BUSY)) { - int timeout = 6000; + int timeout = 50000; - /* Poll on DATA0 line for cmd with busy signal for 600 ms */ + /* Poll on DATA0 line for cmd with busy signal for 5000 ms */ while (timeout > 0 && !(esdhc_read32(®s->prsstat) & PRSSTAT_DAT0)) { udelay(100); @@ -704,6 +703,7 @@ static int esdhc_change_pinstate(struct udevice *dev) case UHS_SDR104: case MMC_HS_200: case MMC_HS_400: + case MMC_HS_400_ES: ret = pinctrl_select_state(dev, "state_200mhz"); break; default: @@ -774,6 +774,7 @@ static int esdhc_set_timing(struct mmc *mmc) writel(mixctrl, ®s->mixctrl); break; case MMC_HS_400: + case MMC_HS_400_ES: mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN; writel(mixctrl, ®s->mixctrl); esdhc_set_strobe_dll(mmc); @@ -1426,10 +1427,8 @@ static int fsl_esdhc_probe(struct udevice *dev) priv->esdhc_regs = (struct fsl_esdhc *)addr; priv->dev = dev; priv->mode = -1; - if (data) { + if (data) priv->flags = data->flags; - priv->caps = data->caps; - } val = dev_read_u32_default(dev, "bus-width", -1); if (val == 8) @@ -1490,9 +1489,6 @@ static int fsl_esdhc_probe(struct udevice *dev) } #endif - if (fdt_get_property(fdt, node, "no-1-8-v", NULL)) - priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_HS400); - /* * TODO: * Because lack of clk driver, if SDHC clk is not enabled, @@ -1515,7 +1511,7 @@ static int fsl_esdhc_probe(struct udevice *dev) init_clk_usdhc(dev->seq); - if (IS_ENABLED(CONFIG_CLK)) { + if (CONFIG_IS_ENABLED(CLK)) { /* Assigned clock already set clock */ ret = clk_get_by_name(dev, "per", &priv->per_clk); if (ret) { @@ -1543,6 +1539,10 @@ static int fsl_esdhc_probe(struct udevice *dev) return ret; } + ret = mmc_of_parse(dev, &plat->cfg); + if (ret) + return ret; + mmc = &plat->mmc; mmc->cfg = &plat->cfg; mmc->dev = dev; @@ -1596,6 +1596,21 @@ static int fsl_esdhc_set_ios(struct udevice *dev) return esdhc_set_ios_common(priv, &plat->mmc); } +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) +static int fsl_esdhc_set_enhanced_strobe(struct udevice *dev) +{ + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + struct fsl_esdhc *regs = priv->esdhc_regs; + u32 m; + + m = readl(®s->mixctrl); + m |= MIX_CTRL_HS400_ES; + writel(m, ®s->mixctrl); + + return 0; +} +#endif + static const struct dm_mmc_ops fsl_esdhc_ops = { .get_cd = fsl_esdhc_get_cd, .send_cmd = fsl_esdhc_send_cmd, @@ -1603,6 +1618,9 @@ static const struct dm_mmc_ops fsl_esdhc_ops = { #ifdef MMC_SUPPORTS_TUNING .execute_tuning = fsl_esdhc_execute_tuning, #endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + .set_enhanced_strobe = fsl_esdhc_set_enhanced_strobe, +#endif }; #endif @@ -1610,8 +1628,12 @@ static struct esdhc_soc_data usdhc_imx7d_data = { .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HS400, - .caps = UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_DDR_52MHz | - MMC_MODE_HS_52MHz | MMC_MODE_HS, +}; + +static struct esdhc_soc_data usdhc_imx8qm_data = { + .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING | + ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | + ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES, }; static const struct udevice_id fsl_esdhc_ids[] = { @@ -1622,6 +1644,7 @@ static const struct udevice_id fsl_esdhc_ids[] = { { .compatible = "fsl,imx6q-usdhc", }, { .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,}, { .compatible = "fsl,imx7ulp-usdhc", }, + { .compatible = "fsl,imx8qm-usdhc", .data = (ulong)&usdhc_imx8qm_data,}, { .compatible = "fsl,esdhc", }, { /* sentinel */ } }; |