[U-Boot] [PATCH v2 23/26] mmc: Retry some MMC cmds on failure

Jaehoon Chung jh80.chung at samsung.com
Fri Sep 22 13:54:38 UTC 2017


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



More information about the U-Boot mailing list