diff options
author | Tom Rini <trini@konsulko.com> | 2021-04-06 22:42:55 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-04-06 22:42:55 -0400 |
commit | 02395fec007657c5beb4f7fd77784e10b3054c90 (patch) | |
tree | ef219c5928cccb889ec4a50266babb460dbe7386 /drivers | |
parent | 2e216be8cf1e38df0f84963222cb6becaf0fc78e (diff) | |
parent | 2243d19e5618122d9d7aba23eb51f63f2719dba5 (diff) | |
download | u-boot-02395fec007657c5beb4f7fd77784e10b3054c90.zip u-boot-02395fec007657c5beb4f7fd77784e10b3054c90.tar.gz u-boot-02395fec007657c5beb4f7fd77784e10b3054c90.tar.bz2 |
Merge tag 'mmc-2021-4-6' of https://source.denx.de/u-boot/custodians/u-boot-mmcWIP/06Apr2021
Update hwpartition usage
Check bootbus's arguments
workaround for erratum A-011334 for fsl_esdhc driver
add pulse width detection workaround for fsl_esdhc driver
Use alias num before checking mmc index when creating device
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 31 | ||||
-rw-r--r-- | drivers/mmc/mmc-uclass.c | 12 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 8 |
4 files changed, 45 insertions, 12 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c34fce3..4925675 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -813,3 +813,9 @@ config SYS_FSL_ERRATUM_ESDHC135 config SYS_FSL_ERRATUM_ESDHC_A001 bool + +config SYS_FSL_ERRATUM_A011334 + bool + +config SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND + bool diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 6014e1c..7501fdb 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -71,7 +71,8 @@ struct fsl_esdhc { uint sdtimingctl; /* SD timing control register */ char reserved8[20]; /* reserved */ uint dllcfg0; /* DLL config 0 register */ - char reserved9[12]; /* reserved */ + uint dllcfg1; /* DLL config 1 register */ + char reserved9[8]; /* reserved */ uint dllstat0; /* DLL status 0 register */ char reserved10[664];/* reserved */ uint esdhcctl; /* eSDHC control register */ @@ -518,6 +519,24 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) while (sdhc_clk / (div * pre_div) > clock && div < 16) div++; + if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_A011334) && + clock == 200000000 && mmc->selected_mode == MMC_HS_400) { + u32 div_ratio = pre_div * div; + + if (div_ratio <= 4) { + pre_div = 4; + div = 1; + } else if (div_ratio <= 8) { + pre_div = 4; + div = 2; + } else if (div_ratio <= 12) { + pre_div = 4; + div = 3; + } else { + printf("unsupported clock division.\n"); + } + } + mmc->clock = sdhc_clk / pre_div / div; priv->clock = mmc->clock; @@ -749,6 +768,9 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) /* Set timout to the maximum value */ esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16); + if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND)) + esdhc_clrbits32(®s->dllcfg1, DLL_PD_PULSE_STRETCH_SEL); + return 0; } @@ -1063,9 +1085,14 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode) struct fsl_esdhc_plat *plat = dev_get_plat(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); struct fsl_esdhc *regs = priv->esdhc_regs; + struct mmc *mmc = &plat->mmc; u32 val, irqstaten; int i; + if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_A011334) && + plat->mmc.hs400_tuning) + set_sysctl(priv, mmc, mmc->clock); + esdhc_tuning_block_enable(priv, true); esdhc_setbits32(®s->autoc12err, EXECUTE_TUNING); @@ -1073,7 +1100,7 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode) esdhc_write32(®s->irqstaten, IRQSTATEN_BRR); for (i = 0; i < MAX_TUNING_LOOP; i++) { - mmc_send_tuning(&plat->mmc, opcode, NULL); + mmc_send_tuning(mmc, opcode, NULL); mdelay(1); val = esdhc_read32(®s->autoc12err); diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 53eabc9..d36aae3 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -383,18 +383,16 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) { struct blk_desc *bdesc; struct udevice *bdev; - int ret, devnum = -1; + int ret; if (!mmc_get_ops(dev)) return -ENOSYS; -#ifndef CONFIG_SPL_BUILD - /* Use the fixed index with aliase node's index */ - ret = dev_read_alias_seq(dev, &devnum); - debug("%s: alias ret=%d, devnum=%d\n", __func__, ret, devnum); -#endif + + /* Use the fixed index with aliases node's index */ + debug("%s: alias devnum=%d\n", __func__, dev_seq(dev)); ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, - devnum, 512, 0, &bdev); + dev_seq(dev), 512, 0, &bdev); if (ret) { debug("Cannot create block device\n"); return ret; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index b4c8e7f..1e83007 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -3052,9 +3052,11 @@ int mmc_init_device(int num) struct mmc *m; int ret; - ret = uclass_get_device(UCLASS_MMC, num, &dev); - if (ret) - return ret; + if (uclass_get_device_by_seq(UCLASS_MMC, num, &dev)) { + ret = uclass_get_device(UCLASS_MMC, num, &dev); + if (ret) + return ret; + } m = mmc_get_mmc_dev(dev); if (!m) |