mmc_spi: generate R1b response for erase and stop transmission command
authorPragnesh Patel <pragnesh.patel@sifive.com>
Mon, 29 Jun 2020 09:47:29 +0000 (15:17 +0530)
committerPeng Fan <peng.fan@nxp.com>
Tue, 14 Jul 2020 08:19:47 +0000 (16:19 +0800)
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>
drivers/mmc/mmc_spi.c

index 96a4107..50fcd32 100644 (file)
@@ -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;