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 /drivers/spi/davinci_spi.c | |
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>
Diffstat (limited to 'drivers/spi/davinci_spi.c')
-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) |