| From 0add6e9b88d0632a25323aaf4987dbacb0e4ae64 Mon Sep 17 00:00:00 2001 |
| From: Michael Walle <michael@walle.cc> |
| Date: Fri, 23 Oct 2020 00:23:37 +0200 |
| Subject: mmc: sdhci-of-esdhc: set timeout to max before tuning |
| |
| From: Michael Walle <michael@walle.cc> |
| |
| commit 0add6e9b88d0632a25323aaf4987dbacb0e4ae64 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: ba49cbd0936e ("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> |
| |
| --- |
| drivers/mmc/host/sdhci-of-esdhc.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| --- a/drivers/mmc/host/sdhci-of-esdhc.c |
| +++ b/drivers/mmc/host/sdhci-of-esdhc.c |
| @@ -1069,6 +1069,17 @@ static int esdhc_execute_tuning(struct m |
| |
| 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 { |