Skip to content

Commit

Permalink
spi/davinci: Support DMA transfers larger than 65535 words
Browse files Browse the repository at this point in the history
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 <michael.williamson@criticallink.com>
Tested-by: Stefano Babic <sbabic@denx.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
  • Loading branch information
Michael Williamson authored and Grant Likely committed Mar 14, 2011
1 parent d09519e commit b1178b2
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions drivers/spi/davinci_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit b1178b2

Please sign in to comment.