diff options
author | Tom Rini <trini@konsulko.com> | 2020-07-15 22:41:43 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-07-15 22:41:43 -0400 |
commit | 3b33eff3f263e6ccadf505e67d450970cc1c8e6c (patch) | |
tree | f1e3b9a68f43062bdccc56376a22f7b92ba23a0c | |
parent | 47b0a493247b38c1557062e108cc4868e211a73e (diff) | |
parent | ed4a11cb7d19a26dd0625bc468ef930c035a71b2 (diff) |
Merge tag 'mmc-7-24-2020' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
- Correct mmc_spi check condition
- Generate R1/R2/R1b response
- Read SSR for SD SPI
-rw-r--r-- | drivers/mmc/mmc.c | 5 | ||||
-rw-r--r-- | drivers/mmc/mmc_spi.c | 52 |
2 files changed, 49 insertions, 8 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 50f47d4ba2..7b5c55be7d 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1753,6 +1753,11 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps) mmc_set_bus_width(mmc, 1); mmc_select_mode(mmc, MMC_LEGACY); mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE); +#if CONFIG_IS_ENABLED(MMC_WRITE) + err = sd_read_ssr(mmc); + if (err) + pr_warn("unable to read ssr\n"); +#endif return 0; } diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index e76ab54838..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; @@ -105,12 +106,14 @@ static int mmc_spi_sendcmd(struct udevice *dev, if (resp_match) { r = ~resp_match_value; i = CMD_TIMEOUT; - while (i--) { + 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 == resp_match_value) break; } @@ -131,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; @@ -263,8 +284,8 @@ 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; - u8 resp8 = 0, resp40[5] = { 0 }, resp_match_value = 0; + bool resp_match = false, r1b = false; + u8 resp8 = 0, resp16[2] = { 0 }, resp40[5] = { 0 }, resp_match_value = 0; dm_spi_claim_bus(dev); @@ -289,20 +310,33 @@ static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd, resp_size = sizeof(resp40); break; case MMC_CMD_SEND_STATUS: + resp = (u8 *)&resp16[0]; + resp_size = sizeof(resp16); + 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: case MMC_CMD_READ_MULTIPLE_BLOCK: case MMC_CMD_WRITE_SINGLE_BLOCK: case MMC_CMD_WRITE_MULTIPLE_BLOCK: + case MMC_CMD_APP_CMD: + case SD_CMD_ERASE_WR_BLK_START: + case SD_CMD_ERASE_WR_BLK_END: + resp = &resp8; + resp_size = sizeof(resp8); break; default: resp = &resp8; @@ -313,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; @@ -330,8 +364,10 @@ static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd, cmd->response[0] |= (uint)resp40[1] << 24; break; case MMC_CMD_SEND_STATUS: - cmd->response[0] = (resp8 & 0xff) ? - MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA; + if (resp16[0] || resp16[1]) + cmd->response[0] = MMC_STATUS_ERROR; + else + cmd->response[0] = MMC_STATUS_RDY_FOR_DATA; break; case MMC_CMD_SEND_CID: case MMC_CMD_SEND_CSD: |