On Mon, Mar 14, 2011 at 11:49:02AM -0400, Michael Williamson wrote:
> The current davinci SPI driver, in DMA mode, is limited to 65535
> words for a single transfer.  Modify the driver by configuring a
> 3 dimensional EDMA transfer to support up to 65535x65535
> words.
> 
> Signed-off-by: Michael Williamson <[email protected]>
> Tested-by: Stefano Babic <[email protected]>

Applied, thanks.

> ---
> changes since v0:
>    - Added spaces per style guide comments.
> 
> This patch is an attempt to address the issue raised here:
> 
> http://comments.gmane.org/gmane.linux.davinci/20581
> 
> Tested with:
> dd if=/dev/mtd7 of=/tmp/test.1K bs=1024 count=1024
> dd if=/dev/mtd7 of=/tmp/test.64K bs=65536 count=16
> dd if=/dev/mtd7 of=/tmp/test.128K bs=131072 count=8
> md5sum /tmp/test*
> 
>  drivers/spi/davinci_spi.c |   33 +++++++++++++++++++++++++--------
>  1 files changed, 25 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
> index 037ba82..1f0ed80 100644
> --- a/drivers/spi/davinci_spi.c
> +++ b/drivers/spi/davinci_spi.c
> @@ -571,6 +571,7 @@ static int davinci_spi_bufs(struct spi_device *spi, 
> struct spi_transfer *t)
>               unsigned long tx_reg, rx_reg;
>               struct edmacc_param param;
>               void *rx_buf;
> +             int b, c;
>  
>               dma = &dspi->dma;
>  
> @@ -599,14 +600,30 @@ static int davinci_spi_bufs(struct spi_device *spi, 
> struct spi_transfer *t)
>                       }
>               }
>  
> +             /*
> +              * If number of words is greater than 65535, then we need
> +              * to configure a 3 dimension transfer.  Use the BCNTRLD
> +              * feature to allow for transfers that aren't even multiples
> +              * of 65535 (or any other possible b size) by first transferring
> +              * the remainder amount then grabbing the next N blocks of
> +              * 65535 words.
> +              */
> +
> +             c = dspi->wcount / (SZ_64K - 1);        /* N 65535 Blocks */
> +             b = dspi->wcount - c * (SZ_64K - 1);    /* Remainder */
> +             if (b)
> +                     c++;
> +             else
> +                     b = SZ_64K - 1;
> +
>               param.opt = TCINTEN | EDMA_TCC(dma->tx_channel);
>               param.src = t->tx_buf ? t->tx_dma : tx_reg;
> -             param.a_b_cnt = dspi->wcount << 16 | data_type;
> +             param.a_b_cnt = b << 16 | data_type;
>               param.dst = tx_reg;
>               param.src_dst_bidx = t->tx_buf ? data_type : 0;
> -             param.link_bcntrld = 0xffff;
> -             param.src_dst_cidx = 0;
> -             param.ccnt = 1;
> +             param.link_bcntrld = 0xffffffff;
> +             param.src_dst_cidx = t->tx_buf ? data_type : 0;
> +             param.ccnt = c;
>               edma_write_slot(dma->tx_channel, &param);
>               edma_link(dma->tx_channel, dma->dummy_param_slot);
>  
> @@ -643,12 +660,12 @@ static int davinci_spi_bufs(struct spi_device *spi, 
> struct spi_transfer *t)
>  
>               param.opt = TCINTEN | EDMA_TCC(dma->rx_channel);
>               param.src = rx_reg;
> -             param.a_b_cnt = dspi->rcount << 16 | data_type;
> +             param.a_b_cnt = b << 16 | data_type;
>               param.dst = t->rx_dma;
>               param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16;
> -             param.link_bcntrld = 0xffff;
> -             param.src_dst_cidx = 0;
> -             param.ccnt = 1;
> +             param.link_bcntrld = 0xffffffff;
> +             param.src_dst_cidx = (t->rx_buf ? data_type : 0) << 16;
> +             param.ccnt = c;
>               edma_write_slot(dma->rx_channel, &param);
>  
>               if (pdata->cshold_bug)
> -- 
> 1.7.0.4
> 
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to