On Fri, 23 Oct 2020 at 00:24, Michael Walle <michael@xxxxxxxx> wrote: > > On rare occations there is the following error: > > mmc0: Tuning timeout, falling back to fixed sampling clock > > There are SD cards which takes a significant longer time to reply to the > first CMD19 command. The eSDHC takes the data timeout value into account > during the tuning period. The SDHCI core doesn't explicitly set this > timeout for the tuning procedure. Thus on the slow cards, there might be > a spurious "Buffer Read Ready" interrupt, which in turn triggers a wrong > sequence of events. In the end this will lead to an unsuccessful tuning > procedure and to the above error. > > To workaround this, set the timeout to the maximum value (which is the > best we can do) and the SDHCI core will take care of the proper timeout > handling. > > Fixes: ba49cbd0936e ("mmc: sdhci-of-esdhc: add tuning support") > Signed-off-by: Michael Walle <michael@xxxxxxxx> > Acked-by: Adrian Hunter <adrian.hunter@xxxxxxxxx> Applied for fixes and by adding a stable tag, thanks! I am not sure for what stable kernel this applies to, but I guess we will get notified about that, sooner or later. Kind regards Uffe > > --- > Changes since v1: > - Added fixes tag. Suggested by Ulf Hansson. > > drivers/mmc/host/sdhci-of-esdhc.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c > index 0b45eff6fed4..baf7801a1804 100644 > --- a/drivers/mmc/host/sdhci-of-esdhc.c > +++ b/drivers/mmc/host/sdhci-of-esdhc.c > @@ -1052,6 +1052,17 @@ static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) > > esdhc_tuning_block_enable(host, true); > > + /* > + * The eSDHC controller takes the data timeout value into account > + * during tuning. If the SD card is too slow sending the response, the > + * timer will expire and a "Buffer Read Ready" interrupt without data > + * is triggered. This leads to tuning errors. > + * > + * Just set the timeout to the maximum value because the core will > + * already take care of it in sdhci_send_tuning(). > + */ > + sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); > + > hs400_tuning = host->flags & SDHCI_HS400_TUNING; > > do { > -- > 2.20.1 >