Message ID | 1299844874-7605-2-git-send-email-lamiaposta71@gmail.com |
---|---|
State | Accepted |
Delegated to: | Andy Fleming |
Headers | show |
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> Best regards, Lei
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
On Sat, Aug 6, 2011 at 8:07 PM, Marek Vasut <marek.vasut@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@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 ? > no... I just test with normal sd and emmc card... Best regards, Lei
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 */