]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
mmc: fsl_esdhc: add workaround for erratum A-011334
authorMichael Walle <michael@walle.cc>
Wed, 17 Mar 2021 14:01:36 +0000 (15:01 +0100)
committerPeng Fan <peng.fan@nxp.com>
Tue, 6 Apr 2021 10:35:55 +0000 (18:35 +0800)
LS1028A SoCs are restricted in what divider values are allowed for HS400
mode. This is basically a port from the corresponding linux driver.

Signed-off-by: Michael Walle <michael@walle.cc>
arch/arm/cpu/armv8/fsl-layerscape/Kconfig
drivers/mmc/Kconfig
drivers/mmc/fsl_esdhc.c

index ae0b7b21e81bd95719f90a291821f1e2d2cdac6d..c0190a233ead4eba4c4c2c08b37a2ca76ba4dd64 100644 (file)
@@ -47,6 +47,7 @@ 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 RESV_RAM if GIC_V3_ITS
        imply PANIC_HANG
 
index c34fce370e553c7b6bcf20d866e17860d0e272e9..b0ff92b5fa11b817a76a116f2eba65e7602eccae 100644 (file)
@@ -813,3 +813,6 @@ config SYS_FSL_ERRATUM_ESDHC135
 
 config SYS_FSL_ERRATUM_ESDHC_A001
        bool
+
+config SYS_FSL_ERRATUM_A011334
+       bool
index 6014e1c5cac93d7560fdcf493cf987c8b9d146bc..09ea1a9de91bcea1dc67a2483928572ce2e03df4 100644 (file)
@@ -518,6 +518,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;
 
@@ -1063,9 +1081,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(&regs->autoc12err, EXECUTE_TUNING);
 
@@ -1073,7 +1096,7 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
        esdhc_write32(&regs->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(&regs->autoc12err);