aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorHaibo Chen <haibo.chen@nxp.com>2020-11-03 17:18:35 +0800
committerStefano Babic <sbabic@denx.de>2020-12-06 15:31:37 +0100
commit5d772196d93509306f9a4333e181a64f3e7e4249 (patch)
treeb61037e092ab54e2a990e3d69512985cc182febb /drivers/mmc
parentea51af2fdd87bb5da024507c9233a038e84e8737 (diff)
downloadu-boot-5d772196d93509306f9a4333e181a64f3e7e4249.zip
u-boot-5d772196d93509306f9a4333e181a64f3e7e4249.tar.gz
u-boot-5d772196d93509306f9a4333e181a64f3e7e4249.tar.bz2
mmc: fsl_esdhc_imx: optimize the timing setting
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@nxp.com> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 29592d1..e5409ad 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);