Commit 94554a9a01f80ae24db59b412bccb94258afe85e

Authored by Philip, Avinash
1 parent e5f3cf5b95
Exists in master

arm:omap:mcspi - DMA support has added for MCSPI

Support for DMA transmission on MCSPI added.
1. MCSPI TX and RX registers are not 256-bit aligned address, as
required for Constant address mode in DAM and SAM in EDMA, causing EDMA
error generation condition. With this commit SAM and DAM are set to
Increment address mode.
2. SPI uses EDMA AB synchronized mode for transmission and EDMA A
synchronized mode for reception, which can be used to handle large chunk
of data above 64KB with single EDMA completion interrupt.

Signed-off-by: Philip, Avinash <avinashphilip@ti.com>

Showing 1 changed file with 64 additions and 45 deletions Side-by-side Diff

drivers/spi/spi-omap2-mcspi.c
... ... @@ -40,6 +40,7 @@
40 40 #include <plat/dma.h>
41 41 #include <plat/clock.h>
42 42 #include <plat/mcspi.h>
  43 +#include <mach/edma.h>
43 44  
44 45 #define OMAP2_MCSPI_MAX_FREQ 48000000
45 46  
46 47  
... ... @@ -101,12 +102,13 @@
101 102  
102 103 struct completion dma_tx_completion;
103 104 struct completion dma_rx_completion;
  105 + int dummy_param_slot;
104 106 };
105 107  
106 108 /* use PIO for small transfers, avoiding DMA setup/teardown overhead and
107 109 * cache operations; better heuristics consider wordsize and bitrate.
108 110 */
109   -#define DMA_MIN_BYTES (4 * 1024 * 1024)
  111 +#define DMA_MIN_BYTES (160)
110 112  
111 113 struct omap2_mcspi {
112 114 struct work_struct work;
... ... @@ -302,6 +304,7 @@
302 304 u8 * rx;
303 305 const u8 * tx;
304 306 void __iomem *chstat_reg;
  307 + struct edmacc_param param;
305 308  
306 309 mcspi = spi_master_get_devdata(spi->master);
307 310 mcspi_dma = &mcspi->dma_channels[spi->chip_select];
308 311  
309 312  
310 313  
311 314  
312 315  
... ... @@ -331,37 +334,57 @@
331 334 }
332 335  
333 336 if (tx != NULL) {
334   - omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel,
335   - data_type, element_count, 1,
336   - OMAP_DMA_SYNC_ELEMENT,
337   - mcspi_dma->dma_tx_sync_dev, 0);
  337 + int a_cnt, b_cnt, c_cnt, b_cntrld;
338 338  
339   - omap_set_dma_dest_params(mcspi_dma->dma_tx_channel, 0,
340   - OMAP_DMA_AMODE_CONSTANT,
341   - tx_reg, 0, 0);
  339 + a_cnt = 1;
  340 + b_cnt = 1;
  341 + c_cnt = (element_count / a_cnt) / 256;
  342 + b_cntrld = SZ_64K - 1;
342 343  
343   - omap_set_dma_src_params(mcspi_dma->dma_tx_channel, 0,
344   - OMAP_DMA_AMODE_POST_INC,
345   - xfer->tx_dma, 0, 0);
  344 + param.opt = TCINTEN |
  345 + EDMA_TCC(mcspi_dma->dma_tx_channel) | SYNCDIM ;
  346 + param.src = xfer->tx_dma;
  347 + param.a_b_cnt = a_cnt | b_cnt << 16;
  348 + param.dst = tx_reg;
  349 + param.src_dst_bidx = a_cnt;
  350 + param.link_bcntrld = b_cntrld << 16;
  351 + param.src_dst_cidx = b_cnt;
  352 + param.ccnt = element_count;
  353 + edma_write_slot(mcspi_dma->dma_tx_channel, &param);
  354 + edma_link(mcspi_dma->dma_tx_channel,
  355 + mcspi_dma->dummy_param_slot);
346 356 }
347 357  
348 358 if (rx != NULL) {
  359 + int a_cnt, b_cnt, c_cnt, b_cntrld;
  360 +
  361 + a_cnt = 1;
  362 + c_cnt = (element_count / a_cnt) / (SZ_64K - 1);
  363 + b_cnt = element_count - c_cnt * (SZ_64K - 1);
  364 + b_cntrld = SZ_64K - 1;
  365 +
  366 + if (b_cnt)
  367 + c_cnt++;
  368 + else
  369 + b_cnt = SZ_64K - 1;
  370 +
349 371 elements = element_count - 1;
350 372 if (l & OMAP2_MCSPI_CHCONF_TURBO)
351 373 elements--;
352 374  
353   - omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel,
354   - data_type, elements, 1,
355   - OMAP_DMA_SYNC_ELEMENT,
356   - mcspi_dma->dma_rx_sync_dev, 1);
  375 + param.opt = TCINTEN |
  376 + EDMA_TCC(mcspi_dma->dma_rx_channel);
  377 + param.src = rx_reg;
  378 + param.a_b_cnt = a_cnt | b_cnt << 16;
  379 + param.dst = xfer->rx_dma;
  380 + param.src_dst_bidx = a_cnt << 16;
  381 + param.link_bcntrld = b_cntrld << 16;
  382 + param.src_dst_cidx = 1 << 16;
  383 + param.ccnt = c_cnt;
  384 + edma_write_slot(mcspi_dma->dma_rx_channel, &param);
  385 + edma_link(mcspi_dma->dma_rx_channel,
  386 + mcspi_dma->dummy_param_slot);
357 387  
358   - omap_set_dma_src_params(mcspi_dma->dma_rx_channel, 0,
359   - OMAP_DMA_AMODE_CONSTANT,
360   - rx_reg, 0, 0);
361   -
362   - omap_set_dma_dest_params(mcspi_dma->dma_rx_channel, 0,
363   - OMAP_DMA_AMODE_POST_INC,
364   - xfer->rx_dma, 0, 0);
365 388 }
366 389  
367 390 if (tx != NULL) {
... ... @@ -418,23 +441,6 @@
418 441 }
419 442 }
420 443  
421   - if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
422   - & OMAP2_MCSPI_CHSTAT_RXS)) {
423   - u32 w;
424   -
425   - w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0);
426   - if (word_len <= 8)
427   - ((u8 *)xfer->rx_buf)[elements] = w;
428   - else if (word_len <= 16)
429   - ((u16 *)xfer->rx_buf)[elements] = w;
430   - else /* word_len <= 32 */
431   - ((u32 *)xfer->rx_buf)[elements] = w;
432   - } else {
433   - dev_err(&spi->dev, "DMA RX last word empty");
434   - count -= (word_len <= 8) ? 1 :
435   - (word_len <= 16) ? 2 :
436   - /* word_len <= 32 */ 4;
437   - }
438 444 omap2_mcspi_set_enable(spi, 1);
439 445 }
440 446 return count;
441 447  
... ... @@ -717,13 +723,13 @@
717 723 struct omap2_mcspi *mcspi;
718 724 struct omap2_mcspi_dma *mcspi_dma;
719 725  
  726 + /* We must disable the DMA RX request */
  727 + omap2_mcspi_set_dma_req(spi, 1, 0);
720 728 mcspi = spi_master_get_devdata(spi->master);
721 729 mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
722 730  
723 731 complete(&mcspi_dma->dma_rx_completion);
724 732  
725   - /* We must disable the DMA RX request */
726   - omap2_mcspi_set_dma_req(spi, 1, 0);
727 733 }
728 734  
729 735 static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data)
730 736  
... ... @@ -732,13 +738,13 @@
732 738 struct omap2_mcspi *mcspi;
733 739 struct omap2_mcspi_dma *mcspi_dma;
734 740  
  741 + /* We must disable the DMA TX request */
  742 + omap2_mcspi_set_dma_req(spi, 0, 0);
735 743 mcspi = spi_master_get_devdata(spi->master);
736 744 mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
737 745  
738 746 complete(&mcspi_dma->dma_tx_completion);
739 747  
740   - /* We must disable the DMA TX request */
741   - omap2_mcspi_set_dma_req(spi, 0, 0);
742 748 }
743 749  
744 750 static int omap2_mcspi_request_dma(struct spi_device *spi)
... ... @@ -746,6 +752,7 @@
746 752 struct spi_master *master = spi->master;
747 753 struct omap2_mcspi *mcspi;
748 754 struct omap2_mcspi_dma *mcspi_dma;
  755 + int ret = 0;
749 756  
750 757 mcspi = spi_master_get_devdata(master);
751 758 mcspi_dma = mcspi->dma_channels + spi->chip_select;
... ... @@ -765,6 +772,18 @@
765 772 dev_err(&spi->dev, "no TX DMA channel for McSPI\n");
766 773 return -EAGAIN;
767 774 }
  775 + ret = edma_alloc_slot(EDMA_CTLR(mcspi_dma->dma_tx_channel),
  776 + EDMA_SLOT_ANY);
  777 +
  778 + if (ret < 0) {
  779 + pr_err("Unable to request SPI TX DMA param slot\n");
  780 + ret = -EAGAIN;
  781 + return ret;
  782 + }
  783 +
  784 + mcspi_dma->dummy_param_slot = ret;
  785 + edma_link(mcspi_dma->dummy_param_slot,
  786 + mcspi_dma->dummy_param_slot);
768 787  
769 788 init_completion(&mcspi_dma->dma_rx_completion);
770 789 init_completion(&mcspi_dma->dma_tx_completion);