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 <robot...@chromium.org> Cc: Andy Fleming <aflem...@gmail.com> Cc: Tom Warren <twar...@nvidia.com> Cc: Stephen Warren <swar...@nvidia.com> Cc: Albert Aribaud <albert.u.b...@aribaud.net> --- drivers/mmc/tegra2_mmc.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c index 2e7746d..73f6405 100644 --- a/drivers/mmc/tegra2_mmc.c +++ b/drivers/mmc/tegra2_mmc.c @@ -240,9 +240,16 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, __func__, mask); return -1; } else if (mask & TEGRA2_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(TEGRA2_MMC_NORINTSTS_DMA_INTERRUPT, + &host->reg->norintsts); + writel(address, &host->reg->sysad); } else if (mask & TEGRA2_MMC_NORINTSTS_XFER_COMPLETE) { /* Transfer Complete */ debug("r/w is done\n"); @@ -380,6 +387,7 @@ static int mmc_core_init(struct mmc *mmc) mask |= (1 << 5) | (1 << 4) | (1 << 1) | (1 << 0); mask |= (TEGRA2_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA2_MMC_NORINTSTSEN_XFER_COMPLETE | + TEGRA2_MMC_NORINTSTSEN_DMA_INTERRUPT | TEGRA2_MMC_NORINTSTSEN_BUFFER_WRITE_READY | TEGRA2_MMC_NORINTSTSEN_BUFFER_READ_READY); writel(mask, &host->reg->norintstsen); -- 1.7.3.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot