@@ -763,27 +763,47 @@ static int davinci_spi_txrx_bufs(struct
spi_device *spi, struct spi_transfer *t)
t->rx_dma = dma_map_single(&spi->dev, rx_buf,
rx_buf_count, DMA_FROM_DEVICE);
- tx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_tx_channel);
- tx_param.src = t->tx_buf ? t->tx_dma : tx_reg;
- tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type;
- tx_param.dst = tx_reg;
- tx_param.src_dst_bidx = t->tx_buf ? data_type : 0;
- tx_param.link_bcntrld = 0xffff;
- tx_param.src_dst_cidx = 0;
- tx_param.ccnt = 1;
- edma_write_slot(davinci_dma->dma_tx_channel, &tx_param);
- edma_link(davinci_dma->dma_tx_channel,
- davinci_dma->dummy_param_slot);
-
- rx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_rx_channel);
- rx_param.src = rx_reg;
- rx_param.a_b_cnt = davinci_spi->rcount << 16 | data_type;
- rx_param.dst = t->rx_dma;
- rx_param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16;
- rx_param.link_bcntrld = 0xffff;
- rx_param.src_dst_cidx = 0;
- rx_param.ccnt = 1;
- edma_write_slot(davinci_dma->dma_rx_channel, &rx_param);
+ if( davinci_spi->wcount < 0x10000 || !(davinci_spi->wcount & 0x7fff) ) {
+ /*We can use a single PaRAM slot*/
+ tx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_tx_channel);
+ tx_param.src = t->tx_buf ? t->tx_dma : tx_reg;
+ tx_param.dst = tx_reg;
+ tx_param.src_dst_bidx = t->tx_buf ? data_type : 0;
+ tx_param.src_dst_cidx = t->tx_buf ? data_type : 0;
+ tx_param.link_bcntrld = (0x8000 << 16) | 0xffff;
+ if( davinci_spi->wcount < 0x10000 ) { /*Use a single frame of BCNT=wcount*/
+ tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type;
+ tx_param.ccnt = 1;
+ }
+ else { /*Use multiple frames of BCNT=32K*/
+ tx_param.a_b_cnt = 0x8000 << 16 | data_type;
+ tx_param.ccnt = davinci_spi->wcount / 0x8000;
+ }
+ edma_write_slot(davinci_dma->dma_tx_channel, &tx_param);
+ edma_link(davinci_dma->dma_tx_channel,
+ davinci_dma->dummy_param_slot);
+
+ rx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_rx_channel);
+ rx_param.src = rx_reg;
+ rx_param.dst = t->rx_dma;
+ rx_param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16;
+ rx_param.src_dst_cidx = (t->rx_buf ? data_type : 0) << 16;
+ rx_param.link_bcntrld = (0x8000 << 16) | 0xffff;
+ if( davinci_spi->rcount < 0x10000 ) { /*Use a single frame of BCNT=wcount*/
+ rx_param.a_b_cnt = davinci_spi->rcount << 16 | data_type;
+ rx_param.ccnt = 1;
+ }
+ else { /*Use multiple frames of BCNT=32K*/
+ rx_param.a_b_cnt = 0x8000 << 16 | data_type;
+ rx_param.ccnt = davinci_spi->rcount / 0x8000;
+ }
+ edma_write_slot(davinci_dma->dma_rx_channel, &rx_param);
+ }
+ else {
+ /*Need to use multiple PaRAM slots*/
+ printk("unsupported\n");
+ return -EIO;
+ }
iowrite16(spidat1 >> SPIDAT1_CSNR_SHIFT,