[PATCH 6/6] mmc_spi: generate R1b response for erase and stop transmission command
Pragnesh Patel
pragnesh.patel at sifive.com
Mon Jun 29 11:47:29 CEST 2020
As per the SD physical layer specification version 7.10, erase
command (CMD38) and stop transmission command (CMD12) will generate
R1b response.
R1b = R1 + busy signal
A non-zero value after the R1 response indicates card is ready for
next command.
Signed-off-by: Pragnesh Patel <pragnesh.patel at sifive.com>
---
drivers/mmc/mmc_spi.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
index 96a41076dc..50fcd32674 100644
--- a/drivers/mmc/mmc_spi.c
+++ b/drivers/mmc/mmc_spi.c
@@ -59,6 +59,7 @@
#define CMD_TIMEOUT 8
#define READ_TIMEOUT 3000000 /* 1 sec */
#define WRITE_TIMEOUT 3000000 /* 1 sec */
+#define R1B_TIMEOUT 3000000 /* 1 sec */
struct mmc_spi_plat {
struct mmc_config cfg;
@@ -72,7 +73,7 @@ struct mmc_spi_priv {
static int mmc_spi_sendcmd(struct udevice *dev,
ushort cmdidx, u32 cmdarg, u32 resp_type,
u8 *resp, u32 resp_size,
- bool resp_match, u8 resp_match_value)
+ bool resp_match, u8 resp_match_value, bool r1b)
{
int i, rpos = 0, ret = 0;
u8 cmdo[7], r;
@@ -133,6 +134,24 @@ static int mmc_spi_sendcmd(struct udevice *dev,
resp[i] = r;
}
+ if (r1b == true) {
+ i = R1B_TIMEOUT;
+ while (i) {
+ ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
+ if (ret)
+ return ret;
+
+ debug(" resp%d=0x%x", rpos, r);
+ rpos++;
+ i--;
+
+ if (r)
+ break;
+ }
+ if (!i)
+ return -ETIMEDOUT;
+ }
+
debug("\n");
return 0;
@@ -265,7 +284,7 @@ static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd,
int i, multi, ret = 0;
u8 *resp = NULL;
u32 resp_size = 0;
- bool resp_match = false;
+ bool resp_match = false, r1b = false;
u8 resp8 = 0, resp16[2] = { 0 }, resp40[5] = { 0 }, resp_match_value = 0;
dm_spi_claim_bus(dev);
@@ -296,12 +315,17 @@ static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd,
break;
case MMC_CMD_SET_BLOCKLEN:
case MMC_CMD_SPI_CRC_ON_OFF:
- case MMC_CMD_STOP_TRANSMISSION:
resp = &resp8;
resp_size = sizeof(resp8);
resp_match = true;
resp_match_value = 0x0;
break;
+ case MMC_CMD_STOP_TRANSMISSION:
+ case MMC_CMD_ERASE:
+ resp = &resp8;
+ resp_size = sizeof(resp8);
+ r1b = true;
+ break;
case MMC_CMD_SEND_CSD:
case MMC_CMD_SEND_CID:
case MMC_CMD_READ_SINGLE_BLOCK:
@@ -323,7 +347,7 @@ static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd,
};
ret = mmc_spi_sendcmd(dev, cmd->cmdidx, cmd->cmdarg, cmd->resp_type,
- resp, resp_size, resp_match, resp_match_value);
+ resp, resp_size, resp_match, resp_match_value, r1b);
if (ret)
goto done;
--
2.17.1
More information about the U-Boot
mailing list