diff options
author | Cliff Brake <cbrake@bec-systems.com> | 2009-01-22 17:07:03 -0500 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2009-02-02 14:57:07 -0500 |
commit | b6018958a57f6621d6979c4384e42a3df636beed (patch) | |
tree | 84806c5f1b5839e66edcfc811927b137fda7a247 /drivers/mmc/host/pxamci.c | |
parent | e10a854c4602072c34c03380b99da0a3ee15682c (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.c | 16 |
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 | ||
186 | static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) | 194 | 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) | |||
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 | } |