On Fri, Mar 11, 2011 at 8:01 PM, Raffaele Recalcati <lamiapost...@gmail.com> wrote: > From: Raffaele Recalcati <raffaele.recalc...@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.recalc...@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 <lei...@marvell.com> Best regards, Lei _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot