mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-25 13:14:19 +08:00
mmc: checking status after commands with R1b response
It is recommended to check card status after these kind of commands. This is done using CMD13 (SEND_STATUS) JEDEC command until the card is ready. In case of error the card status field is displayed. Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it> Signed-off-by: Andy Fleming <afleming@freescale.com>
This commit is contained in:
parent
8baf939c2c
commit
5d4fc8d907
@ -52,6 +52,42 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||
return mmc->send_cmd(mmc, cmd, data);
|
||||
}
|
||||
|
||||
int mmc_send_status(struct mmc *mmc, int timeout)
|
||||
{
|
||||
struct mmc_cmd cmd;
|
||||
int err;
|
||||
#ifdef CONFIG_MMC_TRACE
|
||||
int status;
|
||||
#endif
|
||||
|
||||
cmd.cmdidx = MMC_CMD_SEND_STATUS;
|
||||
cmd.resp_type = MMC_RSP_R1;
|
||||
cmd.cmdarg = 0;
|
||||
cmd.flags = 0;
|
||||
|
||||
do {
|
||||
err = mmc_send_cmd(mmc, &cmd, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
|
||||
break;
|
||||
|
||||
udelay(1000);
|
||||
|
||||
if (cmd.response[0] & MMC_STATUS_MASK) {
|
||||
printf("Status Error: 0x%08X\n", cmd.response[0]);
|
||||
return COMM_ERR;
|
||||
}
|
||||
} while (timeout--);
|
||||
|
||||
if (!timeout) {
|
||||
printf("Timeout waiting card ready\n");
|
||||
return TIMEOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mmc_set_blocklen(struct mmc *mmc, int len)
|
||||
{
|
||||
struct mmc_cmd cmd;
|
||||
@ -86,6 +122,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
|
||||
{
|
||||
struct mmc_cmd cmd;
|
||||
struct mmc_data data;
|
||||
int timeout = 1000;
|
||||
|
||||
if ((start + blkcnt) > mmc->block_dev.lba) {
|
||||
printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
|
||||
@ -128,6 +165,9 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
|
||||
printf("mmc fail to send stop cmd\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Waiting for the ready status */
|
||||
mmc_send_status(mmc, timeout);
|
||||
}
|
||||
|
||||
return blkcnt;
|
||||
@ -162,6 +202,7 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
|
||||
{
|
||||
struct mmc_cmd cmd;
|
||||
struct mmc_data data;
|
||||
int timeout = 1000;
|
||||
|
||||
if (blkcnt > 1)
|
||||
cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
|
||||
@ -193,6 +234,9 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
|
||||
printf("mmc fail to send stop cmd\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Waiting for the ready status */
|
||||
mmc_send_status(mmc, timeout);
|
||||
}
|
||||
|
||||
return blkcnt;
|
||||
@ -396,15 +440,23 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
|
||||
int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
|
||||
{
|
||||
struct mmc_cmd cmd;
|
||||
int timeout = 1000;
|
||||
int ret;
|
||||
|
||||
cmd.cmdidx = MMC_CMD_SWITCH;
|
||||
cmd.resp_type = MMC_RSP_R1b;
|
||||
cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
|
||||
(index << 16) |
|
||||
(value << 8);
|
||||
(index << 16) |
|
||||
(value << 8);
|
||||
cmd.flags = 0;
|
||||
|
||||
return mmc_send_cmd(mmc, &cmd, NULL);
|
||||
ret = mmc_send_cmd(mmc, &cmd, NULL);
|
||||
|
||||
/* Waiting for the ready status */
|
||||
mmc_send_status(mmc, timeout);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int mmc_change_freq(struct mmc *mmc)
|
||||
@ -643,6 +695,7 @@ int mmc_startup(struct mmc *mmc)
|
||||
u64 cmult, csize;
|
||||
struct mmc_cmd cmd;
|
||||
char ext_csd[512];
|
||||
int timeout = 1000;
|
||||
|
||||
#ifdef CONFIG_MMC_SPI_CRC_ON
|
||||
if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
|
||||
@ -699,6 +752,9 @@ int mmc_startup(struct mmc *mmc)
|
||||
|
||||
err = mmc_send_cmd(mmc, &cmd, NULL);
|
||||
|
||||
/* Waiting for the ready status */
|
||||
mmc_send_status(mmc, timeout);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -97,6 +97,10 @@
|
||||
#define OCR_BUSY 0x80000000
|
||||
#define OCR_HCS 0x40000000
|
||||
|
||||
#define MMC_STATUS_MASK (~0x0206BF7F)
|
||||
#define MMC_STATUS_RDY_FOR_DATA (1<<8)
|
||||
#define MMC_STATUS_CURR_STATE (0xf<<9)
|
||||
|
||||
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
|
||||
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
|
||||
#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
|
||||
|
Loading…
Reference in New Issue
Block a user