
On 09/21/2017 11:30 PM, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I kishon@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 vigneshr@ti.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@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?
};
struct mmc_hwpart_conf {