r4678 - developers/werner/wlan-spi/patches

werner at docs.openmoko.org werner at docs.openmoko.org
Sun Sep 28 04:12:37 CEST 2008


Author: werner
Date: 2008-09-28 04:12:36 +0200 (Sun, 28 Sep 2008)
New Revision: 4678

Added:
   developers/werner/wlan-spi/patches/s3c-spi-fix-int-mode.patch
   developers/werner/wlan-spi/patches/s3c-spi-from-int-to-poll.patch
Removed:
   developers/werner/wlan-spi/patches/tweak-spi.patch
Modified:
   developers/werner/wlan-spi/patches/series
Log:
- renamed tweak-spi.patch to s3c-spi-fix-int-mode.patch
- s3c-spi-from-int-to-poll.patch: use poll mode instead of interrupt mode, for
  a nice speedup



Copied: developers/werner/wlan-spi/patches/s3c-spi-fix-int-mode.patch (from rev 4676, developers/werner/wlan-spi/patches/tweak-spi.patch)
===================================================================
--- developers/werner/wlan-spi/patches/s3c-spi-fix-int-mode.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches/s3c-spi-fix-int-mode.patch	2008-09-28 02:12:36 UTC (rev 4678)
@@ -0,0 +1,76 @@
+Work in progress. Makes spi_s3c24xx.c work for up to 12MHz.
+
+At speeds of 13MHz or higher, we have setup time issues. I.e., the
+SPI host sees the data coming from the device delayed by one bit,
+even though things look fine on the scope.
+
+This 12MHz/13MHz "barrier" exists with or without probes attached,
+suggesting capacitative loading plays only a minor role in this.
+
+Index: korig/drivers/spi/spi_s3c24xx.c
+===================================================================
+--- korig.orig/drivers/spi/spi_s3c24xx.c	2008-09-27 21:32:30.000000000 -0300
++++ korig/drivers/spi/spi_s3c24xx.c	2008-09-27 22:27:20.000000000 -0300
+@@ -198,6 +198,27 @@
+ 	writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
+ 	wait_for_completion(&hw->done);
+ 
++	/*
++	 * Get the last byte. Since we don't have more data we can send in
++	 * order to clock the byte out of the SPI system, we need to wait.
++	 *
++	 * Duh, I'm just handwaving here about possible explanations of what's
++	 * going on in the hardware. This is the voodoo ritual that makes it
++	 * work while anything else fails.
++	 */
++	if (hw->rx && hw->count) {
++		udelay(1+10*1000000/spi->max_speed_hz);
++		hw->rx[hw->count-1] = readb(hw->regs + S3C2410_SPRDAT);
++	}
++
++	if (0&&t->rx_buf && t->len > 18) {
++		int i;
++
++		printk(KERN_INFO "RX (%p):", t->rx_buf);
++		for (i = 0; i != t->len; i++)
++			printk(" %02x", ((u8 *) t->rx_buf)[i]);
++		printk("\n");
++	}
+ 	return hw->count;
+ }
+ 
+@@ -233,8 +254,19 @@
+ 
+ 	hw->count++;
+ 
+-	if (hw->rx)
+-		hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
++	/*
++	 * Misfeature #1: the first byte received can only be read after
++	 * writing the second byte to send to the shifter.
++	 *
++	 * Misfeature #2: we need to consume the byte preceding the first byte
++	 * or the SPI engine gets upset.
++	 */
++	if (hw->rx) {
++		u8 b = readb(hw->regs + S3C2410_SPRDAT);
++
++		if (count)
++			hw->rx[count-1] = b;
++	}
+ 
+ 	count++;
+ 
+Index: korig/arch/arm/mach-s3c2440/mach-gta02.c
+===================================================================
+--- korig.orig/arch/arm/mach-s3c2440/mach-gta02.c	2008-09-27 21:32:30.000000000 -0300
++++ korig/arch/arm/mach-s3c2440/mach-gta02.c	2008-09-27 21:32:30.000000000 -0300
+@@ -1239,7 +1239,7 @@
+ static struct spi_board_info gta02_spi_mmc_bdinfo = {
+ 	.modalias	= "mmc_spi",
+ 	.irq		= IRQ_EINT3,	/* unused ? */
+-	.max_speed_hz	= 25 * 1000 * 1000,
++	.max_speed_hz	= 12 * 1000 * 1000, /* SPI doesn't want to go faster */
+ 	.bus_num	= 0,
+ 	.chip_select	= 0,
+ 	.mode		= SPI_MODE_0,

Added: developers/werner/wlan-spi/patches/s3c-spi-from-int-to-poll.patch
===================================================================
--- developers/werner/wlan-spi/patches/s3c-spi-from-int-to-poll.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches/s3c-spi-from-int-to-poll.patch	2008-09-28 02:12:36 UTC (rev 4678)
@@ -0,0 +1,105 @@
+Change the S3C SPI driver to use poll mode instead of interrupt mode.
+This reduces the gap between bytes from about 2.25us [1] to 100ns [2].
+
+[1] http://people.openmoko.org/werner/wlan-spi/spi-int.png
+[2] http://people.openmoko.org/werner/wlan-spi/spi-poll.png
+
+Index: korig/drivers/spi/spi_s3c24xx.c
+===================================================================
+--- korig.orig/drivers/spi/spi_s3c24xx.c	2008-09-27 22:45:38.000000000 -0300
++++ korig/drivers/spi/spi_s3c24xx.c	2008-09-27 22:46:45.000000000 -0300
+@@ -56,7 +56,7 @@
+ 	struct s3c2410_spi_info *pdata;
+ };
+ 
+-#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)
++#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_POLL)
+ #define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP)
+ 
+ static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev)
+@@ -183,6 +183,7 @@
+ static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
+ {
+ 	struct s3c24xx_spi *hw = to_hw(spi);
++	int i;
+ 
+ 	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
+ 		t->tx_buf, t->rx_buf, t->len);
+@@ -194,9 +195,19 @@
+ 	hw->len = t->len;
+ 	hw->count = 0;
+ 
+-	/* send the first byte */
+-	writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
+-	wait_for_completion(&hw->done);
++	for (i = 0; i != t->len; i++) {
++		u8 spsta;
++
++		writeb(hw_txbyte(hw, i), hw->regs + S3C2410_SPTDAT);
++		do spsta = readb(hw->regs + S3C2410_SPSTA);
++		while (!(spsta & S3C2410_SPSTA_READY));
++		if (hw->rx) {
++			u8 b = readb(hw->regs + S3C2410_SPRDAT);
++
++			if (i)
++				hw->rx[i-1] = b;
++		}
++	}
+ 
+ 	/*
+ 	 * Get the last byte. Since we don't have more data we can send in
+@@ -206,9 +217,9 @@
+ 	 * going on in the hardware. This is the voodoo ritual that makes it
+ 	 * work while anything else fails.
+ 	 */
+-	if (hw->rx && hw->count) {
++	if (hw->rx && i) {
+ 		udelay(1+10*1000000/spi->max_speed_hz);
+-		hw->rx[hw->count-1] = readb(hw->regs + S3C2410_SPRDAT);
++		hw->rx[i-1] = readb(hw->regs + S3C2410_SPRDAT);
+ 	}
+ 
+ 	if (0&&t->rx_buf && t->len > 18) {
+@@ -219,7 +230,7 @@
+ 			printk(" %02x", ((u8 *) t->rx_buf)[i]);
+ 		printk("\n");
+ 	}
+-	return hw->count;
++	return t->len;
+ }
+ 
+ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
+@@ -351,6 +362,7 @@
+ 		goto err_no_iomap;
+ 	}
+ 
++#if 0
+ 	hw->irq = platform_get_irq(pdev, 0);
+ 	if (hw->irq < 0) {
+ 		dev_err(&pdev->dev, "No IRQ specified\n");
+@@ -363,6 +375,7 @@
+ 		dev_err(&pdev->dev, "Cannot claim IRQ\n");
+ 		goto err_no_irq;
+ 	}
++#endif
+ 
+ 	hw->clk = clk_get(&pdev->dev, "spi");
+ 	if (IS_ERR(hw->clk)) {
+@@ -416,7 +429,7 @@
+ 	clk_put(hw->clk);
+ 
+  err_no_clk:
+-	free_irq(hw->irq, hw);
++	//free_irq(hw->irq, hw);
+ 
+  err_no_irq:
+ 	iounmap(hw->regs);
+@@ -444,7 +457,7 @@
+ 	clk_disable(hw->clk);
+ 	clk_put(hw->clk);
+ 
+-	free_irq(hw->irq, hw);
++	//free_irq(hw->irq, hw);
+ 	iounmap(hw->regs);
+ 
+ 	release_resource(hw->ioarea);

Modified: developers/werner/wlan-spi/patches/series
===================================================================
--- developers/werner/wlan-spi/patches/series	2008-09-28 01:44:31 UTC (rev 4677)
+++ developers/werner/wlan-spi/patches/series	2008-09-28 02:12:36 UTC (rev 4678)
@@ -25,6 +25,7 @@
 ar6k-essid-one-and-32.patch
 gta02-no-glamo-mmc.patch
 hack-silence-battery.patch
-tweak-spi.patch
+s3c-spi-fix-int-mode.patch
+s3c-spi-from-int-to-poll.patch
 #dont-poll-irq.patch
 #try

Deleted: developers/werner/wlan-spi/patches/tweak-spi.patch
===================================================================
--- developers/werner/wlan-spi/patches/tweak-spi.patch	2008-09-28 01:44:31 UTC (rev 4677)
+++ developers/werner/wlan-spi/patches/tweak-spi.patch	2008-09-28 02:12:36 UTC (rev 4678)
@@ -1,76 +0,0 @@
-Work in progress. Makes spi_s3c24xx.c work for up to 12MHz.
-
-At speeds of 13MHz or higher, we have setup time issues. I.e., the
-SPI host sees the data coming from the device delayed by one bit,
-even though things look fine on the scope.
-
-This 12MHz/13MHz "barrier" exists with or without probes attached,
-suggesting capacitative loading plays only a minor role in this.
-
-Index: korig/drivers/spi/spi_s3c24xx.c
-===================================================================
---- korig.orig/drivers/spi/spi_s3c24xx.c	2008-09-27 21:32:30.000000000 -0300
-+++ korig/drivers/spi/spi_s3c24xx.c	2008-09-27 22:27:20.000000000 -0300
-@@ -198,6 +198,27 @@
- 	writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
- 	wait_for_completion(&hw->done);
- 
-+	/*
-+	 * Get the last byte. Since we don't have more data we can send in
-+	 * order to clock the byte out of the SPI system, we need to wait.
-+	 *
-+	 * Duh, I'm just handwaving here about possible explanations of what's
-+	 * going on in the hardware. This is the voodoo ritual that makes it
-+	 * work while anything else fails.
-+	 */
-+	if (hw->rx && hw->count) {
-+		udelay(1+10*1000000/spi->max_speed_hz);
-+		hw->rx[hw->count-1] = readb(hw->regs + S3C2410_SPRDAT);
-+	}
-+
-+	if (0&&t->rx_buf && t->len > 18) {
-+		int i;
-+
-+		printk(KERN_INFO "RX (%p):", t->rx_buf);
-+		for (i = 0; i != t->len; i++)
-+			printk(" %02x", ((u8 *) t->rx_buf)[i]);
-+		printk("\n");
-+	}
- 	return hw->count;
- }
- 
-@@ -233,8 +254,19 @@
- 
- 	hw->count++;
- 
--	if (hw->rx)
--		hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
-+	/*
-+	 * Misfeature #1: the first byte received can only be read after
-+	 * writing the second byte to send to the shifter.
-+	 *
-+	 * Misfeature #2: we need to consume the byte preceding the first byte
-+	 * or the SPI engine gets upset.
-+	 */
-+	if (hw->rx) {
-+		u8 b = readb(hw->regs + S3C2410_SPRDAT);
-+
-+		if (count)
-+			hw->rx[count-1] = b;
-+	}
- 
- 	count++;
- 
-Index: korig/arch/arm/mach-s3c2440/mach-gta02.c
-===================================================================
---- korig.orig/arch/arm/mach-s3c2440/mach-gta02.c	2008-09-27 21:32:30.000000000 -0300
-+++ korig/arch/arm/mach-s3c2440/mach-gta02.c	2008-09-27 21:32:30.000000000 -0300
-@@ -1239,7 +1239,7 @@
- static struct spi_board_info gta02_spi_mmc_bdinfo = {
- 	.modalias	= "mmc_spi",
- 	.irq		= IRQ_EINT3,	/* unused ? */
--	.max_speed_hz	= 25 * 1000 * 1000,
-+	.max_speed_hz	= 12 * 1000 * 1000, /* SPI doesn't want to go faster */
- 	.bus_num	= 0,
- 	.chip_select	= 0,
- 	.mode		= SPI_MODE_0,




More information about the commitlog mailing list