lkml.org 
[lkml]   [2021]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.14 024/125] mmc: sdhci-esdhc-imx: clear the buffer_read_ready to reset standard tuning circuit
    Date
    From: Haibo Chen <haibo.chen@nxp.com>

    commit 9af372dc70e9fdcbb70939dac75365e7b88580b4 upstream.

    To reset standard tuning circuit completely, after clear ESDHC_MIX_CTRL_EXE_TUNE,
    also need to clear bit buffer_read_ready, this operation will finally clear the
    USDHC IP internal logic flag execute_tuning_with_clr_buf, make sure the following
    normal data transfer will not be impacted by standard tuning logic used before.

    Find this issue when do quick SD card insert/remove stress test. During standard
    tuning prodedure, if remove SD card, USDHC standard tuning logic can't clear the
    internal flag execute_tuning_with_clr_buf. Next time when insert SD card, all
    data related commands can't get any data related interrupts, include data transfer
    complete interrupt, data timeout interrupt, data CRC interrupt, data end bit interrupt.
    Always trigger software timeout issue. Even reset the USDHC through bits in register
    SYS_CTRL (0x2C, bit28 reset tuning, bit26 reset data, bit 25 reset command, bit 24
    reset all) can't recover this. From the user's point of view, USDHC stuck, SD can't
    be recognized any more.

    Fixes: d9370424c948 ("mmc: sdhci-esdhc-imx: reset tuning circuit when power on mmc card")
    Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
    Acked-by: Adrian Hunter <adrian.hunter@intel.com>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/1634263236-6111-1-git-send-email-haibo.chen@nxp.com
    Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++++++
    1 file changed, 16 insertions(+)

    --- a/drivers/mmc/host/sdhci-esdhc-imx.c
    +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
    @@ -1133,6 +1133,7 @@ static void esdhc_reset_tuning(struct sd
    struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
    struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
    u32 ctrl;
    + int ret;

    /* Reset the tuning circuit */
    if (esdhc_is_usdhc(imx_data)) {
    @@ -1145,7 +1146,22 @@ static void esdhc_reset_tuning(struct sd
    } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
    ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
    ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
    + ctrl &= ~ESDHC_MIX_CTRL_EXE_TUNE;
    writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS);
    + /* Make sure ESDHC_MIX_CTRL_EXE_TUNE cleared */
    + ret = readl_poll_timeout(host->ioaddr + SDHCI_AUTO_CMD_STATUS,
    + ctrl, !(ctrl & ESDHC_MIX_CTRL_EXE_TUNE), 1, 50);
    + if (ret == -ETIMEDOUT)
    + dev_warn(mmc_dev(host->mmc),
    + "Warning! clear execute tuning bit failed\n");
    + /*
    + * SDHCI_INT_DATA_AVAIL is W1C bit, set this bit will clear the
    + * usdhc IP internal logic flag execute_tuning_with_clr_buf, which
    + * will finally make sure the normal data transfer logic correct.
    + */
    + ctrl = readl(host->ioaddr + SDHCI_INT_STATUS);
    + ctrl |= SDHCI_INT_DATA_AVAIL;
    + writel(ctrl, host->ioaddr + SDHCI_INT_STATUS);
    }
    }
    }

    \
     
     \ /
      Last update: 2021-11-01 10:42    [W:4.100 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site