pxa2xx_spi: fix chip_info defaults and documentation.
authorVernon Sauder <vernoninhand@gmail.com>
Thu, 16 Oct 2008 05:02:43 +0000 (22:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Oct 2008 18:21:38 +0000 (11:21 -0700)
Make the chip info structure data optional by providing reasonable
defaults.  Improve corresponding documentation, and highlight the drawback
of not providing explicit chipselect control.

DMA can determine appropriate dma_burst_size and thresholds automatically
so use DMA even if dma_burst_size is not specified.

Signed-off-by: Vernon Sauder <VernonInHand@gmail.com>
Reviewed-by: Ned Forrester <nforrester@whoi.edu>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/spi/pxa2xx
drivers/spi/pxa2xx_spi.c

index bbe8dee681a5d2b9a503d7f59b22e79d7a3e9014..6bb916d57c957754fd9b4915c4d1a42e3a4cc8ac 100644 (file)
@@ -96,7 +96,7 @@ Each slave device attached to the PXA must provide slave specific configuration
 information via the structure "pxa2xx_spi_chip" found in
 "arch/arm/mach-pxa/include/mach/pxa2xx_spi.h".  The pxa2xx_spi master controller driver
 will uses the configuration whenever the driver communicates with the slave
-device.
+device. All fields are optional.
 
 struct pxa2xx_spi_chip {
        u8 tx_threshold;
@@ -112,14 +112,17 @@ used to configure the SSP hardware fifo.  These fields are critical to the
 performance of pxa2xx_spi driver and misconfiguration will result in rx
 fifo overruns (especially in PIO mode transfers). Good default values are
 
-       .tx_threshold = 12,
-       .rx_threshold = 4,
+       .tx_threshold = 8,
+       .rx_threshold = 8,
+
+The range is 1 to 16 where zero indicates "use default".
 
 The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA
 engine and is related the "spi_device.bits_per_word" field.  Read and understand
 the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers
 to determine the correct value. An SSP configured for byte-wide transfers would
-use a value of 8.
+use a value of 8. The driver will determine a reasonable default if
+dma_burst_size == 0.
 
 The "pxa2xx_spi_chip.timeout" fields is used to efficiently handle
 trailing bytes in the SSP receiver fifo.  The correct value for this field is
@@ -137,7 +140,13 @@ function for asserting/deasserting a slave device chip select.  If the field is
 NULL, the pxa2xx_spi master controller driver assumes that the SSP port is
 configured to use SSPFRM instead.
 
-NSSP SALVE SAMPLE
+NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the
+chipselect is dropped after each spi_transfer.  Most devices need chip select
+asserted around the complete message.  Use SSPFRM as a GPIO (through cs_control)
+to accomodate these chips.
+
+
+NSSP SLAVE SAMPLE
 -----------------
 The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the
 "spi_board_info.controller_data" field. Below is a sample configuration using
@@ -206,18 +215,21 @@ static void __init streetracer_init(void)
 
 DMA and PIO I/O Support
 -----------------------
-The pxa2xx_spi driver support both DMA and interrupt driven PIO message
-transfers.  The driver defaults to PIO mode and DMA transfers must enabled by
-setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and
-ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero.  The DMA
-mode support both coherent and stream based DMA mappings.
+The pxa2xx_spi driver supports both DMA and interrupt driven PIO message
+transfers.  The driver defaults to PIO mode and DMA transfers must be enabled
+by setting the "enable_dma" flag in the "pxa2xx_spi_master" structure.  The DMA
+mode supports both coherent and stream based DMA mappings.
 
 The following logic is used to determine the type of I/O to be used on
 a per "spi_transfer" basis:
 
-if !enable_dma or dma_burst_size == 0 then
+if !enable_dma then
        always use PIO transfers
 
+if spi_message.len > 8191 then
+       print "rate limited" warning
+       use PIO transfers
+
 if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then
        use coherent DMA mode
 
index 59ae3ed16658f2bd60f009c8922694c7a101362c..dae87b1a4c6effa5c18cff538c3a634a846a2957 100644 (file)
@@ -47,6 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
 
 #define MAX_BUSES 3
 
+#define RX_THRESH_DFLT         8
+#define TX_THRESH_DFLT         8
+#define TIMOUT_DFLT            1000
+
 #define DMA_INT_MASK           (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
 #define RESET_DMA_CHANNEL      (DCSR_NODESC | DMA_INT_MASK)
 #define IS_DMA_ALIGNED(x)      ((((u32)(x)) & 0x07) == 0)
@@ -1171,6 +1175,8 @@ static int setup(struct spi_device *spi)
        struct driver_data *drv_data = spi_master_get_devdata(spi->master);
        struct ssp_device *ssp = drv_data->ssp;
        unsigned int clk_div;
+       uint tx_thres = TX_THRESH_DFLT;
+       uint rx_thres = RX_THRESH_DFLT;
 
        if (!spi->bits_per_word)
                spi->bits_per_word = 8;
@@ -1209,8 +1215,7 @@ static int setup(struct spi_device *spi)
 
                chip->cs_control = null_cs_control;
                chip->enable_dma = 0;
-               chip->timeout = 1000;
-               chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
+               chip->timeout = TIMOUT_DFLT;
                chip->dma_burst_size = drv_data->master_info->enable_dma ?
                                        DCMD_BURST8 : 0;
        }
@@ -1224,22 +1229,21 @@ static int setup(struct spi_device *spi)
        if (chip_info) {
                if (chip_info->cs_control)
                        chip->cs_control = chip_info->cs_control;
-
-               chip->timeout = chip_info->timeout;
-
-               chip->threshold = (SSCR1_RxTresh(chip_info->rx_threshold) &
-                                                               SSCR1_RFT) |
-                               (SSCR1_TxTresh(chip_info->tx_threshold) &
-                                                               SSCR1_TFT);
-
-               chip->enable_dma = chip_info->dma_burst_size != 0
-                                       && drv_data->master_info->enable_dma;
+               if (chip_info->timeout)
+                       chip->timeout = chip_info->timeout;
+               if (chip_info->tx_threshold)
+                       tx_thres = chip_info->tx_threshold;
+               if (chip_info->rx_threshold)
+                       rx_thres = chip_info->rx_threshold;
+               chip->enable_dma = drv_data->master_info->enable_dma;
                chip->dma_threshold = 0;
-
                if (chip_info->enable_loopback)
                        chip->cr1 = SSCR1_LBM;
        }
 
+       chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
+                       (SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
+
        /* set dma burst and threshold outside of chip_info path so that if
         * chip_info goes away after setting chip->enable_dma, the
         * burst and threshold can still respond to changes in bits_per_word */
@@ -1268,17 +1272,19 @@ static int setup(struct spi_device *spi)
 
        /* NOTE:  PXA25x_SSP _could_ use external clocking ... */
        if (drv_data->ssp_type != PXA25x_SSP)
-               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
+               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
                                spi->bits_per_word,
                                clk_get_rate(ssp->clk)
                                        / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-                               spi->mode & 0x3);
+                               spi->mode & 0x3,
+                               chip->enable_dma ? "DMA" : "PIO");
        else
-               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
+               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
                                spi->bits_per_word,
-                               clk_get_rate(ssp->clk)
+                               clk_get_rate(ssp->clk) / 2
                                        / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-                               spi->mode & 0x3);
+                               spi->mode & 0x3,
+                               chip->enable_dma ? "DMA" : "PIO");
 
        if (spi->bits_per_word <= 8) {
                chip->n_bytes = 1;
@@ -1498,7 +1504,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
 
        /* Load default SSP configuration */
        write_SSCR0(0, drv_data->ioaddr);
-       write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr);
+       write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) |
+                               SSCR1_TxTresh(TX_THRESH_DFLT),
+                               drv_data->ioaddr);
        write_SSCR0(SSCR0_SerClkDiv(2)
                        | SSCR0_Motorola
                        | SSCR0_DataSize(8),