aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPragnesh Patel <pragnesh.patel@sifive.com>2020-06-29 15:17:29 +0530
committerPeng Fan <peng.fan@nxp.com>2020-07-14 16:19:47 +0800
commited4a11cb7d19a26dd0625bc468ef930c035a71b2 (patch)
treea250f992f4037e82d3648b7d773fa9a4062657f8 /drivers
parent6f4555af8471491d7f8c01187a97f2b0fcedc286 (diff)
downloadu-boot-ed4a11cb7d19a26dd0625bc468ef930c035a71b2.zip
u-boot-ed4a11cb7d19a26dd0625bc468ef930c035a71b2.tar.gz
u-boot-ed4a11cb7d19a26dd0625bc468ef930c035a71b2.tar.bz2
mmc_spi: generate R1b response for erase and stop transmission command
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@sifive.com> Reviewed-by: Bin Meng <bin.meng@windriver.com> Tested-by: Bin Meng <bin.meng@windriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/mmc_spi.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
index 96a4107..50fcd32 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;