
On Thu, Oct 13, 2011 at 2:57 PM, Anton Staaf robotboy@chromium.org wrote:
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.
Signed-off-by: Anton Staaf robotboy@chromium.org Cc: Tom Warren twarren@nvidia.com Cc: Stephen Warren swarren@nvidia.com
Adding Albert to CC.
-Anton
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 8b6f829..195f89d 100644 --- a/drivers/mmc/tegra2_mmc.c +++ b/drivers/mmc/tegra2_mmc.c @@ -256,9 +256,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"); @@ -442,12 +448,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);
/*
1.7.3.1