spi:improve spi dma burst
authorLuowei <lw@rock-chips.com>
Fri, 17 Oct 2014 03:26:01 +0000 (11:26 +0800)
committerLuowei <lw@rock-chips.com>
Fri, 17 Oct 2014 03:26:01 +0000 (11:26 +0800)
drivers/spi/spi-rockchip-core.c
drivers/spi/spi-rockchip-core.h
drivers/spi/spi-rockchip-dma.c
drivers/spi/spi-rockchip-test.c

index 87b1df613aee3129a641d27921225827ff25ace3..93cb1803d2af3e544ecfa06f7b1bdaa068528254 100755 (executable)
@@ -569,7 +569,7 @@ static void pump_transfers(unsigned long data)
        u32 speed = 0;
        u32 cr0 = 0;    
        u16 dma_ctrl = 0;
-
+       int i = 0;
 
        /* Get current state information */
        message = dws->cur_msg;
@@ -747,27 +747,38 @@ static void pump_transfers(unsigned long data)
                /* setup DMA related registers */
                if(dws->dma_mapped)
                {
+                       dws->dmatdlr = dws->n_bytes;
+                       dws->dmardlr = dws->n_bytes - 1;
+                       for(i=dws->n_bytes; i<=dws->fifo_len / 4; i++)
+                       {
+                               if((dws->len / dws->n_bytes) % i == 0)
+                               dws->dmatdlr = i;
+                       }
+
                        /* Set the interrupt mask, for poll mode just diable all int */
                        spi_mask_intr(dws, 0xff);               
                        if(dws->tx)
                        {
                                dma_ctrl |= SPI_DMACR_TX_ENABLE;                
-                               dw_writew(dws, SPIM_DMATDLR, 8);
+                               dw_writew(dws, SPIM_DMATDLR, dws->dmatdlr);
                                dw_writew(dws, SPIM_CTRLR1, dws->len-1);        
                        }
+
+                       dws->dmardlr = (dws->dmatdlr != dws->n_bytes)?(dws->dmatdlr-1):(dws->n_bytes-1);
                        
                        if (dws->rx)
                        {
                                dma_ctrl |= SPI_DMACR_RX_ENABLE;        
-                               dw_writew(dws, SPIM_DMARDLR, 0);                        
-                               dw_writew(dws, SPIM_CTRLR1, dws->len-1);        
+                               dw_writew(dws, SPIM_DMARDLR, dws->dmardlr);
+                               dw_writew(dws, SPIM_CTRLR1, dws->len-1);
                        }
                        dw_writew(dws, SPIM_DMACR, dma_ctrl);
 
-                       DBG_SPI("%s:dma_ctrl=0x%x\n",__func__,dw_readw(dws, SPIM_DMACR));
+                       DBG_SPI("%s:dma_ctrl=0x%x,dmatdlr=%d,dmardlr=%d\n",__func__,dw_readw(dws, SPIM_DMACR),dws->dmatdlr, dws->dmardlr);
                        
                }
-               
+
+               if((!dws->dma_mapped) || (dws->dma_mapped && dws->tx))
                spi_enable_chip(dws, 1);
 
                DBG_SPI("%s:ctrl0=0x%x\n",__func__,dw_readw(dws, SPIM_CTRLR0));
index 9fa458c13cd34a8ccde94719365b6491f1a7e6d5..bb07d58ba3e0111fff529e73647cd7ecb400e59c 100755 (executable)
@@ -179,6 +179,8 @@ struct dw_spi {
        u8                      n_bytes;        /* current is a 1/2 bytes op */
        u8                      max_bits_per_word;      /* maxim is 16b */
        u32                     dma_width;
+       int                     dmatdlr;
+       int                     dmardlr;
        int                     cs_change;
        void                    *tx_buffer;
        void                    *rx_buffer;
index 11468e04dbe311046e7a743ad63e8b558fbbe5f1..cbd613a0c62999d67736a28ba437641575174427 100755 (executable)
@@ -252,7 +252,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
                /* 2. Prepare the TX dma transfer */
                txconf.direction = DMA_MEM_TO_DEV;
                txconf.dst_addr = dws->tx_dma_addr;
-               txconf.dst_maxburst = dws->dma_width;
+               txconf.dst_maxburst = dws->dmatdlr;//dws->dma_width;
                //txconf.src_addr_width = width;
                txconf.dst_addr_width = width;
                //txconf.device_fc = false;
@@ -276,7 +276,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
                txdesc->callback = dw_spi_dma_txcb;
                txdesc->callback_param = dws;
 
-               DBG_SPI("%s:dst_addr=0x%p,tx_dma=0x%p,len=%d,burst=%d,width=%d\n",__func__,(int *)dws->tx_dma_addr, (int *)dws->tx_dma, dws->len,dws->dma_width, width);
+               DBG_SPI("%s:dst_addr=0x%p,tx_dma=0x%p,len=%d,burst=%d,width=%d\n",__func__,(int *)dws->tx_dma_addr, (int *)dws->tx_dma, dws->len,txconf.dst_maxburst, width);
        }
 
        if (dws->rx)
@@ -284,7 +284,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
                /* 3. Prepare the RX dma transfer */
                rxconf.direction = DMA_DEV_TO_MEM;
                rxconf.src_addr = dws->rx_dma_addr;
-               rxconf.src_maxburst = dws->dma_width; 
+               rxconf.src_maxburst = dws->dmardlr + 1;//dws->dma_width;
                //rxconf.dst_addr_width = width;
                rxconf.src_addr_width = width;
                //rxconf.device_fc = false;
@@ -307,8 +307,11 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
                rxdesc->callback = dw_spi_dma_rxcb;
                rxdesc->callback_param = dws;
                
-               DBG_SPI("%s:src_addr=0x%p,rx_dma=0x%p,len=%d,burst=%d,width=%d\n",__func__, (int *)dws->rx_dma_addr, (int *)dws->rx_dma, dws->len, dws->dma_width, width);
+               DBG_SPI("%s:src_addr=0x%p,rx_dma=0x%p,len=%d,burst=%d,width=%d\n",__func__, (int *)dws->rx_dma_addr, (int *)dws->rx_dma, dws->len, rxconf.src_maxburst, width);
        }
+
+       if(!dws->tx)
+       spi_enable_chip(dws, 1);
        
        /* rx must be started before tx due to spi instinct */  
        if (dws->rx)
index 19aa7a12b6b981dcfc736558a4d46e6e2ac3a538..58411e4279ace097f137797dcba55751952e8075 100755 (executable)
@@ -81,12 +81,14 @@ static ssize_t spi_test_write(struct file *file,
 \r
        spi = g_spi_test_data[nr]->spi;\r
 \r
-       for(i=0; i<100; i++)\r
+       for(i=0; i<5000; i++)\r
        {\r
                ret = spi_write(spi, txbuf, 256);\r
-               ret = spi_read(spi, rxbuf, 256);\r
-               ret = spi_write_then_read(spi,txbuf,256,rxbuf,256);             \r
-               ret = spi_write_and_read(spi,txbuf,rxbuf,256);\r
+               ret = spi_read(spi, rxbuf, 255);\r
+               ret = spi_write_then_read(spi,txbuf,254,rxbuf,253);\r
+               ret = spi_write_and_read(spi,txbuf,rxbuf,252);\r
+               ret = spi_write_and_read(spi,txbuf,rxbuf,251);\r
+               if(i%500==0)\r
                printk("%s:test %d times\n\n",__func__,i+1);\r
        }\r
        \r