Tegra2: mmc: Support DMA restarts at buffer boundaries
[platform/kernel/u-boot.git] / drivers / mmc / tegra2_mmc.c
index 2bea07d..159cef1 100644 (file)
@@ -270,9 +270,16 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                                                __func__, mask);
                                return -1;
                        } else if (mask & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT) {
-                               /* DMA Interrupt */
+                               /*
+                                * DMA Interrupt, restart the transfer where
+                                * it was interrupted.
+                                */
+                               unsigned int address = readl(&host->reg->sysad);
+
                                debug("DMA end\n");
-                               break;
+                               writel(TEGRA_MMC_NORINTSTS_DMA_INTERRUPT,
+                                      &host->reg->norintsts);
+                               writel(address, &host->reg->sysad);
                        } else if (mask & TEGRA_MMC_NORINTSTS_XFER_COMPLETE) {
                                /* Transfer Complete */
                                debug("r/w is done\n");
@@ -419,6 +426,7 @@ static int mmc_core_init(struct mmc *mmc)
         * NORMAL Interrupt Status Enable Register init
         * [5] ENSTABUFRDRDY : Buffer Read Ready Status Enable
         * [4] ENSTABUFWTRDY : Buffer write Ready Status Enable
+        * [3] ENSTADMAINT   : DMA boundary interrupt
         * [1] ENSTASTANSCMPLT : Transfre Complete Status Enable
         * [0] ENSTACMDCMPLT : Command Complete Status Enable
        */
@@ -426,6 +434,7 @@ static int mmc_core_init(struct mmc *mmc)
        mask &= ~(0xffff);
        mask |= (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE |
                 TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE |
+                TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT |
                 TEGRA_MMC_NORINTSTSEN_BUFFER_WRITE_READY |
                 TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY);
        writel(mask, &host->reg->norintstsen);