[PATCH] mmc: fsl_esdhc_imx: optimize the timing setting

haibo.chen at nxp.com haibo.chen at nxp.com
Tue Nov 3 10:18:35 CET 2020


From: Haibo Chen <haibo.chen at nxp.com>

For imx usdhc/esdhc, once set the DDR_EN, enable the DDR mode, the
card clock will be divied by 2 automatically by the host. So need
to first config the DDR_EN correctly, then update the card clock.
This will make sure the actual card clock is as our expected.
IC also suggest config the DDR_EN firstly, then config the clock
divider.

For HS400/HS400ES mode, need to config the strobe dll, this need
to based on the correct target clock rate, so need to do this after
clock rate is update.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 drivers/mmc/fsl_esdhc_imx.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 3843d61d71..98bc81f2de 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -760,7 +760,6 @@ static int esdhc_set_timing(struct mmc *mmc)
 	case MMC_HS_400_ES:
 		mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
 		esdhc_write32(&regs->mixctrl, mixctrl);
-		esdhc_set_strobe_dll(mmc);
 		break;
 	case MMC_HS:
 	case MMC_HS_52:
@@ -933,6 +932,23 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
 	int ret __maybe_unused;
 	u32 clock;
 
+#ifdef MMC_SUPPORTS_TUNING
+	/*
+	 * call esdhc_set_timing() before update the clock rate,
+	 * This is because current we support DDR and SDR mode,
+	 * Once the DDR_EN bit is set, the card clock will be
+	 * divide by 2 automatically. So need to do this before
+	 * setting clock rate.
+	 */
+	if (priv->mode != mmc->selected_mode) {
+		ret = esdhc_set_timing(mmc);
+		if (ret) {
+			printf("esdhc_set_timing error %d\n", ret);
+			return ret;
+		}
+	}
+#endif
+
 	/* Set the clock speed */
 	clock = mmc->clock;
 	if (clock < mmc->cfg->f_min)
@@ -957,13 +973,13 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
 #endif
 	}
 
-	if (priv->mode != mmc->selected_mode) {
-		ret = esdhc_set_timing(mmc);
-		if (ret) {
-			printf("esdhc_set_timing error %d\n", ret);
-			return ret;
-		}
-	}
+	/*
+	 * For HS400/HS400ES mode, make sure set the strobe dll in the
+	 * target clock rate. So call esdhc_set_strobe_dll() after the
+	 * clock updated.
+	 */
+	if (mmc->selected_mode == MMC_HS_400 || mmc->selected_mode == MMC_HS_400_ES)
+		esdhc_set_strobe_dll(mmc);
 
 	if (priv->signal_voltage != mmc->signal_voltage) {
 		ret = esdhc_set_voltage(mmc);
-- 
2.17.1



More information about the U-Boot mailing list