[PATCH v3 1/3] mmc: Fix MMC_CMD_STOP_TRANSMISSION response type and add comment

For MMC/eMMC, the MMC_CMD_STOP_TRANSMISSION response is R1 for read transfers and R1b for write transfers per JEDEC Standard No. 84-B51 Page 126 . The response is R1b unconditionally per Physical Layer Simplified Specification Version 9.00.
Correct the response type and add a comment about it.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org --- V2: New patch V3: Account for SD case --- Cc: "Ying-Chun Liu (PaulLiu)" paul.liu@linaro.org Cc: Hai Pham hai.pham.ud@renesas.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Loic Poulain loic.poulain@linaro.org Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org Cc: Takeshi Kihara takeshi.kihara.df@renesas.com --- drivers/mmc/mmc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 965bc8f0dba..38d85c71402 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -427,7 +427,16 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, if (blkcnt > 1) { cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_R1b; + /* + * JEDEC Standard No. 84-B51 Page 126 + * CMD12 STOP_TRANSMISSION R1/R1b[3] + * NOTE 3 R1 for read cases and R1b for write cases. + * + * Physical Layer Simplified Specification Version 9.00 + * 7.3.1.3 Detailed Command Description + * CMD12 R1b + */ + cmd.resp_type = IS_SD(mmc) ? MMC_RSP_R1b : MMC_RSP_R1; if (mmc_send_cmd(mmc, &cmd, NULL)) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) pr_err("mmc fail to send stop cmd\n");

From: Hai Pham hai.pham.ud@renesas.com
If a tuning command times out, the card could still be processing it, which will cause problems for recovery. The eMMC specification section 6.6 Data transfer mode (cont’d) claims that CMD12 can be used to stop CMD21: " The relationship between the various data transfer modes is summarized (see Figure 27): - All data read commands can be aborted any time by the stop command (CMD12). The data transfer will terminate and the Device will return to the Transfer State. The read commands are: ... send tuning block (CMD21) .... " Add a function that does that.
Based on Linux commit [1] and [2].
[1] e711f0309109 ("mmc: mmc: Introduce mmc_abort_tuning()") [2] 21adc2e45f4e ("mmc: Improve function name when aborting a tuning cmd")
Reviewed-by: Takeshi Kihara takeshi.kihara.df@renesas.com Reviewed-by: Marek Vasut marek.vasut+renesas@mailbox.org Signed-off-by: Hai Pham hai.pham.ud@renesas.com Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org [Marek: Update commit message, quote relevant part of the specification. Rename to mmc_send_stop_transmission(). Remove tuning opcode check, this is controller driver specific. Deduplicate part of mmc_read_blocks() using this function.] --- V2: Support both read and write transmission stop V3: Update on previous patch changes --- Cc: "Ying-Chun Liu (PaulLiu)" paul.liu@linaro.org Cc: Hai Pham hai.pham.ud@renesas.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Loic Poulain loic.poulain@linaro.org Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org Cc: Takeshi Kihara takeshi.kihara.df@renesas.com --- drivers/mmc/mmc.c | 34 +++++++++++++++++++++------------- include/mmc.h | 2 ++ 2 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 38d85c71402..31cfda28858 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -398,6 +398,26 @@ int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error) } #endif
+int mmc_send_stop_transmission(struct mmc *mmc, bool write) +{ + struct mmc_cmd cmd; + + cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; + cmd.cmdarg = 0; + /* + * JEDEC Standard No. 84-B51 Page 126 + * CMD12 STOP_TRANSMISSION R1/R1b[3] + * NOTE 3 R1 for read cases and R1b for write cases. + * + * Physical Layer Simplified Specification Version 9.00 + * 7.3.1.3 Detailed Command Description + * CMD12 R1b + */ + cmd.resp_type = (IS_SD(mmc) || write) ? MMC_RSP_R1b : MMC_RSP_R1; + + return mmc_send_cmd(mmc, &cmd, NULL); +} + static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, lbaint_t blkcnt) { @@ -425,19 +445,7 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, return 0;
if (blkcnt > 1) { - cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; - cmd.cmdarg = 0; - /* - * JEDEC Standard No. 84-B51 Page 126 - * CMD12 STOP_TRANSMISSION R1/R1b[3] - * NOTE 3 R1 for read cases and R1b for write cases. - * - * Physical Layer Simplified Specification Version 9.00 - * 7.3.1.3 Detailed Command Description - * CMD12 R1b - */ - cmd.resp_type = IS_SD(mmc) ? MMC_RSP_R1b : MMC_RSP_R1; - if (mmc_send_cmd(mmc, &cmd, NULL)) { + if (mmc_send_stop_transmission(mmc, false)) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) pr_err("mmc fail to send stop cmd\n"); #endif diff --git a/include/mmc.h b/include/mmc.h index b8fbff150de..1022db3ffa7 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -558,6 +558,8 @@ int mmc_deferred_probe(struct mmc *mmc); int mmc_reinit(struct mmc *mmc); int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt); int mmc_hs400_prepare_ddr(struct mmc *mmc); +int mmc_send_stop_transmission(struct mmc *mmc, bool write); + #else struct mmc_ops { int (*send_cmd)(struct mmc *mmc,

Subject: [PATCH v3 2/3] mmc: Introduce mmc_send_stop_transmission()
From: Hai Pham hai.pham.ud@renesas.com
If a tuning command times out, the card could still be processing it, which will cause problems for recovery. The eMMC specification section 6.6 Data transfer mode (cont’d) claims that CMD12 can be used to stop CMD21: " The relationship between the various data transfer modes is summarized (see Figure 27):
- All data read commands can be aborted any time by the stop command
(CMD12). The data transfer will terminate and the Device will return to the Transfer State. The read commands are: ... send tuning block (CMD21) .... " Add a function that does that.
Based on Linux commit [1] and [2].
[1] e711f0309109 ("mmc: mmc: Introduce mmc_abort_tuning()") [2] 21adc2e45f4e ("mmc: Improve function name when aborting a tuning cmd")
Reviewed-by: Takeshi Kihara takeshi.kihara.df@renesas.com Reviewed-by: Marek Vasut marek.vasut+renesas@mailbox.org Signed-off-by: Hai Pham hai.pham.ud@renesas.com Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org [Marek: Update commit message, quote relevant part of the specification. Rename to mmc_send_stop_transmission(). Remove tuning opcode check, this is controller driver specific. Deduplicate part of mmc_read_blocks() using this function.]
V2: Support both read and write transmission stop V3: Update on previous patch changes
Cc: "Ying-Chun Liu (PaulLiu)" paul.liu@linaro.org Cc: Hai Pham hai.pham.ud@renesas.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Loic Poulain loic.poulain@linaro.org Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org Cc: Takeshi Kihara takeshi.kihara.df@renesas.com
drivers/mmc/mmc.c | 34 +++++++++++++++++++++------------- include/mmc.h | 2 ++ 2 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 38d85c71402..31cfda28858 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -398,6 +398,26 @@ int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error) } #endif
+int mmc_send_stop_transmission(struct mmc *mmc, bool write) {
- struct mmc_cmd cmd;
- cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
- cmd.cmdarg = 0;
- /*
* JEDEC Standard No. 84-B51 Page 126
* CMD12 STOP_TRANSMISSION R1/R1b[3]
* NOTE 3 R1 for read cases and R1b for write cases.
*
* Physical Layer Simplified Specification Version 9.00
* 7.3.1.3 Detailed Command Description
* CMD12 R1b
*/
- cmd.resp_type = (IS_SD(mmc) || write) ? MMC_RSP_R1b :
MMC_RSP_R1;
- return mmc_send_cmd(mmc, &cmd, NULL);
+}
static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, lbaint_t blkcnt) { @@ -425,19 +445,7 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, return 0;
if (blkcnt > 1) {
cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
cmd.cmdarg = 0;
/*
* JEDEC Standard No. 84-B51 Page 126
* CMD12 STOP_TRANSMISSION R1/R1b[3]
* NOTE 3 R1 for read cases and R1b for write cases.
*
* Physical Layer Simplified Specification Version 9.00
* 7.3.1.3 Detailed Command Description
* CMD12 R1b
*/
cmd.resp_type = IS_SD(mmc) ? MMC_RSP_R1b :
MMC_RSP_R1;
if (mmc_send_cmd(mmc, &cmd, NULL)) {
if (mmc_send_stop_transmission(mmc, false)) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) pr_err("mmc fail to send stop cmd\n"); #endif diff -- git a/include/mmc.h b/include/mmc.h index b8fbff150de..1022db3ffa7 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -558,6 +558,8 @@ int mmc_deferred_probe(struct mmc *mmc); int mmc_reinit(struct mmc *mmc); int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt); int mmc_hs400_prepare_ddr(struct mmc *mmc); +int mmc_send_stop_transmission(struct mmc *mmc, bool write);
#else struct mmc_ops { int (*send_cmd)(struct mmc *mmc,
Reviewed-by: Peng Fan peng.fan@nxp.com
-- 2.39.2

From: Hai Pham hai.pham.ud@renesas.com
When tuning command (CMD21) fails with command error, call mmc_send_stop_transmission() to send stop command (CMD12).
Reviewed-by: Takeshi Kihara takeshi.kihara.df@renesas.com Reviewed-by: Marek Vasut marek.vasut+renesas@mailbox.org Signed-off-by: Hai Pham hai.pham.ud@renesas.com Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org [Marek: Add dev_dbg() message in case tuning abort fails Move tuning opcode check from mmc_abort_tuning()] --- V2: Update on previous patch changes V3: Update on previous patch changes --- Cc: "Ying-Chun Liu (PaulLiu)" paul.liu@linaro.org Cc: Hai Pham hai.pham.ud@renesas.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Loic Poulain loic.poulain@linaro.org Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org Cc: Takeshi Kihara takeshi.kihara.df@renesas.com --- drivers/mmc/renesas-sdhi.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 280d96dbc2d..8e716f74491 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -611,6 +611,17 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) priv->smpcmp |= BIT(i);
mdelay(1); + + /* + * eMMC specification specifies that CMD12 can be used to stop a tuning + * command, but SD specification does not, so do nothing unless it is + * eMMC. + */ + if (ret && (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200)) { + ret = mmc_send_stop_transmission(mmc, false); + if (ret < 0) + dev_dbg(dev, "Tuning abort fail (%d)\n", ret); + } }
ret = renesas_sdhi_select_tuning(priv, taps);

Subject: [PATCH v3 3/3] mmc: renesas-sdhi: Send stop when MMC tuning command fails
From: Hai Pham hai.pham.ud@renesas.com
When tuning command (CMD21) fails with command error, call mmc_send_stop_transmission() to send stop command (CMD12).
Reviewed-by: Takeshi Kihara takeshi.kihara.df@renesas.com Reviewed-by: Marek Vasut marek.vasut+renesas@mailbox.org Signed-off-by: Hai Pham hai.pham.ud@renesas.com Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org [Marek: Add dev_dbg() message in case tuning abort fails Move tuning opcode check from mmc_abort_tuning()]
V2: Update on previous patch changes V3: Update on previous patch changes
Cc: "Ying-Chun Liu (PaulLiu)" paul.liu@linaro.org Cc: Hai Pham hai.pham.ud@renesas.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Loic Poulain loic.poulain@linaro.org Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org Cc: Takeshi Kihara takeshi.kihara.df@renesas.com
drivers/mmc/renesas-sdhi.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 280d96dbc2d..8e716f74491 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -611,6 +611,17 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) priv->smpcmp |= BIT(i);
mdelay(1);
/*
* eMMC specification specifies that CMD12 can be used to
stop a tuning
* command, but SD specification does not, so do nothing
unless it is
* eMMC.
*/
if (ret && (opcode ==
MMC_CMD_SEND_TUNING_BLOCK_HS200)) {
ret = mmc_send_stop_transmission(mmc, false);
if (ret < 0)
dev_dbg(dev, "Tuning abort fail (%d)\n",
ret);
}
}
ret = renesas_sdhi_select_tuning(priv, taps);
Reviewed-by: Peng Fan peng.fan@nxp.com
-- 2.39.2

-----Original Message----- From: Marek Vasut marek.vasut+renesas@mailbox.org Sent: 2023年6月20日 6:38 To: u-boot@lists.denx.de Cc: Marek Vasut marek.vasut+renesas@mailbox.org; Ying-Chun Liu (PaulLiu) paul.liu@linaro.org; Hai Pham hai.pham.ud@renesas.com; Jaehoon Chung jh80.chung@samsung.com; Loic Poulain loic.poulain@linaro.org; Peng Fan peng.fan@nxp.com; Simon Glass sjg@chromium.org; Takeshi Kihara takeshi.kihara.df@renesas.com Subject: [PATCH v3 1/3] mmc: Fix MMC_CMD_STOP_TRANSMISSION response type and add comment
For MMC/eMMC, the MMC_CMD_STOP_TRANSMISSION response is R1 for read transfers and R1b for write transfers per JEDEC Standard No. 84-B51 Page 126 . The response is R1b unconditionally per Physical Layer Simplified Specification Version 9.00.
Correct the response type and add a comment about it.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org
V2: New patch V3: Account for SD case
Cc: "Ying-Chun Liu (PaulLiu)" paul.liu@linaro.org Cc: Hai Pham hai.pham.ud@renesas.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Loic Poulain loic.poulain@linaro.org Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org Cc: Takeshi Kihara takeshi.kihara.df@renesas.com
drivers/mmc/mmc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 965bc8f0dba..38d85c71402 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -427,7 +427,16 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, if (blkcnt > 1) { cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0;
cmd.resp_type = MMC_RSP_R1b;
/*
* JEDEC Standard No. 84-B51 Page 126
* CMD12 STOP_TRANSMISSION R1/R1b[3]
* NOTE 3 R1 for read cases and R1b for write cases.
*
* Physical Layer Simplified Specification Version 9.00
* 7.3.1.3 Detailed Command Description
* CMD12 R1b
*/
cmd.resp_type = IS_SD(mmc) ? MMC_RSP_R1b :
MMC_RSP_R1; if (mmc_send_cmd(mmc, &cmd, NULL)) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) pr_err("mmc fail to send stop cmd\n");
Reviewed-by: Peng Fan peng.fan@nxp.com
-- 2.39.2
participants (2)
-
Marek Vasut
-
Peng Fan