On 23/12/22 04:50, haibo.chen@xxxxxxx wrote: > From: Haibo Chen <haibo.chen@xxxxxxx> > > Clear auto tuning bit when reset tuning, and enable auto tuning > only after tuning done successfully for both standard tuning and > manual tuning. > > Signed-off-by: Haibo Chen <haibo.chen@xxxxxxx> Acked-by: Adrian Hunter <adrian.hunter@xxxxxxxxx> > --- > drivers/mmc/host/sdhci-esdhc-imx.c | 25 ++++++++++++++++--------- > 1 file changed, 16 insertions(+), 9 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c > index 89ef0c80ac37..bf8d6f60a9ee 100644 > --- a/drivers/mmc/host/sdhci-esdhc-imx.c > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c > @@ -429,9 +429,10 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host) > } > > /* Enable the auto tuning circuit to check the CMD line and BUS line */ > -static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host) > +static inline void usdhc_auto_tuning_mode_sel_and_en(struct sdhci_host *host) > { > u32 buswidth, auto_tune_buswidth; > + u32 reg; > > buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); > > @@ -450,6 +451,10 @@ static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host) > esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, > auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, > ESDHC_VEND_SPEC2); > + > + reg = readl(host->ioaddr + ESDHC_MIX_CTRL); > + reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; > + writel(reg, host->ioaddr + ESDHC_MIX_CTRL); > } > > static u32 esdhc_readl_le(struct sdhci_host *host, int reg) > @@ -681,14 +686,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) > } else { > v &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; > m &= ~ESDHC_MIX_CTRL_FBCLK_SEL; > - m &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN; > } > > if (val & SDHCI_CTRL_EXEC_TUNING) { > v |= ESDHC_MIX_CTRL_EXE_TUNE; > m |= ESDHC_MIX_CTRL_FBCLK_SEL; > - m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; > - usdhc_auto_tuning_mode_sel(host); > } else { > v &= ~ESDHC_MIX_CTRL_EXE_TUNE; > } > @@ -1022,13 +1024,15 @@ static void esdhc_reset_tuning(struct sdhci_host *host) > > /* Reset the tuning circuit */ > if (esdhc_is_usdhc(imx_data)) { > + ctrl = readl(host->ioaddr + ESDHC_MIX_CTRL); > + ctrl &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN; > if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { > - ctrl = readl(host->ioaddr + ESDHC_MIX_CTRL); > ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; > ctrl &= ~ESDHC_MIX_CTRL_FBCLK_SEL; > writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); > writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); > } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { > + writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); > ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); > ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; > ctrl &= ~ESDHC_MIX_CTRL_EXE_TUNE; > @@ -1054,6 +1058,7 @@ static void esdhc_reset_tuning(struct sdhci_host *host) > static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) > { > struct sdhci_host *host = mmc_priv(mmc); > + int err; > > /* > * i.MX uSDHC internally already uses a fixed optimized timing for > @@ -1068,7 +1073,12 @@ static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) > * correct delay cell. > */ > esdhc_reset_tuning(host); > - return sdhci_execute_tuning(mmc, opcode); > + err = sdhci_execute_tuning(mmc, opcode); > + /* If tuning done, enable auto tuning */ > + if (!err && !host->tuning_err) > + usdhc_auto_tuning_mode_sel_and_en(host); > + > + return err; > } > > static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val) > @@ -1102,11 +1112,8 @@ static void esdhc_post_tuning(struct sdhci_host *host) > { > u32 reg; > > - usdhc_auto_tuning_mode_sel(host); > - > reg = readl(host->ioaddr + ESDHC_MIX_CTRL); > reg &= ~ESDHC_MIX_CTRL_EXE_TUNE; > - reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; > writel(reg, host->ioaddr + ESDHC_MIX_CTRL); > } >