Merge branch 'master' of git://git.denx.de/u-boot-usb
[oweals/u-boot.git] / drivers / mmc / tegra2_mmc.c
index 5b4c9f69a18fe34b7f0033ce8799225e60045ad4..fb8a57d162fcb2bf6ced82e1ac035f909a105895 100644 (file)
@@ -114,6 +114,14 @@ static void mmc_set_transfer_mode(struct mmc_host *host, struct mmc_data *data)
        if (data->flags & MMC_DATA_READ)
                mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
 
+       if (data->flags & MMC_DATA_WRITE) {
+               if ((uintptr_t)data->src & (ARCH_DMA_MINALIGN - 1))
+                       printf("Warning: unaligned write to %p may fail\n",
+                              data->src);
+               flush_dcache_range((ulong)data->src, (ulong)data->src +
+                       data->blocks * data->blocksize);
+       }
+
        writew(mode, &host->reg->trnmod);
 }
 
@@ -154,7 +162,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        struct mmc_host *host = (struct mmc_host *)mmc->priv;
        int flags, i;
        int result;
-       unsigned int mask;
+       unsigned int mask = 0;
        unsigned int retry = 0x100000;
        debug(" mmc_send_cmd called\n");
 
@@ -219,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;
        }
 
@@ -257,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;
                        }
 
@@ -310,6 +322,14 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                        }
                }
                writel(mask, &host->reg->norintsts);
+               if (data->flags & MMC_DATA_READ) {
+                       if ((uintptr_t)data->dest & (ARCH_DMA_MINALIGN - 1))
+                               printf("Warning: unaligned read from %p "
+                                       "may fail\n", data->dest);
+                       invalidate_dcache_range((ulong)data->dest,
+                               (ulong)data->dest +
+                                       data->blocks * data->blocksize);
+               }
        }
 
        udelay(1000);