From: Ye Li <ye...@nxp.com>

According to SD and MMC spec, 74 clocks must be sent to device after
power stable. This is need in reinit ops for DM MMC or init ops for
non-DM MMC after power cycle.

So set the INTIA to send 80 clocks in esdhc_init_common and move
its calling from probe to reinit.

However, on 8MQ EVK and 8QXP MEK with some brands of SD cards, sending
80 clocks may not work well.

The root cause is related with power up time.  According to spec, after
power stable, host shall supply at least 74 SD clocks to the SD card with
the maximum of 1ms. However, the power ram up time is related with the
characteristic of SD card. At the moment of sending 74 SD clocks, the
power probably not ram up to the operating level on the problematic
cards. Then cause the cards not ready.

This patch changes to send SD clock with 1ms duration to replace 80
SD clocks (0.2ms at 400Khz clock).
This way meets the spec requirement as well, and adds the margin for
power ram up time to be compatible with the problematic SD cards.
This is also aligned with implementation which has FORCE clock
always on.

Reviewed-and-tested-by: Haibo Chen <haibo.c...@nxp.com>
Signed-off-by: Ye Li <ye...@nxp.com>
Signed-off-by: Peng Fan <peng....@nxp.com>
---

V2:
 None

 drivers/mmc/fsl_esdhc_imx.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 0ced796ff49..e61c5d544ea 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -1035,6 +1035,11 @@ static int esdhc_init_common(struct fsl_esdhc_priv 
*priv, struct mmc *mmc)
        /* Set timout to the maximum value */
        esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
 
+       /* max 1ms delay with clock on for initialization */
+       esdhc_setbits32(&regs->vendorspec, VENDORSPEC_FRC_SDCLK_ON);
+       udelay(1000);
+       esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_FRC_SDCLK_ON);
+
        return 0;
 }
 
@@ -1569,7 +1574,7 @@ static int fsl_esdhc_probe(struct udevice *dev)
 
        upriv->mmc = mmc;
 
-       return esdhc_init_common(priv, mmc);
+       return 0;
 }
 
 static int fsl_esdhc_get_cd(struct udevice *dev)
@@ -1621,6 +1626,14 @@ static int fsl_esdhc_wait_dat0(struct udevice *dev, int 
state,
        return esdhc_wait_dat0_common(priv, state, timeout_us);
 }
 
+static int fsl_esdhc_reinit(struct udevice *dev)
+{
+       struct fsl_esdhc_plat *plat = dev_get_plat(dev);
+       struct fsl_esdhc_priv *priv = dev_get_priv(dev);
+
+       return esdhc_init_common(priv, &plat->mmc);
+}
+
 static const struct dm_mmc_ops fsl_esdhc_ops = {
        .get_cd         = fsl_esdhc_get_cd,
        .send_cmd       = fsl_esdhc_send_cmd,
@@ -1632,6 +1645,7 @@ static const struct dm_mmc_ops fsl_esdhc_ops = {
        .set_enhanced_strobe = fsl_esdhc_set_enhanced_strobe,
 #endif
        .wait_dat0 = fsl_esdhc_wait_dat0,
+       .reinit = fsl_esdhc_reinit,
 };
 
 static struct esdhc_soc_data usdhc_imx7d_data = {
-- 
2.35.3

Reply via email to