diff options
author | Anton Staaf <robotboy@chromium.org> | 2011-06-03 11:43:00 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2011-08-24 13:10:48 -0700 |
commit | be4b3a6a47f70cb778f3679e70bdd0efcf5548a1 (patch) | |
tree | 99bda8e3fcd1434e62478264a1dd99d81873c980 /drivers/mmc | |
parent | 7937ff9d81911b867394b64760a1233c8503b08c (diff) |
mmc: Tegra2: Support DMA restarts at buffer boundaries
Currently if a DMA buffer straddles a buffer alignment boundary
(512KiB) then the DMA engine will pause and generate a DMA
interrupt. Since the DMA interrupt is not enabled it will hang
the MMC driver.
This patch adds support for restarting the DMA transfer. The
SYSTEM_ADDRESS register contains the next address that would have
been read/written when a boundary is hit. So we can read that
and write it back. The write triggers the resumption of the
transfer.
BUG=None
TEST=Run "mmc part 0" and "ext2ls mmc 0:3" on Seaboard.
Signed-off-by: Anton Staaf <robotboy@chromium.org>
Change-Id: Iaa7c37dbeb46e8ae987c7eaf1dcb4dd810dd4160
Reviewed-on: http://gerrit.chromium.org/gerrit/2111
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/tegra2_mmc.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c index 980675c0fb7..3a07ad054af 100644 --- a/drivers/mmc/tegra2_mmc.c +++ b/drivers/mmc/tegra2_mmc.c @@ -257,9 +257,15 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, __func__, mask); return -1; } else if (mask & (1 << 3)) { - /* DMA Interrupt */ + /* + * DMA Interrupt, restart the transfer where + * it was interrupted. + */ + unsigned int address = readl(&host->reg->sysad); + debug("DMA end\n"); - break; + writel((1 << 3), &host->reg->norintsts); + writel(address, &host->reg->sysad); } else if (mask & (1 << 1)) { /* Transfer Complete */ debug("r/w is done\n"); @@ -432,12 +438,13 @@ 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 Interrupt Status Enable * [1] ENSTASTANSCMPLT : Transfre Complete Status Enable * [0] ENSTACMDCMPLT : Command Complete Status Enable - */ + */ mask = readl(&host->reg->norintstsen); mask &= ~(0xffff); - mask |= (1 << 5) | (1 << 4) | (1 << 1) | (1 << 0); + mask |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 1) | (1 << 0); writel(mask, &host->reg->norintstsen); /* |