Merge tag 'mmc-2020-6-24' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
authorTom Rini <trini@konsulko.com>
Wed, 24 Jun 2020 13:05:35 +0000 (09:05 -0400)
committerTom Rini <trini@konsulko.com>
Wed, 24 Jun 2020 13:05:35 +0000 (09:05 -0400)
- Fix fsl_esdhc_imx tunning mask
- Disable CMD CRC for normal tuning for fsl_esdhc_imx
- Retry CM1 until emmc ready
- Fix sdhci HISPD handling
- Cache-aligned extcsd reading

cmd/mmc.c
drivers/mmc/fsl_esdhc_imx.c
drivers/mmc/mmc.c
drivers/mmc/sdhci.c
include/fsl_esdhc_imx.h

index 1c252e050282403904d2be7bedb01f3b43d5b708..1529a3e05dddbb6f4143c1e65bfb06a7f21dd4a7 100644 (file)
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -8,6 +8,7 @@
 #include <blk.h>
 #include <command.h>
 #include <console.h>
+#include <memalign.h>
 #include <mmc.h>
 #include <part.h>
 #include <sparse_format.h>
@@ -56,7 +57,8 @@ static void print_mmcinfo(struct mmc *mmc)
        if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
                bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
                bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
-               u8 wp, ext_csd[MMC_MAX_BLOCK_LEN];
+               ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+               u8 wp;
                int ret;
 
 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
index f42e01843434127bca39026bff05e5e27f271a2c..5b61eeb21468bb985813e3a27e01bbb7b02779bc 100644 (file)
@@ -907,19 +907,9 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
                ctrl = readl(&regs->autoc12err);
                if ((!(ctrl & MIX_CTRL_EXE_TUNE)) &&
                    (ctrl & MIX_CTRL_SMPCLK_SEL)) {
-                       /*
-                        * need to wait some time, make sure sd/mmc fininsh
-                        * send out tuning data, otherwise, the sd/mmc can't
-                        * response to any command when the card still out
-                        * put the tuning data.
-                        */
-                       mdelay(1);
                        ret = 0;
                        break;
                }
-
-               /* Add 1ms delay for SD and eMMC */
-               mdelay(1);
        }
 
        writel(irqstaten, &regs->irqstaten);
@@ -1267,6 +1257,18 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
                        val |= priv->tuning_start_tap;
                        val &= ~ESDHC_TUNING_STEP_MASK;
                        val |= (priv->tuning_step) << ESDHC_TUNING_STEP_SHIFT;
+
+                       /* Disable the CMD CRC check for tuning, if not, need to
+                        * add some delay after every tuning command, because
+                        * hardware standard tuning logic will directly go to next
+                        * step once it detect the CMD CRC error, will not wait for
+                        * the card side to finally send out the tuning data, trigger
+                        * the buffer read ready interrupt immediately. If usdhc send
+                        * the next tuning command some eMMC card will stuck, can't
+                        * response, block the tuning procedure or the first command
+                        * after the whole tuning procedure always can't get any response.
+                        */
+                       val |= ESDHC_TUNING_CMD_CRC_CHECK_DISABLE;
                        writel(val, &regs->tuning_ctrl);
                }
        }
index 620bb930640fc6df2ec41cbd1668504ed7cd98a0..725a36799d355ae7b3dd922f68e54495cf2b480e 100644 (file)
@@ -669,12 +669,15 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
 static int mmc_send_op_cond(struct mmc *mmc)
 {
        int err, i;
+       int timeout = 1000;
+       uint start;
 
        /* Some cards seem to need this */
        mmc_go_idle(mmc);
 
+       start = get_timer(0);
        /* Asking to the card its capabilities */
-       for (i = 0; i < 2; i++) {
+       for (i = 0; ; i++) {
                err = mmc_send_op_cond_iter(mmc, i != 0);
                if (err)
                        return err;
@@ -682,6 +685,10 @@ static int mmc_send_op_cond(struct mmc *mmc)
                /* exit if not busy (flag seems to be inverted) */
                if (mmc->ocr & OCR_BUSY)
                        break;
+
+               if (get_timer(start) > timeout)
+                       return -ETIMEDOUT;
+               udelay(100);
        }
        mmc->op_cond_pending = 1;
        return 0;
index 92cc8434af240a7f9f62acb087644db251514aa9..f4eb655f6ec17333a94685e30ad6fb2d7f52a908 100644 (file)
@@ -567,6 +567,7 @@ static int sdhci_set_ios(struct mmc *mmc)
 #endif
        u32 ctrl;
        struct sdhci_host *host = mmc->priv;
+       bool no_hispd_bit = false;
 
        if (host->ops && host->ops->set_control_reg)
                host->ops->set_control_reg(host);
@@ -594,14 +595,26 @@ static int sdhci_set_ios(struct mmc *mmc)
                        ctrl &= ~SDHCI_CTRL_4BITBUS;
        }
 
-       if (mmc->clock > 26000000)
-               ctrl |= SDHCI_CTRL_HISPD;
-       else
-               ctrl &= ~SDHCI_CTRL_HISPD;
-
        if ((host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) ||
-           (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE))
+           (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE)) {
                ctrl &= ~SDHCI_CTRL_HISPD;
+               no_hispd_bit = true;
+       }
+
+       if (!no_hispd_bit) {
+               if (mmc->selected_mode == MMC_HS ||
+                   mmc->selected_mode == SD_HS ||
+                   mmc->selected_mode == MMC_DDR_52 ||
+                   mmc->selected_mode == MMC_HS_200 ||
+                   mmc->selected_mode == MMC_HS_400 ||
+                   mmc->selected_mode == UHS_SDR25 ||
+                   mmc->selected_mode == UHS_SDR50 ||
+                   mmc->selected_mode == UHS_SDR104 ||
+                   mmc->selected_mode == UHS_DDR50)
+                       ctrl |= SDHCI_CTRL_HISPD;
+               else
+                       ctrl &= ~SDHCI_CTRL_HISPD;
+       }
 
        sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
index 33c6d52bfe950ec3fe2739288690baa31beb0bf2..279a66d9bff4a84705e60cccda6c53b1b341ca8f 100644 (file)
 #define ESDHC_STD_TUNING_EN             BIT(24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
 #define ESDHC_TUNING_START_TAP_DEFAULT 0x1
-#define ESDHC_TUNING_START_TAP_MASK    0xff
+#define ESDHC_TUNING_START_TAP_MASK    0x7f
+#define ESDHC_TUNING_CMD_CRC_CHECK_DISABLE     BIT(7)
 #define ESDHC_TUNING_STEP_MASK         0x00070000
 #define ESDHC_TUNING_STEP_SHIFT                16