aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/pxamci.c
diff options
context:
space:
mode:
authorCliff Brake <cbrake@bec-systems.com>2009-01-22 17:07:03 -0500
committerPierre Ossman <drzeus@drzeus.cx>2009-02-02 14:57:07 -0500
commitb6018958a57f6621d6979c4384e42a3df636beed (patch)
tree84806c5f1b5839e66edcfc811927b137fda7a247 /drivers/mmc/host/pxamci.c
parente10a854c4602072c34c03380b99da0a3ee15682c (diff)
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>
Diffstat (limited to 'drivers/mmc/host/pxamci.c')
-rw-r--r--drivers/mmc/host/pxamci.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 3000422f4d81..9702ad3774cf 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)
180 else 180 else
181 DALGN &= ~(1 << host->dma); 181 DALGN &= ~(1 << host->dma);
182 DDADR(host->dma) = host->sg_dma; 182 DDADR(host->dma) = host->sg_dma;
183 DCSR(host->dma) = DCSR_RUN; 183
184 /*
185 * workaround for erratum #91:
186 * only start DMA now if we are doing a read,
187 * otherwise we wait until CMD/RESP has finished
188 * before starting DMA.
189 */
190 if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ)
191 DCSR(host->dma) = DCSR_RUN;
184} 192}
185 193
186static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) 194static 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)
267 pxamci_disable_irq(host, END_CMD_RES); 275 pxamci_disable_irq(host, END_CMD_RES);
268 if (host->data && !cmd->error) { 276 if (host->data && !cmd->error) {
269 pxamci_enable_irq(host, DATA_TRAN_DONE); 277 pxamci_enable_irq(host, DATA_TRAN_DONE);
278 /*
279 * workaround for erratum #91, if doing write
280 * enable DMA late
281 */
282 if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE)
283 DCSR(host->dma) = DCSR_RUN;
270 } else { 284 } else {
271 pxamci_finish_request(host, host->mrq); 285 pxamci_finish_request(host, host->mrq);
272 } 286 }