[U-Boot] [RFC 1/3][v4] mmc: checking status after commands with R1b response
Lei Wen
adrian.wenl at gmail.com
Fri Mar 11 13:18:15 CET 2011
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>
Best regards,
Lei
More information about the U-Boot
mailing list