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? > }; > > struct mmc_hwpart_conf { > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot