summaryrefslogtreecommitdiff
path: root/drivers/mmc/s5p_mmc.c
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2011-06-30 09:55:08 +0000
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2011-09-03 22:40:47 +0200
commit9070872bb343e07945bf3882c572da82901c637d (patch)
tree35a777748213c0f01eecac00b6b5a4d809d4df50 /drivers/mmc/s5p_mmc.c
parent34d34b88b6b3d947de86dae81574bdde85b8d01e (diff)
downloadu-boot-imx-9070872bb343e07945bf3882c572da82901c637d.zip
u-boot-imx-9070872bb343e07945bf3882c572da82901c637d.tar.gz
u-boot-imx-9070872bb343e07945bf3882c572da82901c637d.tar.bz2
mmc: S5P: 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> Signed-off-by: Minkyu Kang <mk7.kang@samsung.com> Tested-by : Jaehoon Chung <jh80.chung@samsung.com> Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Diffstat (limited to 'drivers/mmc/s5p_mmc.c')
-rw-r--r--drivers/mmc/s5p_mmc.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/mmc/s5p_mmc.c b/drivers/mmc/s5p_mmc.c
index f136813..7786ecf 100644
--- a/drivers/mmc/s5p_mmc.c
+++ b/drivers/mmc/s5p_mmc.c
@@ -232,9 +232,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");
@@ -425,12 +431,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);
/*