Commit c8c49a5a authored by Haibo Chen's avatar Haibo Chen Committed by Ulf Hansson

mmc: sdhci-esdhc-imx: simplify the auto tuning logic

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: default avatarHaibo Chen <haibo.chen@nxp.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20221223025022.1893102-2-haibo.chen@nxp.comSigned-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 08e03039
...@@ -430,9 +430,10 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host) ...@@ -430,9 +430,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 */ /* 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 buswidth, auto_tune_buswidth;
u32 reg;
buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL));
...@@ -451,6 +452,10 @@ static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host) ...@@ -451,6 +452,10 @@ static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
ESDHC_VEND_SPEC2); 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) static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
...@@ -682,14 +687,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) ...@@ -682,14 +687,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
} else { } else {
v &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; v &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
m &= ~ESDHC_MIX_CTRL_FBCLK_SEL; m &= ~ESDHC_MIX_CTRL_FBCLK_SEL;
m &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN;
} }
if (val & SDHCI_CTRL_EXEC_TUNING) { if (val & SDHCI_CTRL_EXEC_TUNING) {
v |= ESDHC_MIX_CTRL_EXE_TUNE; v |= ESDHC_MIX_CTRL_EXE_TUNE;
m |= ESDHC_MIX_CTRL_FBCLK_SEL; m |= ESDHC_MIX_CTRL_FBCLK_SEL;
m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
usdhc_auto_tuning_mode_sel(host);
} else { } else {
v &= ~ESDHC_MIX_CTRL_EXE_TUNE; v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
} }
...@@ -1023,13 +1025,15 @@ static void esdhc_reset_tuning(struct sdhci_host *host) ...@@ -1023,13 +1025,15 @@ static void esdhc_reset_tuning(struct sdhci_host *host)
/* Reset the tuning circuit */ /* Reset the tuning circuit */
if (esdhc_is_usdhc(imx_data)) { 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) { 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_SMPCLK_SEL;
ctrl &= ~ESDHC_MIX_CTRL_FBCLK_SEL; ctrl &= ~ESDHC_MIX_CTRL_FBCLK_SEL;
writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL);
writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { } 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 = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
ctrl &= ~ESDHC_MIX_CTRL_EXE_TUNE; ctrl &= ~ESDHC_MIX_CTRL_EXE_TUNE;
...@@ -1055,6 +1059,7 @@ static void esdhc_reset_tuning(struct sdhci_host *host) ...@@ -1055,6 +1059,7 @@ static void esdhc_reset_tuning(struct sdhci_host *host)
static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
{ {
struct sdhci_host *host = mmc_priv(mmc); struct sdhci_host *host = mmc_priv(mmc);
int err;
/* /*
* i.MX uSDHC internally already uses a fixed optimized timing for * i.MX uSDHC internally already uses a fixed optimized timing for
...@@ -1069,7 +1074,12 @@ static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -1069,7 +1074,12 @@ static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
* correct delay cell. * correct delay cell.
*/ */
esdhc_reset_tuning(host); 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) static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
...@@ -1103,11 +1113,8 @@ static void esdhc_post_tuning(struct sdhci_host *host) ...@@ -1103,11 +1113,8 @@ static void esdhc_post_tuning(struct sdhci_host *host)
{ {
u32 reg; u32 reg;
usdhc_auto_tuning_mode_sel(host);
reg = readl(host->ioaddr + ESDHC_MIX_CTRL); reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
reg &= ~ESDHC_MIX_CTRL_EXE_TUNE; reg &= ~ESDHC_MIX_CTRL_EXE_TUNE;
reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
writel(reg, host->ioaddr + ESDHC_MIX_CTRL); writel(reg, host->ioaddr + ESDHC_MIX_CTRL);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment