- Correct mmc_spi check condition
- Generate R1/R2/R1b response
- Read SSR for SD SPI
This commit is contained in:
Tom Rini 2020-07-15 22:41:43 -04:00
commit 3b33eff3f2
2 changed files with 49 additions and 8 deletions

View file

@ -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;
}

View 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;
@ -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: