[U-Boot] [RFC 1/3][v4] mmc: checking status after commands with R1b response
Lei Wen
adrian.wenl at gmail.com
Sat Aug 6 14:18:29 CEST 2011
On Sat, Aug 6, 2011 at 8:07 PM, Marek Vasut <marek.vasut at 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
>>
>> <lamiaposta71 at gmail.com> wrote:
>> > From: Raffaele Recalcati <raffaele.recalcati at 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 at 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 at 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
More information about the U-Boot
mailing list