From: Haibo Chen Date: Tue, 3 Nov 2020 09:18:35 +0000 (+0800) Subject: mmc: fsl_esdhc_imx: optimize the timing setting X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=5d772196d93509306f9a4333e181a64f3e7e4249;p=u-boot.git 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 Reviewed-by: Jaehoon Chung --- diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 29592d1f2c..e5409ade1b 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(®s->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);