Ned,

Sorry for the slow response. Real world/work intrudes sometimes.

Here is another version of the patch along with responses to your
comments.

Ned Forrester wrote:

>Vernon Sauder wrote:
>> 
>> Would you be in favor of a patch like this? If the code does not
>> match the documentation, let me know if the documentation is
>> correct. I can then figure out what the code should do.
>> 
>> Regards,
>> Vern
>
>Looks fine, except as noted below...
>
>Also, you should make patches with something equivalent to:
>
>rm -f $patch_file $tmp_file
>LC_ALL=C TZ=UTC0 diff -Nurp $src_dir $patch_dir > $tmp_file
>cat $patch_text > $patch_file
>diffstat -p 1 -w 70 $tmp_file >> $patch_file
>echo "" >> $patch_file
>cat $tmp_file >> $patch_file
>rm $tmp_file
>
>Note the environment variables and flags passed to diff, and the use of
>diffstat.

Thanks. This time I used git format-patch because I used a git tree.

>> ---
>> pxa2xx_spi: Fix chip_info defaults and documentation.
>> 
>> Make the chip info structure data optional by providing reasonable
>> defaults. Improve corresponding documentation.
>> 
>> 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 <[EMAIL PROTECTED]>
>> ---
>> --- linux-2.6.24.4/drivers/spi/pxa2xx_spi.c  2008-03-24
>> 14:49:18.000000000 -0400 +++
>> src.cache/drivers/spi/pxa2xx_spi.c   2008-08-20
>> 13:20:19.000000000 -0400 @@ -44,6 +44,10 @@ 
>>  #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)
>> @@ -1126,8 +1130,7 @@
>>  
>>              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;
>>      }
>> @@ -1138,25 +1141,28 @@
>>  
>>      /* chip_info isn't always needed */
>>      chip->cr1 = 0;
>> +    uint tx_thres = TX_THRESH_DFLT;
>> +    uint rx_thres = RX_THRESH_DFLT;
>>      if (chip_info) {
>>              if (chip_info->cs_control)
>>                      chip->cs_control = chip_info->cs_control;
>> -
>> -            chip->timeout = chip_info->timeout;
>> +            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->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;
>> +            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 */ @@ -1196,17 +1202,19 @@
>>  
>>      /* NOTE:  PXA25x_SSP _could_ use external clocking ... */
>>      if (drv_data->ssp_type != PXA25x_SSP)
>> -            dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
>> +            dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d,
>> %s\n", spi->bits_per_word,
>>                              (CLOCK_SPEED_HZ)
>>                                      / (1 + ((chip->cr0 &
>> SSCR0_SCR) >> 8)),
>> -                            spi->mode & 0x3);
>> +                            spi->mode & 0x3,
>> +                            chip->enable_dma ? "DMA" : "PIO");
>
>Oops! You are not patching the latest version of the code.  This
>version predates 1/26/08.  CLOCK_SPEED_HZ is no longer part of the
>code.  The patch will be rejected if it does not apply against the
>current git tree.  The latest version can be found at:
>
>http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=drivers/spi/pxa2xx_spi.c;hb=HEAD
>

This patch is against the latest Linus tree.

>>      else
>> -            dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
>> +            dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d,
>> %s\n", spi->bits_per_word,
>>                              (CLOCK_SPEED_HZ/2)
>
>I note that when this line was changed in 1/26/08 commit, the author of
>that patch left out the /2, leaving the two branches of this if/else
>identical.  Please restore the /2 when you submit this patch.
>

Done.

>>                                      / (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;
>> @@ -1457,7 +1465,8 @@
>>  
>>      /* 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),
>> --- linux-2.6.24.4/Documentation/spi/pxa2xx  2008-03-24
>> 14:49:18.000000000 -0400 +++
>> src.cache/Documentation/spi/pxa2xx   2008-08-20
>> 13:14:01.000000000 -0400 @@ -96,7 +96,7 @@ information via the
>> structure "pxa2xx_spi_chip" found in
>> "include/asm-arm/arch-pxa/pxa2xx_spi.h".  The pxa2xx_spi master
>> controller driver
>
>Again, you are trying to patch an obsolete version.  I'm not sure if
>the correctly made patch will apply to older versions, but this whole
>patch is not essential to back port, as it is a "clarification" and
>not a bug fix.  I realize that you consider it a bug fix, and in a way
>I agree, but it is not, in the sense that older drivers can be used if
>all fields in this structure are filled in.
>
>>  will uses the configuration whenever the driver communicates with
>> the slave -device.
>> +device. All fields are optional.
>
>Do you need to note that unused fields should be set to zero, or is
>these always zeroed by the way the struct pxa2xx_spi_chip is declared
>(external or static declaration)?  I have forgotten and you probably
>looked at that recently.

C requires all file-scope variables without initializers to be in the
BSS which is cleared at startup.

>>  
>>  struct pxa2xx_spi_chip {
>>      u8 tx_threshold;
>> @@ -112,14 +112,17 @@
>>  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 @@ -135,7 +138,10 @@
>>  The "pxa2xx_spi_chip.cs_control" field is used to point to a board
>> specific 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. +configured to use SSPFRM instead. NOTE: the SPI driver
>> cannot control the chip +select if SSPFRM is used so each transfer
>> will assert/deassert SSPFRM around it. +Many devices need chip
>> select asserted around the complete message. The +cs_control method
>> should use the SSPFRM pin as a GPIO to accomodate these chips.
>
>*could* use the SSPFRM pin.  It can also use any other GPIO line, and
>at most one could use SSPFRM if there are multiple chips on the bus.

Done.

>>  
>>  NSSP SALVE SAMPLE
>>  -----------------
>> @@ -206,16 +212,15 @@
>>  
>>  DMA and PIO I/O Support
>>  -----------------------
>> -The pxa2xx_spi driver support both DMA and interrupt driven PIO
>> message +The pxa2xx_spi driver supports both DMA and interrupt
>> driven PIO message transfers.  The driver defaults to PIO mode and
>> DMA transfers must enabled by
>
>Add "be" between "must enabled".

Done.

>> -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 +setting the "enable_dma" flag in the
>> "pxa2xx_spi_master" structure.  The DMA mode support both coherent
>> and stream based DMA mappings.
>
>As long as you are fixing, then "supports" above.
>

Done.

>>  
>>  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
>
>Well, that is true, but the user should probably note that simply
>requesting DMA via the enable_dma flag is not sufficient to guarantee
>that DMA will be used.  There are a number of criteria in
>map_dma_buffers that must be met.  I guess that is what the rest of
>that list is trying to say.
>
>Also note that the very recent patch that I submitted, tries to address
>a problem that you encountered with transfer lengths longer than 8192;
>in that case, I changed the behavior from "fail" to "do it in PIO mode
>with rate limited warning".  Some day the driver could be rewritten to
>bust long transfers and do the pieces by DMA, but that is too ambitious
>for now.  So you could add to the list of states that transfers longer
>than 8191 will be PIO.  Have you tested that patch to see if it fixes
>any of your other problems?
>

I did not try that patch yet. I added a comment to the doc about this.

>I'm not sure I believe the words about coherent and stream DMA, but I
>will have to check that later.

OK

Patch against Linus 2.6 tree after
4c246edd2550304df5b766cc841584b2bb058843. It is compile tested only.

---
Subject: [PATCH] pxa2xx_spi: Fix chip_info defaults and documentation.

Make the chip info structure data optional by providing reasonable
defaults. Improve corresponding documentation.

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 <[EMAIL PROTECTED]>
---
 Documentation/spi/pxa2xx |   31 ++++++++++++++++++++-----------
 drivers/spi/pxa2xx_spi.c |   43 ++++++++++++++++++++++++++-----------------
 2 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx
index bbe8dee..92e3a37 100644
--- a/Documentation/spi/pxa2xx
+++ b/Documentation/spi/pxa2xx
@@ -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
@@ -135,7 +138,10 @@ testing.
 The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific
 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.
+configured to use SSPFRM instead. NOTE: the SPI driver cannot control the chip
+select if SSPFRM is used so each transfer will assert/deassert SSPFRM around 
it.
+Many devices need chip select asserted around the complete message. The 
+cs_control method could use the SSPFRM pin as a GPIO to accomodate these chips.
 
 NSSP SALVE SAMPLE
 -----------------
@@ -206,18 +212,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 > 8192 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
 
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 34c7c98..239a26c 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -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)
@@ -1105,6 +1109,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;
@@ -1143,8 +1149,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;
        }
@@ -1159,21 +1164,22 @@ static int setup(struct spi_device *spi)
                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 */
@@ -1202,17 +1208,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;
@@ -1432,7 +1440,8 @@ 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),
-- 
1.5.2.4


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to