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