diff options
-rw-r--r-- | arch/arm/include/asm/arch-am33xx/mmc_host_def.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap3/mmc_host_def.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap4/mmc_host_def.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap5/mmc_host_def.h | 2 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 34 | ||||
-rw-r--r-- | drivers/mmc/omap_hsmmc.c | 5 | ||||
-rw-r--r-- | drivers/mmc/tegra2_mmc.c | 4 | ||||
-rw-r--r-- | include/mmc.h | 2 |
8 files changed, 31 insertions, 22 deletions
diff --git a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h index 5d7dd4b..943526b 100644 --- a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h +++ b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h @@ -97,7 +97,7 @@ typedef struct hsmmc { #define INDEX_MASK (0x3f << 24) #define INDEX(i) (i << 24) #define DATI_MASK (0x1 << 1) -#define DATI_CMDDIS (0x1 << 1) +#define CMDI_MASK (0x1 << 0) #define DTW_1_BITMODE (0x0 << 1) #define DTW_4_BITMODE (0x1 << 1) #define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/ diff --git a/arch/arm/include/asm/arch-omap3/mmc_host_def.h b/arch/arm/include/asm/arch-omap3/mmc_host_def.h index 2963679..f8c42c0 100644 --- a/arch/arm/include/asm/arch-omap3/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap3/mmc_host_def.h @@ -129,7 +129,7 @@ struct hsmmc { #define INDEX_MASK (0x3f << 24) #define INDEX(i) (i << 24) #define DATI_MASK (0x1 << 1) -#define DATI_CMDDIS (0x1 << 1) +#define CMDI_MASK (0x1 << 0) #define DTW_1_BITMODE (0x0 << 1) #define DTW_4_BITMODE (0x1 << 1) #define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/ diff --git a/arch/arm/include/asm/arch-omap4/mmc_host_def.h b/arch/arm/include/asm/arch-omap4/mmc_host_def.h index 74439c9..ce1bce1 100644 --- a/arch/arm/include/asm/arch-omap4/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap4/mmc_host_def.h @@ -107,7 +107,7 @@ struct hsmmc { #define INDEX_MASK (0x3f << 24) #define INDEX(i) (i << 24) #define DATI_MASK (0x1 << 1) -#define DATI_CMDDIS (0x1 << 1) +#define CMDI_MASK (0x1 << 0) #define DTW_1_BITMODE (0x0 << 1) #define DTW_4_BITMODE (0x1 << 1) #define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/ diff --git a/arch/arm/include/asm/arch-omap5/mmc_host_def.h b/arch/arm/include/asm/arch-omap5/mmc_host_def.h index 74439c9..ce1bce1 100644 --- a/arch/arm/include/asm/arch-omap5/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap5/mmc_host_def.h @@ -107,7 +107,7 @@ struct hsmmc { #define INDEX_MASK (0x3f << 24) #define INDEX(i) (i << 24) #define DATI_MASK (0x1 << 1) -#define DATI_CMDDIS (0x1 << 1) +#define CMDI_MASK (0x1 << 0) #define DTW_1_BITMODE (0x0 << 1) #define DTW_4_BITMODE (0x1 << 1) #define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/ diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6db37b1..49c3349 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -108,7 +108,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) int mmc_send_status(struct mmc *mmc, int timeout) { struct mmc_cmd cmd; - int err; + int err, retries = 5; #ifdef CONFIG_MMC_TRACE int status; #endif @@ -121,17 +121,21 @@ int mmc_send_status(struct mmc *mmc, int timeout) do { err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) + if (!err) { + if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) && + (cmd.response[0] & MMC_STATUS_CURR_STATE) != + MMC_STATE_PRG) + break; + else if (cmd.response[0] & MMC_STATUS_MASK) { + printf("Status Error: 0x%08X\n", + cmd.response[0]); + return COMM_ERR; + } + } else if (--retries < 0) 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--); #ifdef CONFIG_MMC_TRACE @@ -305,11 +309,12 @@ 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, timeout); } + /* Waiting for the ready status */ + if (mmc_send_status(mmc, timeout)) + return 0; + return blkcnt; } @@ -341,7 +346,6 @@ 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; @@ -373,9 +377,6 @@ 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, timeout); } return blkcnt; @@ -610,7 +611,8 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) ret = mmc_send_cmd(mmc, &cmd, NULL); /* Waiting for the ready status */ - mmc_send_status(mmc, timeout); + if (!ret) + ret = mmc_send_status(mmc, timeout); return ret; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index ef64e37..2400db2 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -198,9 +198,10 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ulong start; start = get_timer(0); - while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) { + while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) { if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for cmddis!\n", __func__); + printf("%s: timedout waiting on cmd inhibit to clear\n", + __func__); return TIMEOUT; } } diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c index 3191557..33cc8fb 100644 --- a/drivers/mmc/tegra2_mmc.c +++ b/drivers/mmc/tegra2_mmc.c @@ -227,16 +227,19 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (i == retry) { printf("%s: waiting for status update\n", __func__); + writel(mask, &host->reg->norintsts); return TIMEOUT; } if (mask & TEGRA_MMC_NORINTSTS_CMD_TIMEOUT) { /* Timeout Error */ debug("timeout: %08x cmd %d\n", mask, cmd->cmdidx); + writel(mask, &host->reg->norintsts); return TIMEOUT; } else if (mask & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { /* Error Interrupt */ debug("error: %08x cmd %d\n", mask, cmd->cmdidx); + writel(mask, &host->reg->norintsts); return -1; } @@ -265,6 +268,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (i == retry) { printf("%s: card is still busy\n", __func__); + writel(mask, &host->reg->norintsts); return TIMEOUT; } diff --git a/include/mmc.h b/include/mmc.h index 8744604..30c2375 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -112,6 +112,8 @@ #define MMC_STATUS_CURR_STATE (0xf << 9) #define MMC_STATUS_ERROR (1 << 19) +#define MMC_STATE_PRG (7 << 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 */ |