[PATCH] mmc: core: Modify the CMD1 transmission interval

From: 李晓洁 (Xiaojie Li/13233)

Date: Thu Sep 10 2026 - 03:18:29 EST


Hi Ulf,

Just following up on the patch below.

Could you please let me know if there are any concerns or if further changes are needed?

Best regards,
Xiaojie.Li

-----邮件原件-----
发件人: 李晓洁 (Xiaojie Li/13233) <xiaojie.li2@xxxxxxxxxx>
发送时间: 2026年8月27日 17:15
收件人: Ulf Hansson <ulfh@xxxxxxxxxx>
抄送: linux-mmc@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; 李晓洁 (Xiaojie Li/13233) <xiaojie.li2@xxxxxxxxxx>; 陈文超 (Wenchao Chen) <Wenchao.Chen@xxxxxxxxxx>; 张如泉 (Rain Zhang) <Rain.Zhang@xxxxxxxxxx>; 唐月林 (Yuelin Tang) <yuelin.tang@xxxxxxxxxx>; cixi.geng@xxxxxxxxx
主题: [PATCH] mmc: core: Modify the CMD1 transmission interval

The current code's maximum udelay value is set to 64ms. Since it uses usleep_range(udelay, udelay*2), this results in a maximum wait time of 128ms between two consecutive CMD1 commands. For lower-performance eMMC chips, local testing shows that compared to the old code which used mmc_delay(10), the total time required to wait for the busy bit in the CMD1 response to change has increased by approximately 300ms, negatively impacting the overall eMMC initialization time.

Although the current code sends the CMD1 command fewer times than the old version, the total waiting time is significantly longer.
To address this, it's proposed to modify the CMD1 sending interval to follow a pattern like 4ms, 6ms, 8ms, 10ms, 10ms, etc., effectively capping the longest single wait at 10ms. Local testing confirms that this approach can bring the total time waiting for the busy state change very close to the performance level of the old code.

The eMMC chip used for testing: manfid= 0x00009b, name= Y0S128, mdt= 2022-10 The eMMC part number is: YMEC8B0TE2A2C3

Signed-off-by: Xiaojie Li <xiaojie.li2@xxxxxxxxxx>
---
drivers/mmc/core/mmc_ops.c | 85 ++++++++++++++++----------------------
1 file changed, 36 insertions(+), 49 deletions(-)

diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index a952cc8265af..3076666cf2ca 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -189,64 +189,51 @@ int mmc_go_idle(struct mmc_host *host)
return err;
}

-static int __mmc_send_op_cond_cb(void *cb_data, bool *busy) -{
- struct mmc_op_cond_busy_data *data = cb_data;
- struct mmc_host *host = data->host;
- struct mmc_command *cmd = data->cmd;
- u32 ocr = data->ocr;
- int err = 0;
-
- err = mmc_wait_for_cmd(host, cmd, 0);
- if (err)
- return err;
-
- if (mmc_host_is_spi(host)) {
- if (!(cmd->resp[0] & R1_SPI_IDLE)) {
- *busy = false;
- return 0;
- }
- } else {
- if (cmd->resp[0] & MMC_CARD_BUSY) {
- *busy = false;
- return 0;
- }
- }
-
- *busy = true;
-
- /*
- * According to eMMC specification v5.1 section 6.4.3, we
- * should issue CMD1 repeatedly in the idle state until
- * the eMMC is ready. Otherwise some eMMC devices seem to enter
- * the inactive mode after mmc_init_card() issued CMD0 when
- * the eMMC device is busy.
- */
- if (!ocr && !mmc_host_is_spi(host))
- cmd->arg = cmd->resp[0] | BIT(30);
-
- return 0;
-}
-
int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) {
struct mmc_command cmd = {};
+ unsigned int udelay = MMC_OP_COND_PERIOD_US;
+ unsigned int udelay_max = 10000;
+ unsigned long timeout = jiffies +
+msecs_to_jiffies(MMC_OP_COND_TIMEOUT_MS) + 1;
int err = 0;
- struct mmc_op_cond_busy_data cb_data = {
- .host = host,
- .ocr = ocr,
- .cmd = &cmd
- };

cmd.opcode = MMC_SEND_OP_COND;
cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;

- err = __mmc_poll_for_busy(host, MMC_OP_COND_PERIOD_US,
- MMC_OP_COND_TIMEOUT_MS,
- &__mmc_send_op_cond_cb, &cb_data);
- if (err)
- return err;
+ while (!time_after(jiffies, timeout)) {
+ err = mmc_wait_for_cmd(host, &cmd, 0);
+ if (err)
+ break;
+
+ if (mmc_host_is_spi(host)) {
+ if (!(cmd.resp[0] & R1_SPI_IDLE))
+ break;
+ } else {
+ if (cmd.resp[0] & MMC_CARD_BUSY)
+ break;
+ }
+
+ /*
+ * According to eMMC specification v5.1 section 6.4.3, we
+ * should issue CMD1 repeatedly in the idle state until
+ * the eMMC is ready. Otherwise some eMMC devices seem to enter
+ * the inactive mode after mmc_init_card() issued CMD0 when
+ * the eMMC device is busy.
+ */
+ if (!ocr && !mmc_host_is_spi(host))
+ cmd.arg = cmd.resp[0] | BIT(30);
+
+ usleep_range(udelay, udelay + 1000);
+
+ if (udelay < udelay_max)
+ udelay += 2000;
+ else
+ udelay = udelay_max;
+ }
+
+ if (time_after(jiffies, timeout))
+ err = -ETIMEDOUT;

if (rocr && !mmc_host_is_spi(host))
*rocr = cmd.resp[0];
--
2.34.1