On Sat, Aug 6, 2011 at 8:07 PM, Marek Vasut <marek.va...@gmail.com> wrote: > On Friday, March 11, 2011 01:18:15 PM Lei Wen wrote: >> 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> > > Hi, > > have you tested this with cards operating in SPI mode ? >
no... I just test with normal sd and emmc card... Best regards, Lei _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot