aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/pxamci.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-07-11 21:57:40 +1000
committerNeil Brown <neilb@suse.de>2008-07-11 21:57:40 +1000
commit0306d5efbf897c7d410fd30b89fc7d97372aa501 (patch)
tree668811bca39ca7c1585da88d52ec2f0a43216c0e /drivers/mmc/host/pxamci.c
parentMerge branch 'for-2.6.26' into for-next (diff)
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 (diff)
downloadlinux-dev-0306d5efbf897c7d410fd30b89fc7d97372aa501.tar.xz
linux-dev-0306d5efbf897c7d410fd30b89fc7d97372aa501.zip
Merge branch 'master' into for-next
Diffstat (limited to 'drivers/mmc/host/pxamci.c')
-rw-r--r--drivers/mmc/host/pxamci.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 65210fca37ed..d89475d36988 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -114,6 +114,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
unsigned int nob = data->blocks;
unsigned long long clks;
unsigned int timeout;
+ bool dalgn = 0;
u32 dcmd;
int i;
@@ -152,6 +153,9 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
host->sg_cpu[i].dcmd = dcmd | length;
if (length & 31 && !(data->flags & MMC_DATA_READ))
host->sg_cpu[i].dcmd |= DCMD_ENDIRQEN;
+ /* Not aligned to 8-byte boundary? */
+ if (sg_dma_address(&data->sg[i]) & 0x7)
+ dalgn = 1;
if (data->flags & MMC_DATA_READ) {
host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO;
host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]);
@@ -165,6 +169,15 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
host->sg_cpu[host->dma_len - 1].ddadr = DDADR_STOP;
wmb();
+ /*
+ * The PXA27x DMA controller encounters overhead when working with
+ * unaligned (to 8-byte boundaries) data, so switch on byte alignment
+ * mode only if we have unaligned data.
+ */
+ if (dalgn)
+ DALGN |= (1 << host->dma);
+ else
+ DALGN &= (1 << host->dma);
DDADR(host->dma) = host->sg_dma;
DCSR(host->dma) = DCSR_RUN;
}