lkml.org 
[lkml]   [2020]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 153/232] mmc: sdhci-of-esdhc: fix esdhc_reset() for different controller versions
    Date
    From: Yangbo Lu <yangbo.lu@nxp.com>

    commit 2aa3d826adb578b26629a79b775a552cfe3fedf7 upstream.

    This patch is to fix operating in esdhc_reset() for different
    controller versions, and to add bus-width restoring after data
    reset for eSDHC (verdor version <= 2.2).

    Also add annotation for understanding.

    Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
    Acked-by: Adrian Hunter <adrian.hunter@intel.com>
    Link: https://lore.kernel.org/r/20200108040713.38888-1-yangbo.lu@nxp.com
    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 | 43 ++++++++++++++++++++++++++++++++++----
    1 file changed, 39 insertions(+), 4 deletions(-)

    --- a/drivers/mmc/host/sdhci-of-esdhc.c
    +++ b/drivers/mmc/host/sdhci-of-esdhc.c
    @@ -734,23 +734,58 @@ static void esdhc_reset(struct sdhci_hos
    {
    struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
    struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
    - u32 val;
    + u32 val, bus_width = 0;

    + /*
    + * Add delay to make sure all the DMA transfers are finished
    + * for quirk.
    + */
    if (esdhc->quirk_delay_before_data_reset &&
    (mask & SDHCI_RESET_DATA) &&
    (host->flags & SDHCI_REQ_USE_DMA))
    mdelay(5);

    + /*
    + * Save bus-width for eSDHC whose vendor version is 2.2
    + * or lower for data reset.
    + */
    + if ((mask & SDHCI_RESET_DATA) &&
    + (esdhc->vendor_ver <= VENDOR_V_22)) {
    + val = sdhci_readl(host, ESDHC_PROCTL);
    + bus_width = val & ESDHC_CTRL_BUSWIDTH_MASK;
    + }
    +
    sdhci_reset(host, mask);

    - sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
    - sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
    + /*
    + * Restore bus-width setting and interrupt registers for eSDHC
    + * whose vendor version is 2.2 or lower for data reset.
    + */
    + if ((mask & SDHCI_RESET_DATA) &&
    + (esdhc->vendor_ver <= VENDOR_V_22)) {
    + val = sdhci_readl(host, ESDHC_PROCTL);
    + val &= ~ESDHC_CTRL_BUSWIDTH_MASK;
    + val |= bus_width;
    + sdhci_writel(host, val, ESDHC_PROCTL);
    +
    + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
    + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
    + }

    - if (mask & SDHCI_RESET_ALL) {
    + /*
    + * Some bits have to be cleaned manually for eSDHC whose spec
    + * version is higher than 3.0 for all reset.
    + */
    + if ((mask & SDHCI_RESET_ALL) &&
    + (esdhc->spec_ver >= SDHCI_SPEC_300)) {
    val = sdhci_readl(host, ESDHC_TBCTL);
    val &= ~ESDHC_TB_EN;
    sdhci_writel(host, val, ESDHC_TBCTL);

    + /*
    + * Initialize eSDHC_DLLCFG1[DLL_PD_PULSE_STRETCH_SEL] to
    + * 0 for quirk.
    + */
    if (esdhc->quirk_unreliable_pulse_detection) {
    val = sdhci_readl(host, ESDHC_DLLCFG1);
    val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL;

    \
     
     \ /
      Last update: 2020-04-16 17:18    [W:4.212 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site