
On Friday, March 11, 2011 01:18:15 PM Lei Wen wrote:
On Fri, Mar 11, 2011 at 8:01 PM, Raffaele Recalcati
lamiaposta71@gmail.com wrote:
From: Raffaele Recalcati raffaele.recalcati@bticino.it
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
drivers/mmc/mmc.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++-- include/mmc.h | 4 +++ 2 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6805b33..fc1792a 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -48,6 +48,40 @@ 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;
int status;
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; @@ -82,6 +116,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",
@@ -121,6 +156,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, 1000); } return blkcnt;
@@ -158,6 +196,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;
@@ -189,6 +228,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, 1000); } return blkcnt;
@@ -369,15 +411,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, 1000);
return ret;
}
int mmc_change_freq(struct mmc *mmc) @@ -610,6 +660,7 @@ int mmc_startup(struct mmc *mmc) u64 cmult, csize; struct mmc_cmd cmd; char ext_csd[512];
int timeout = 1000; /* Put the Card in Identify Mode */ cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
@@ -722,6 +773,9 @@ int mmc_startup(struct mmc *mmc) cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL);
/* Waiting for the ready status */
mmc_send_status(mmc, 1000);
if (err) return err;
diff --git a/include/mmc.h b/include/mmc.h index fcd0fd1..4ee8e1c 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -94,6 +94,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 */ -- 1.7.0.4
Works fine on Pantheon board. (armv5) Tested-by:Lei Wen leiwen@marvell.com
Hi,
have you tested this with cards operating in SPI mode ?
Best regards, Lei _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot