aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-omap2-mcspi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
-rw-r--r--drivers/spi/spi-omap2-mcspi.c181
1 files changed, 150 insertions, 31 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 0c73dd4f43a0..9fdb7a9ae03f 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -20,6 +20,8 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * 21 *
22 */ 22 */
23#define USE_DMA_ENGINE_RX
24#define USE_DMA_ENGINE_TX
23 25
24#include <linux/kernel.h> 26#include <linux/kernel.h>
25#include <linux/init.h> 27#include <linux/init.h>
@@ -28,6 +30,8 @@
28#include <linux/device.h> 30#include <linux/device.h>
29#include <linux/delay.h> 31#include <linux/delay.h>
30#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/dmaengine.h>
34#include <linux/omap-dma.h>
31#include <linux/platform_device.h> 35#include <linux/platform_device.h>
32#include <linux/err.h> 36#include <linux/err.h>
33#include <linux/clk.h> 37#include <linux/clk.h>
@@ -93,6 +97,8 @@
93 97
94/* We have 2 DMA channels per CS, one for RX and one for TX */ 98/* We have 2 DMA channels per CS, one for RX and one for TX */
95struct omap2_mcspi_dma { 99struct omap2_mcspi_dma {
100 struct dma_chan *dma_tx;
101 struct dma_chan *dma_rx;
96 int dma_tx_channel; 102 int dma_tx_channel;
97 int dma_rx_channel; 103 int dma_rx_channel;
98 104
@@ -300,6 +306,30 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
300 return 0; 306 return 0;
301} 307}
302 308
309static void omap2_mcspi_rx_callback(void *data)
310{
311 struct spi_device *spi = data;
312 struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
313 struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
314
315 complete(&mcspi_dma->dma_rx_completion);
316
317 /* We must disable the DMA RX request */
318 omap2_mcspi_set_dma_req(spi, 1, 0);
319}
320
321static void omap2_mcspi_tx_callback(void *data)
322{
323 struct spi_device *spi = data;
324 struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
325 struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
326
327 complete(&mcspi_dma->dma_tx_completion);
328
329 /* We must disable the DMA TX request */
330 omap2_mcspi_set_dma_req(spi, 0, 0);
331}
332
303static unsigned 333static unsigned
304omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) 334omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
305{ 335{
@@ -314,6 +344,9 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
314 u8 * rx; 344 u8 * rx;
315 const u8 * tx; 345 const u8 * tx;
316 void __iomem *chstat_reg; 346 void __iomem *chstat_reg;
347 struct dma_slave_config cfg;
348 enum dma_slave_buswidth width;
349 unsigned es;
317 350
318 mcspi = spi_master_get_devdata(spi->master); 351 mcspi = spi_master_get_devdata(spi->master);
319 mcspi_dma = &mcspi->dma_channels[spi->chip_select]; 352 mcspi_dma = &mcspi->dma_channels[spi->chip_select];
@@ -321,6 +354,71 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
321 354
322 chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; 355 chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
323 356
357 if (cs->word_len <= 8) {
358 width = DMA_SLAVE_BUSWIDTH_1_BYTE;
359 es = 1;
360 } else if (cs->word_len <= 16) {
361 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
362 es = 2;
363 } else {
364 width = DMA_SLAVE_BUSWIDTH_4_BYTES;
365 es = 4;
366 }
367
368 memset(&cfg, 0, sizeof(cfg));
369 cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0;
370 cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0;
371 cfg.src_addr_width = width;
372 cfg.dst_addr_width = width;
373 cfg.src_maxburst = 1;
374 cfg.dst_maxburst = 1;
375
376 if (xfer->tx_buf && mcspi_dma->dma_tx) {
377 struct dma_async_tx_descriptor *tx;
378 struct scatterlist sg;
379
380 dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
381
382 sg_init_table(&sg, 1);
383 sg_dma_address(&sg) = xfer->tx_dma;
384 sg_dma_len(&sg) = xfer->len;
385
386 tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1,
387 DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
388 if (tx) {
389 tx->callback = omap2_mcspi_tx_callback;
390 tx->callback_param = spi;
391 dmaengine_submit(tx);
392 } else {
393 /* FIXME: fall back to PIO? */
394 }
395 }
396
397 if (xfer->rx_buf && mcspi_dma->dma_rx) {
398 struct dma_async_tx_descriptor *tx;
399 struct scatterlist sg;
400 size_t len = xfer->len - es;
401
402 dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
403
404 if (l & OMAP2_MCSPI_CHCONF_TURBO)
405 len -= es;
406
407 sg_init_table(&sg, 1);
408 sg_dma_address(&sg) = xfer->rx_dma;
409 sg_dma_len(&sg) = len;
410
411 tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1,
412 DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
413 if (tx) {
414 tx->callback = omap2_mcspi_rx_callback;
415 tx->callback_param = spi;
416 dmaengine_submit(tx);
417 } else {
418 /* FIXME: fall back to PIO? */
419 }
420 }
421
324 count = xfer->len; 422 count = xfer->len;
325 c = count; 423 c = count;
326 word_len = cs->word_len; 424 word_len = cs->word_len;
@@ -342,7 +440,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
342 element_count = count >> 2; 440 element_count = count >> 2;
343 } 441 }
344 442
345 if (tx != NULL) { 443 if (tx != NULL && mcspi_dma->dma_tx_channel != -1) {
346 omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel, 444 omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel,
347 data_type, element_count, 1, 445 data_type, element_count, 1,
348 OMAP_DMA_SYNC_ELEMENT, 446 OMAP_DMA_SYNC_ELEMENT,
@@ -357,7 +455,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
357 xfer->tx_dma, 0, 0); 455 xfer->tx_dma, 0, 0);
358 } 456 }
359 457
360 if (rx != NULL) { 458 if (rx != NULL && mcspi_dma->dma_rx_channel != -1) {
361 elements = element_count - 1; 459 elements = element_count - 1;
362 if (l & OMAP2_MCSPI_CHCONF_TURBO) 460 if (l & OMAP2_MCSPI_CHCONF_TURBO)
363 elements--; 461 elements--;
@@ -377,12 +475,18 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
377 } 475 }
378 476
379 if (tx != NULL) { 477 if (tx != NULL) {
380 omap_start_dma(mcspi_dma->dma_tx_channel); 478 if (mcspi_dma->dma_tx)
479 dma_async_issue_pending(mcspi_dma->dma_tx);
480 else
481 omap_start_dma(mcspi_dma->dma_tx_channel);
381 omap2_mcspi_set_dma_req(spi, 0, 1); 482 omap2_mcspi_set_dma_req(spi, 0, 1);
382 } 483 }
383 484
384 if (rx != NULL) { 485 if (rx != NULL) {
385 omap_start_dma(mcspi_dma->dma_rx_channel); 486 if (mcspi_dma->dma_rx)
487 dma_async_issue_pending(mcspi_dma->dma_rx);
488 else
489 omap_start_dma(mcspi_dma->dma_rx_channel);
386 omap2_mcspi_set_dma_req(spi, 1, 1); 490 omap2_mcspi_set_dma_req(spi, 1, 1);
387 } 491 }
388 492
@@ -406,7 +510,10 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
406 dma_unmap_single(&spi->dev, xfer->rx_dma, count, DMA_FROM_DEVICE); 510 dma_unmap_single(&spi->dev, xfer->rx_dma, count, DMA_FROM_DEVICE);
407 omap2_mcspi_set_enable(spi, 0); 511 omap2_mcspi_set_enable(spi, 0);
408 512
513 elements = element_count - 1;
514
409 if (l & OMAP2_MCSPI_CHCONF_TURBO) { 515 if (l & OMAP2_MCSPI_CHCONF_TURBO) {
516 elements--;
410 517
411 if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) 518 if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
412 & OMAP2_MCSPI_CHSTAT_RXS)) { 519 & OMAP2_MCSPI_CHSTAT_RXS)) {
@@ -725,32 +832,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
725 832
726static void omap2_mcspi_dma_rx_callback(int lch, u16 ch_status, void *data) 833static void omap2_mcspi_dma_rx_callback(int lch, u16 ch_status, void *data)
727{ 834{
728 struct spi_device *spi = data; 835 omap2_mcspi_rx_callback(data);
729 struct omap2_mcspi *mcspi;
730 struct omap2_mcspi_dma *mcspi_dma;
731
732 mcspi = spi_master_get_devdata(spi->master);
733 mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
734
735 complete(&mcspi_dma->dma_rx_completion);
736
737 /* We must disable the DMA RX request */
738 omap2_mcspi_set_dma_req(spi, 1, 0);
739} 836}
740 837
741static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data) 838static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data)
742{ 839{
743 struct spi_device *spi = data; 840 omap2_mcspi_tx_callback(data);
744 struct omap2_mcspi *mcspi;
745 struct omap2_mcspi_dma *mcspi_dma;
746
747 mcspi = spi_master_get_devdata(spi->master);
748 mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
749
750 complete(&mcspi_dma->dma_tx_completion);
751
752 /* We must disable the DMA TX request */
753 omap2_mcspi_set_dma_req(spi, 0, 0);
754} 841}
755 842
756static int omap2_mcspi_request_dma(struct spi_device *spi) 843static int omap2_mcspi_request_dma(struct spi_device *spi)
@@ -758,17 +845,43 @@ static int omap2_mcspi_request_dma(struct spi_device *spi)
758 struct spi_master *master = spi->master; 845 struct spi_master *master = spi->master;
759 struct omap2_mcspi *mcspi; 846 struct omap2_mcspi *mcspi;
760 struct omap2_mcspi_dma *mcspi_dma; 847 struct omap2_mcspi_dma *mcspi_dma;
848 dma_cap_mask_t mask;
849 unsigned sig;
761 850
762 mcspi = spi_master_get_devdata(master); 851 mcspi = spi_master_get_devdata(master);
763 mcspi_dma = mcspi->dma_channels + spi->chip_select; 852 mcspi_dma = mcspi->dma_channels + spi->chip_select;
764 853
854 init_completion(&mcspi_dma->dma_rx_completion);
855 init_completion(&mcspi_dma->dma_tx_completion);
856
857 dma_cap_zero(mask);
858 dma_cap_set(DMA_SLAVE, mask);
859#ifdef USE_DMA_ENGINE_RX
860 sig = mcspi_dma->dma_rx_sync_dev;
861 mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
862 if (!mcspi_dma->dma_rx) {
863 dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n");
864 return -EAGAIN;
865 }
866#else
765 if (omap_request_dma(mcspi_dma->dma_rx_sync_dev, "McSPI RX", 867 if (omap_request_dma(mcspi_dma->dma_rx_sync_dev, "McSPI RX",
766 omap2_mcspi_dma_rx_callback, spi, 868 omap2_mcspi_dma_rx_callback, spi,
767 &mcspi_dma->dma_rx_channel)) { 869 &mcspi_dma->dma_rx_channel)) {
768 dev_err(&spi->dev, "no RX DMA channel for McSPI\n"); 870 dev_err(&spi->dev, "no RX DMA channel for McSPI\n");
769 return -EAGAIN; 871 return -EAGAIN;
770 } 872 }
873#endif
771 874
875#ifdef USE_DMA_ENGINE_TX
876 sig = mcspi_dma->dma_tx_sync_dev;
877 mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
878 if (!mcspi_dma->dma_tx) {
879 dev_err(&spi->dev, "no TX DMA engine channel for McSPI\n");
880 dma_release_channel(mcspi_dma->dma_rx);
881 mcspi_dma->dma_rx = NULL;
882 return -EAGAIN;
883 }
884#else
772 if (omap_request_dma(mcspi_dma->dma_tx_sync_dev, "McSPI TX", 885 if (omap_request_dma(mcspi_dma->dma_tx_sync_dev, "McSPI TX",
773 omap2_mcspi_dma_tx_callback, spi, 886 omap2_mcspi_dma_tx_callback, spi,
774 &mcspi_dma->dma_tx_channel)) { 887 &mcspi_dma->dma_tx_channel)) {
@@ -777,9 +890,7 @@ static int omap2_mcspi_request_dma(struct spi_device *spi)
777 dev_err(&spi->dev, "no TX DMA channel for McSPI\n"); 890 dev_err(&spi->dev, "no TX DMA channel for McSPI\n");
778 return -EAGAIN; 891 return -EAGAIN;
779 } 892 }
780 893#endif
781 init_completion(&mcspi_dma->dma_rx_completion);
782 init_completion(&mcspi_dma->dma_tx_completion);
783 894
784 return 0; 895 return 0;
785} 896}
@@ -812,8 +923,8 @@ static int omap2_mcspi_setup(struct spi_device *spi)
812 list_add_tail(&cs->node, &ctx->cs); 923 list_add_tail(&cs->node, &ctx->cs);
813 } 924 }
814 925
815 if (mcspi_dma->dma_rx_channel == -1 926 if ((!mcspi_dma->dma_rx && mcspi_dma->dma_rx_channel == -1) ||
816 || mcspi_dma->dma_tx_channel == -1) { 927 (!mcspi_dma->dma_tx && mcspi_dma->dma_tx_channel == -1)) {
817 ret = omap2_mcspi_request_dma(spi); 928 ret = omap2_mcspi_request_dma(spi);
818 if (ret < 0) 929 if (ret < 0)
819 return ret; 930 return ret;
@@ -848,6 +959,14 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
848 if (spi->chip_select < spi->master->num_chipselect) { 959 if (spi->chip_select < spi->master->num_chipselect) {
849 mcspi_dma = &mcspi->dma_channels[spi->chip_select]; 960 mcspi_dma = &mcspi->dma_channels[spi->chip_select];
850 961
962 if (mcspi_dma->dma_rx) {
963 dma_release_channel(mcspi_dma->dma_rx);
964 mcspi_dma->dma_rx = NULL;
965 }
966 if (mcspi_dma->dma_tx) {
967 dma_release_channel(mcspi_dma->dma_tx);
968 mcspi_dma->dma_tx = NULL;
969 }
851 if (mcspi_dma->dma_rx_channel != -1) { 970 if (mcspi_dma->dma_rx_channel != -1) {
852 omap_free_dma(mcspi_dma->dma_rx_channel); 971 omap_free_dma(mcspi_dma->dma_rx_channel);
853 mcspi_dma->dma_rx_channel = -1; 972 mcspi_dma->dma_rx_channel = -1;