mmc: renesas_sdhi: Add a condition of cmd/data timeout for retune
authorYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Wed, 23 Dec 2020 07:30:22 +0000 (16:30 +0900)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 1 Feb 2021 10:54:43 +0000 (11:54 +0100)
According to the datasheet, this controller needs retune when
cmd or data timeout happens. So, add a condition into .check_retune().

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://lore.kernel.org/r/1608708622-29668-3-git-send-email-yoshihiro.shimoda.uh@renesas.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/renesas_sdhi_core.c
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc_core.c

index 38f028e..158c21e 100644 (file)
@@ -768,10 +768,12 @@ static bool renesas_sdhi_auto_correction(struct tmio_mmc_host *host)
        return false;
 }
 
-static bool renesas_sdhi_check_scc_error(struct tmio_mmc_host *host)
+static bool renesas_sdhi_check_scc_error(struct tmio_mmc_host *host,
+                                        struct mmc_request *mrq)
 {
        struct renesas_sdhi *priv = host_to_priv(host);
        bool use_4tap = priv->quirks && priv->quirks->hs400_4taps;
+       bool ret = false;
 
        /*
         * Skip checking SCC errors when running on 4 taps in HS400 mode as
@@ -785,11 +787,19 @@ static bool renesas_sdhi_check_scc_error(struct tmio_mmc_host *host)
        if (mmc_doing_tune(host->mmc))
                return false;
 
+       if (((mrq->cmd->error == -ETIMEDOUT) ||
+            (mrq->data && mrq->data->error == -ETIMEDOUT)) &&
+           ((host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
+            (host->ops.get_cd && host->ops.get_cd(host->mmc))))
+               ret |= true;
+
        if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL) &
            SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN)
-               return renesas_sdhi_auto_correction(host);
+               ret |= renesas_sdhi_auto_correction(host);
+       else
+               ret |= renesas_sdhi_manual_correction(host, use_4tap);
 
-       return renesas_sdhi_manual_correction(host, use_4tap);
+       return ret;
 }
 
 static int renesas_sdhi_wait_idle(struct tmio_mmc_host *host, u32 bit)
index 784fa6e..2d1db93 100644 (file)
@@ -181,7 +181,7 @@ struct tmio_mmc_host {
                              unsigned int direction, int blk_size);
        int (*write16_hook)(struct tmio_mmc_host *host, int addr);
        void (*reset)(struct tmio_mmc_host *host);
-       bool (*check_retune)(struct tmio_mmc_host *host);
+       bool (*check_retune)(struct tmio_mmc_host *host, struct mmc_request *mrq);
        void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
        unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);
 
index 21492b5..49c2d40 100644 (file)
@@ -804,7 +804,7 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
        }
 
        /* Error means retune, but executed command was still successful */
-       if (host->check_retune && host->check_retune(host))
+       if (host->check_retune && host->check_retune(host, mrq))
                mmc_retune_needed(host->mmc);
 
        /* If SET_BLOCK_COUNT, continue with main command */