On 22/09/2017 15:54, Jaehoon Chung wrote:
On 09/21/2017 11:30 PM, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I <kis...@ti.com>

With certain SD cards like Kingston 8GB/16GB UHS card, it is seen that
MMC_CMD_ALL_SEND_CID cmd fails on first attempt, but succeeds
subsequently. Therefore, retry MMC_CMD_ALL_SEND_CID cmd a few time
as done in Linux kernel.
Similarly, it is seen that MMC_CMD_SET_BLOCKLEN may fail on first
attempt, therefore retry this cmd a few times as done in kernel.

To make it clear that those are optionnal workarounds, a new Kconfig
option 'MMC_QUIRKS' is added (enabled by default).

Signed-off-by: Vignesh R <vigne...@ti.com>
Signed-off-by: Kishon Vijay Abraham I <kis...@ti.com>
Signed-off-by: Jean-Jacques Hiblot <jjhib...@ti.com>
---
  drivers/mmc/Kconfig |  9 +++++++++
  drivers/mmc/mmc.c   | 41 +++++++++++++++++++++++++++++++++++++++--
  include/mmc.h       |  4 ++++
  3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 3d577e0..78e58d4 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -33,6 +33,15 @@ config SPL_DM_MMC
if MMC +config MMC_QUIRKS
+       bool "Enable quirks"
+       default y
+       help
+         Some cards and hosts may sometimes behave unexpectedly (quirks).
+         This option enable workarounds to handle those quirks. Some of them
+         are enabled by default, other may require additionnal flags or are
+         enabled by the host driver.
+
  config MMC_VERBOSE
        bool "Output more information about the MMC"
        default y
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index c5eaeaf..6d1bf94 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -279,6 +279,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
  int mmc_set_blocklen(struct mmc *mmc, int len)
  {
        struct mmc_cmd cmd;
+       int err;
if (mmc->ddr_mode)
                return 0;
@@ -287,7 +288,24 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
        cmd.resp_type = MMC_RSP_R1;
        cmd.cmdarg = len;
- return mmc_send_cmd(mmc, &cmd, NULL);
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+
+#ifdef CONFIG_MMC_QUIRKS
+       if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) {
+               int retries = 4;
+               /*
+                * It has been seen that SET_BLOCKLEN may fail on the first
+                * attempt, let's try a few more time
+                */
+               do {
+                       err = mmc_send_cmd(mmc, &cmd, NULL);
+                       if (!err)
+                               break;
+               } while (retries--);
+       }
+#endif
+
+       return err;
  }
static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
@@ -1881,7 +1899,6 @@ static int mmc_startup(struct mmc *mmc)
                cmd.resp_type = MMC_RSP_R1;
                cmd.cmdarg = 1;
                err = mmc_send_cmd(mmc, &cmd, NULL);
-
                if (err)
                        return err;
        }
@@ -1895,6 +1912,21 @@ static int mmc_startup(struct mmc *mmc)
err = mmc_send_cmd(mmc, &cmd, NULL); +#ifdef CONFIG_MMC_QUIRKS
+       if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
+               int retries = 4;
+               /*
+                * It has been seen that SEND_CID may fail on the first
+                * attempt, let's try a few more time
+                */
+               do {
+                       err = mmc_send_cmd(mmc, &cmd, NULL);
+                       if (!err)
+                               break;
+               } while (retries--);
+       }
+#endif
+
        if (err)
                return err;
@@ -2239,6 +2271,11 @@ int mmc_start_init(struct mmc *mmc)
        if (err)
                return err;
+#ifdef CONFIG_MMC_QUIRKS
+       mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
+                     MMC_QUIRK_RETRY_SEND_CID;
+#endif
+
        err = mmc_power_cycle(mmc);
        if (err) {
                /*
diff --git a/include/mmc.h b/include/mmc.h
index a8901bf..a9ebc88 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -306,6 +306,9 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
  #define ENHNCD_SUPPORT                (0x2)
  #define PART_ENH_ATTRIB               (0x1f)
+#define MMC_QUIRK_RETRY_SEND_CID BIT(0)
+#define MMC_QUIRK_RETRY_SET_BLOCKLEN   BIT(1)
+
  enum mmc_voltage {
        MMC_SIGNAL_VOLTAGE_000 = 0,
        MMC_SIGNAL_VOLTAGE_120,
@@ -591,6 +594,7 @@ struct mmc {
                                  * operating mode due to limitations when
                                  * accessing the boot partitions
                                  */
+       u32 quirks;
Use the #ifdef MMC_QUIRK for quirks?
OK. I'll fix it in the next round
Thanks,
Jean-Jacques

  };
struct mmc_hwpart_conf {



_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to