Skip to content

Commit

Permalink
mmc: sdhci-of-esdhc: set timeout to max before tuning
Browse files Browse the repository at this point in the history
commit 0add6e9 upstream.

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: ba49cbd ("mmc: sdhci-of-esdhc: add tuning support")
Signed-off-by: Michael Walle <michael@walle.cc>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20201022222337.19857-1-michael@walle.cc
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
mwalle authored and gregkh committed Nov 5, 2020
1 parent b7e1a63 commit fb4e2a6
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/mmc/host/sdhci-of-esdhc.c
Expand Up @@ -1004,6 +1004,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 {
Expand Down

0 comments on commit fb4e2a6

Please sign in to comment.