Merge branch 'master' of git://git.denx.de/u-boot-mmc
authorWolfgang Denk <wd@denx.de>
Fri, 17 Feb 2012 22:54:46 +0000 (23:54 +0100)
committerWolfgang Denk <wd@denx.de>
Fri, 17 Feb 2012 22:54:46 +0000 (23:54 +0100)
* '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

arch/arm/include/asm/arch-am33xx/mmc_host_def.h
arch/arm/include/asm/arch-omap3/mmc_host_def.h
arch/arm/include/asm/arch-omap4/mmc_host_def.h
arch/arm/include/asm/arch-omap5/mmc_host_def.h
drivers/mmc/mmc.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/tegra2_mmc.c
include/mmc.h

index 5d7dd4b..943526b 100644 (file)
@@ -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]*/
index 2963679..f8c42c0 100644 (file)
@@ -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]*/
index 74439c9..ce1bce1 100644 (file)
@@ -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]*/
index 74439c9..ce1bce1 100644 (file)
@@ -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]*/
index 6db37b1..49c3349 100644 (file)
@@ -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;
 
index ef64e37..2400db2 100644 (file)
@@ -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;
                }
        }
index 3191557..33cc8fb 100644 (file)
@@ -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;
                        }
 
index 8744604..30c2375 100644 (file)
 #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 */