[PATCH 2/5] mmc: fsl_esdhc_imx: Send 80 clocks before IDLE command

Peng Fan (OSS) peng.fan at oss.nxp.com
Mon Sep 30 08:50:38 CEST 2024


From: Ye Li <ye.li at 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.chen at nxp.com>
Signed-off-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 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 f22b03657a3..7215237c458 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -1036,6 +1036,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;
 }
 
@@ -1581,7 +1586,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)
@@ -1633,6 +1638,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,
@@ -1644,6 +1657,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



More information about the U-Boot mailing list