Merge branch 'master' of git://git.denx.de/u-boot-mmc
* 'master' of git://git.denx.de/u-boot-mmc: mmc: make mmc_send_status() more reliable mmc: fix card busy polling Tegra: mmc: Fixed handling of interrupts in timeouts. omap_hsmmc: Wait for CMDI to be clear
This commit is contained in:
commit
2acca35ce4
@ -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]*/
|
||||
|
@ -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]*/
|
||||
|
@ -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]*/
|
||||
|
@ -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]*/
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user