Skip to contentSkip to conversation

atmel_spi: Reduce memory bandwidth requirement

RFC PATCH New David Brownell 1 participant 1 message Nov 7, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 atmel_spi: Reduce memory bandwidth requirement

FYI -- this doesn't affect the issue noted (which happens on reads, seemingly due to a too-busy bus) but otherwise it seems like a reasonable notion and I've forwarded it to the driver's maintainer.

---------- Forwarded Message ----------

Subject: [RFC, PATCH] atmel_spi: Reduce memory bandwidth requirement
Date: Friday 02 November 2007
From: Marc Pignat <[email protected]>
To: linux-arm-kernel-xIg/[email protected]

Reduce memory bandwidth requirement for spi write-only transfer. This should fix fifo errors for write-only operations.

---

Hi all!

Hope this patch will fix 'fifo overrun with atmel_spi & JFFS2'.
As stated in the at91sam9260 and at91rm9200 datasheet, the OVRES error is only set for when received data aren't read in time.
So, for write-only spi transfer, there is no need to read the data, and no need to check this flag.

Tested on 2.6.23.1 + maxim.org.za patches on at91rm9200, but only on a write-only (display) device.

Regards

Marc

spi/atmel_spi.c renamed from spi/atmel_spi.c.orig +13 -9
@@ -150,11 +150,9 @@ static void atmel_spi_next_xfer(struct s
 	tx_dma = xfer->tx_dma + xfer->len - len;
 	rx_dma = xfer->rx_dma + xfer->len - len;
 
-	/* use scratch buffer only when rx or tx data is unspecified */
+	/* use scratch buffer only when tx data is unspecified */
 	if (!xfer->rx_buf) {
-		rx_dma = as->buffer_dma;
-		if (len > BUFFER_SIZE)
-			len = BUFFER_SIZE;
+		rx_dma = 0;
 	}
 	if (!xfer->tx_buf) {
 		tx_dma = as->buffer_dma;
@@ -188,16 +186,22 @@ static void atmel_spi_next_xfer(struct s
 	 */
 	spi_writel(as, TNCR, 0);
 	spi_writel(as, RNCR, 0);
-	spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES));
 
 	dev_dbg(&msg->spi->dev,
 		"  start xfer %p: len %u tx %p/%08x rx %p/%08x imr %03x\n",
 		xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
 		xfer->rx_buf, xfer->rx_dma, spi_readl(as, IMR));
 
-	spi_writel(as, TCR, len);
-	spi_writel(as, RCR, len);
-	spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));
+	if (xfer->rx_buf) {
+		spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES));
+		spi_writel(as, TCR, len);
+		spi_writel(as, RCR, len);
+		spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));
+	} else {
+		spi_writel(as, IER, SPI_BIT(ENDTX));
+		spi_writel(as, TCR, len);
+		spi_writel(as, PTCR, SPI_BIT(TXTEN));
+	}
 }
 
 static void atmel_spi_next_message(struct spi_master *master)
@@ -372,7 +376,7 @@ atmel_spi_interrupt(int irq, void *dev_i
 		spi_readl(as, SR);
 
 		atmel_spi_msg_done(master, as, msg, -EIO, 0);
-	} else if (pending & SPI_BIT(ENDRX)) {
+	} else if (pending & (SPI_BIT(ENDRX) | SPI_BIT(ENDTX))) {
 		ret = IRQ_HANDLED;
 
 		spi_writel(as, IDR, pending);

-------------------------------------------------------

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/