[PATCH] pxamci: fix byte aligned DMA transfers

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Pierre Ossman
Date: Saturday, July 5, 2008 - 4:15 pm

From: Philipp Zabel <philipp.zabel@gmail.com>

The pxa27x DMA controller defaults to 64-bit alignment. This caused
the SCR reads to fail (and, depending on card type, error out) when
card->raw_scr was not aligned on a 8-byte boundary.

For performance reasons all scatter-gather addresses passed to
pxamci_request should be aligned on 8-byte boundaries, but if
this can't be guaranteed, byte aligned DMA transfers in the
have to be enabled in the controller to get correct behaviour.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
---
 drivers/mmc/host/pxamci.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 65210fc..d89475d 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 =3D data->blocks;
 	unsigned long long clks;
 	unsigned int timeout;
+	bool dalgn =3D 0;
 	u32 dcmd;
 	int i;
=20
@@ -152,6 +153,9 @@ static void pxamci_setup_data(struct pxamci_host *host,=
 struct mmc_data *data)
 		host->sg_cpu[i].dcmd =3D dcmd | length;
 		if (length & 31 && !(data->flags & MMC_DATA_READ))
 			host->sg_cpu[i].dcmd |=3D DCMD_ENDIRQEN;
+		/* Not aligned to 8-byte boundary? */
+		if (sg_dma_address(&data->sg[i]) & 0x7)
+			dalgn =3D 1;
 		if (data->flags & MMC_DATA_READ) {
 			host->sg_cpu[i].dsadr =3D host->res->start + MMC_RXFIFO;
 			host->sg_cpu[i].dtadr =3D 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 =3D DDADR_STOP;
 	wmb();
=20
+	/*
+	 * 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 |=3D (1 << host->dma);
+	else
+		DALGN &=3D (1 << host->dma);
 	DDADR(host->dma) =3D host->sg_dma;
 	DCSR(host->dma) =3D DCSR_RUN;
 }


--=20
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  rdesktop, core developer          http://www.rdesktop.org

  WARNING: This correspondence is being monitored by the
  Swedish government. Make sure your server uses encryption
  for SMTP traffic and consider using PGP for end-to-end
  encryption.
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH] pxamci: fix byte aligned DMA transfers, Pierre Ossman, (Sat Jul 5, 4:15 pm)