mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 08:01:08 +00:00
Tegra2: mmc: 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. Signed-off-by: Anton Staaf <robotboy@chromium.org> Cc: Andy Fleming <afleming@gmail.com> Cc: Tom Warren <twarren@nvidia.com> Cc: Stephen Warren <swarren@nvidia.com> Cc: Albert Aribaud <albert.u.boot@aribaud.net>
This commit is contained in:
parent
8e42f0d62b
commit
5a762e2509
1 changed files with 11 additions and 2 deletions
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue