diff mbox

Problem with new SPI driver

Message ID AANLkTimcCxrFwjxdXLQufB4-Mbx600hBMSav403dHyui@mail.gmail.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Marc-André Hébert Oct. 29, 2010, 3:02 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 5c9e9ce..93e716d 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -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,