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 | |
parent | 2e216be8cf1e38df0f84963222cb6becaf0fc78e (diff) | |
parent | 2243d19e5618122d9d7aba23eb51f63f2719dba5 (diff) | |
download | u-boot-WIP/06Apr2021.zip u-boot-WIP/06Apr2021.tar.gz u-boot-WIP/06Apr2021.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
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 2 | ||||
-rw-r--r-- | cmd/mmc.c | 50 | ||||
-rw-r--r-- | configs/kontron_sl28_defconfig | 2 | ||||
-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 | ||||
-rw-r--r-- | include/fsl_esdhc.h | 3 |
8 files changed, 96 insertions, 18 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index ae0b7b2..9d1ba4c 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -47,6 +47,8 @@ config ARCH_LS1028A select SYS_FSL_ERRATUM_A009663 if !TFABOOT select SYS_FSL_ERRATUM_A009942 if !TFABOOT select SYS_FSL_ERRATUM_A050382 + select SYS_FSL_ERRATUM_A011334 + select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND select RESV_RAM if GIC_V3_ITS imply PANIC_HANG @@ -735,8 +735,45 @@ static int do_mmc_bootbus(struct cmd_tbl *cmdtp, int flag, return CMD_RET_FAILURE; } + /* + * BOOT_BUS_CONDITIONS[177] + * BOOT_MODE[4:3] + * 0x0 : Use SDR + Backward compatible timing in boot operation + * 0x1 : Use SDR + High Speed Timing in boot operation mode + * 0x2 : Use DDR in boot operation + * RESET_BOOT_BUS_CONDITIONS + * 0x0 : Reset bus width to x1, SDR, Backward compatible + * 0x1 : Retain BOOT_BUS_WIDTH and BOOT_MODE + * BOOT_BUS_WIDTH + * 0x0 : x1(sdr) or x4 (ddr) buswidth + * 0x1 : x4(sdr/ddr) buswith + * 0x2 : x8(sdr/ddr) buswith + * + */ + if (width >= 0x3) { + printf("boot_bus_width %d is invalid\n", width); + return CMD_RET_FAILURE; + } + + if (reset >= 0x2) { + printf("reset_boot_bus_width %d is invalid\n", reset); + return CMD_RET_FAILURE; + } + + if (mode >= 0x3) { + printf("reset_boot_bus_width %d is invalid\n", mode); + return CMD_RET_FAILURE; + } + /* acknowledge to be sent during boot operation */ - return mmc_set_boot_bus_width(mmc, width, reset, mode); + if (mmc_set_boot_bus_width(mmc, width, reset, mode)) { + puts("BOOT_BUS_WIDTH is failed to change.\n"); + return CMD_RET_FAILURE; + } + + printf("Set to BOOT_BUS_WIDTH = 0x%x, RESET = 0x%x, BOOT_MODE = 0x%x\n", + width, reset, mode); + return CMD_RET_SUCCESS; } static int do_mmc_boot_resize(struct cmd_tbl *cmdtp, int flag, @@ -1008,11 +1045,14 @@ U_BOOT_CMD( "mmc list - lists available devices\n" "mmc wp - power on write protect boot partitions\n" #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING) - "mmc hwpartition [args...] - does hardware partitioning\n" + "mmc hwpartition <USER> <GP> <MODE> - does hardware partitioning\n" " arguments (sizes in 512-byte blocks):\n" - " [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n" - " [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n" - " [check|set|complete] - mode, complete set partitioning completed\n" + " USER - <user> <enh> <start> <cnt> <wrrel> <{on|off}>\n" + " : sets user data area attributes\n" + " GP - <{gp1|gp2|gp3|gp4}> <cnt> <enh> <wrrel> <{on|off}>\n" + " : general purpose partition\n" + " MODE - <{check|set|complete}>\n" + " : mode, complete set partitioning completed\n" " WARNING: Partitioning is a write-once setting once it is set to complete.\n" " Power cycling is required to initialize partitions after set to complete.\n" #endif diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig index 0c6c191..1c781e0 100644 --- a/configs/kontron_sl28_defconfig +++ b/configs/kontron_sl28_defconfig @@ -70,7 +70,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y CONFIG_I2C_DEFAULT_BUS_NUMBER=0 CONFIG_I2C_MUX=y CONFIG_DM_MMC=y -CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y CONFIG_FSL_ESDHC=y CONFIG_FSL_ESDHC_SUPPORT_ADMA2=y CONFIG_DM_SPI_FLASH=y 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) diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index 850a304..f86afe5 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -190,6 +190,9 @@ #define DLL_RESET 0x40000000 #define DLL_FREQ_SEL 0x08000000 +/* DLL config 1 register */ +#define DLL_PD_PULSE_STRETCH_SEL 0x80000000 + /* DLL status 0 register */ #define DLL_STS_SLV_LOCK 0x08000000 |