diff options
| author | Michael Williamson <michael.williamson@criticallink.com> | 2011-03-14 11:49:02 -0400 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2011-03-14 15:17:04 -0400 |
| commit | b1178b21c6b9721a07fbd50762067a7c0ffa5a50 (patch) | |
| tree | 048252f10af96adfc09c562214b51b0f4b4e0cae | |
| parent | d09519e41a67eab22cc4566670431f9252b6786a (diff) | |
spi/davinci: Support DMA transfers larger than 65535 words
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>
| -rw-r--r-- | 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 68ed377cc626..e90c2d6a84b3 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) | |||
| 571 | unsigned long tx_reg, rx_reg; | 571 | unsigned long tx_reg, rx_reg; |
| 572 | struct edmacc_param param; | 572 | struct edmacc_param param; |
| 573 | void *rx_buf; | 573 | void *rx_buf; |
| 574 | int b, c; | ||
| 574 | 575 | ||
| 575 | dma = &dspi->dma; | 576 | dma = &dspi->dma; |
| 576 | 577 | ||
| @@ -599,14 +600,30 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
| 599 | } | 600 | } |
| 600 | } | 601 | } |
| 601 | 602 | ||
| 603 | /* | ||
| 604 | * If number of words is greater than 65535, then we need | ||
| 605 | * to configure a 3 dimension transfer. Use the BCNTRLD | ||
| 606 | * feature to allow for transfers that aren't even multiples | ||
| 607 | * of 65535 (or any other possible b size) by first transferring | ||
| 608 | * the remainder amount then grabbing the next N blocks of | ||
| 609 | * 65535 words. | ||
| 610 | */ | ||
| 611 | |||
| 612 | c = dspi->wcount / (SZ_64K - 1); /* N 65535 Blocks */ | ||
| 613 | b = dspi->wcount - c * (SZ_64K - 1); /* Remainder */ | ||
| 614 | if (b) | ||
| 615 | c++; | ||
| 616 | else | ||
| 617 | b = SZ_64K - 1; | ||
| 618 | |||
| 602 | param.opt = TCINTEN | EDMA_TCC(dma->tx_channel); | 619 | param.opt = TCINTEN | EDMA_TCC(dma->tx_channel); |
| 603 | param.src = t->tx_buf ? t->tx_dma : tx_reg; | 620 | param.src = t->tx_buf ? t->tx_dma : tx_reg; |
| 604 | param.a_b_cnt = dspi->wcount << 16 | data_type; | 621 | param.a_b_cnt = b << 16 | data_type; |
| 605 | param.dst = tx_reg; | 622 | param.dst = tx_reg; |
| 606 | param.src_dst_bidx = t->tx_buf ? data_type : 0; | 623 | param.src_dst_bidx = t->tx_buf ? data_type : 0; |
| 607 | param.link_bcntrld = 0xffff; | 624 | param.link_bcntrld = 0xffffffff; |
| 608 | param.src_dst_cidx = 0; | 625 | param.src_dst_cidx = t->tx_buf ? data_type : 0; |
| 609 | param.ccnt = 1; | 626 | param.ccnt = c; |
| 610 | edma_write_slot(dma->tx_channel, ¶m); | 627 | edma_write_slot(dma->tx_channel, ¶m); |
| 611 | edma_link(dma->tx_channel, dma->dummy_param_slot); | 628 | edma_link(dma->tx_channel, dma->dummy_param_slot); |
| 612 | 629 | ||
| @@ -643,12 +660,12 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
| 643 | 660 | ||
| 644 | param.opt = TCINTEN | EDMA_TCC(dma->rx_channel); | 661 | param.opt = TCINTEN | EDMA_TCC(dma->rx_channel); |
| 645 | param.src = rx_reg; | 662 | param.src = rx_reg; |
| 646 | param.a_b_cnt = dspi->rcount << 16 | data_type; | 663 | param.a_b_cnt = b << 16 | data_type; |
| 647 | param.dst = t->rx_dma; | 664 | param.dst = t->rx_dma; |
| 648 | param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16; | 665 | param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16; |
| 649 | param.link_bcntrld = 0xffff; | 666 | param.link_bcntrld = 0xffffffff; |
| 650 | param.src_dst_cidx = 0; | 667 | param.src_dst_cidx = (t->rx_buf ? data_type : 0) << 16; |
| 651 | param.ccnt = 1; | 668 | param.ccnt = c; |
| 652 | edma_write_slot(dma->rx_channel, ¶m); | 669 | edma_write_slot(dma->rx_channel, ¶m); |
| 653 | 670 | ||
| 654 | if (pdata->cshold_bug) | 671 | if (pdata->cshold_bug) |
