From b6018958a57f6621d6979c4384e42a3df636beed Mon Sep 17 00:00:00 2001
From: Cliff Brake <cbrake@bec-systems.com>
Date: Thu, 22 Jan 2009 17:07:03 -0500
Subject: [PATCH] pxamci: enable DMA for write ops after CMD/RESP

With the PXA270 MMC hardware, there seems to be an issue of
data corruption on writes where a 4KB data block is offset
by one byte.

If we delay enabling the DMA for writes until after the CMD/RESP
has finished, the problem seems to be fixed.

related to PXA270 Erratum #91

Tested-by: Vernon Sauder <VernonInHand@gmail.com>
Signed-off-by: Cliff Brake <cbrake@bec-systems.com>
Acked-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
---
 drivers/mmc/host/pxamci.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 3000422f4d811..9702ad3774cf9 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -180,7 +180,15 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
 	else
 		DALGN &= ~(1 << host->dma);
 	DDADR(host->dma) = host->sg_dma;
-	DCSR(host->dma) = DCSR_RUN;
+
+	/*
+	 * workaround for erratum #91:
+	 * only start DMA now if we are doing a read,
+	 * otherwise we wait until CMD/RESP has finished
+	 * before starting DMA.
+	 */
+	if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ)
+		DCSR(host->dma) = DCSR_RUN;
 }
 
 static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat)
@@ -267,6 +275,12 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
 	pxamci_disable_irq(host, END_CMD_RES);
 	if (host->data && !cmd->error) {
 		pxamci_enable_irq(host, DATA_TRAN_DONE);
+		/*
+		 * workaround for erratum #91, if doing write
+		 * enable DMA late
+		 */
+		if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE)
+			DCSR(host->dma) = DCSR_RUN;
 	} else {
 		pxamci_finish_request(host, host->mrq);
 	}
-- 
GitLab