]> pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
pxamci: enable DMA for write ops after CMD/RESP
authorCliff Brake <cbrake@bec-systems.com>
Thu, 22 Jan 2009 22:07:03 +0000 (17:07 -0500)
committerPierre Ossman <drzeus@drzeus.cx>
Mon, 2 Feb 2009 19:57:07 +0000 (20:57 +0100)
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

index 3000422f4d8119ec363fd1eafefa34bd9f6573d1..9702ad3774cf90ae1065d2d8d2a8e271c240aaae 100644 (file)
@@ -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);
        }