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.c229
1 files changed, 127 insertions, 102 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 7d46b15e1520..bc4778175e34 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -28,6 +28,8 @@
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
31#include <linux/dmaengine.h>
32#include <linux/omap-dma.h>
31#include <linux/platform_device.h> 33#include <linux/platform_device.h>
32#include <linux/err.h> 34#include <linux/err.h>
33#include <linux/clk.h> 35#include <linux/clk.h>
@@ -39,7 +41,6 @@
39 41
40#include <linux/spi/spi.h> 42#include <linux/spi/spi.h>
41 43
42#include <plat/dma.h>
43#include <plat/clock.h> 44#include <plat/clock.h>
44#include <plat/mcspi.h> 45#include <plat/mcspi.h>
45 46
@@ -93,8 +94,8 @@
93 94
94/* We have 2 DMA channels per CS, one for RX and one for TX */ 95/* We have 2 DMA channels per CS, one for RX and one for TX */
95struct omap2_mcspi_dma { 96struct omap2_mcspi_dma {
96 int dma_tx_channel; 97 struct dma_chan *dma_tx;
97 int dma_rx_channel; 98 struct dma_chan *dma_rx;
98 99
99 int dma_tx_sync_dev; 100 int dma_tx_sync_dev;
100 int dma_rx_sync_dev; 101 int dma_rx_sync_dev;
@@ -300,20 +301,46 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
300 return 0; 301 return 0;
301} 302}
302 303
304static void omap2_mcspi_rx_callback(void *data)
305{
306 struct spi_device *spi = data;
307 struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
308 struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
309
310 complete(&mcspi_dma->dma_rx_completion);
311
312 /* We must disable the DMA RX request */
313 omap2_mcspi_set_dma_req(spi, 1, 0);
314}
315
316static void omap2_mcspi_tx_callback(void *data)
317{
318 struct spi_device *spi = data;
319 struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
320 struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
321
322 complete(&mcspi_dma->dma_tx_completion);
323
324 /* We must disable the DMA TX request */
325 omap2_mcspi_set_dma_req(spi, 0, 0);
326}
327
303static unsigned 328static unsigned
304omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) 329omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
305{ 330{
306 struct omap2_mcspi *mcspi; 331 struct omap2_mcspi *mcspi;
307 struct omap2_mcspi_cs *cs = spi->controller_state; 332 struct omap2_mcspi_cs *cs = spi->controller_state;
308 struct omap2_mcspi_dma *mcspi_dma; 333 struct omap2_mcspi_dma *mcspi_dma;
309 unsigned int count, c; 334 unsigned int count;
310 unsigned long base, tx_reg, rx_reg; 335 int word_len, element_count;
311 int word_len, data_type, element_count;
312 int elements = 0; 336 int elements = 0;
313 u32 l; 337 u32 l;
314 u8 * rx; 338 u8 * rx;
315 const u8 * tx; 339 const u8 * tx;
316 void __iomem *chstat_reg; 340 void __iomem *chstat_reg;
341 struct dma_slave_config cfg;
342 enum dma_slave_buswidth width;
343 unsigned es;
317 344
318 mcspi = spi_master_get_devdata(spi->master); 345 mcspi = spi_master_get_devdata(spi->master);
319 mcspi_dma = &mcspi->dma_channels[spi->chip_select]; 346 mcspi_dma = &mcspi->dma_channels[spi->chip_select];
@@ -321,68 +348,92 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
321 348
322 chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; 349 chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
323 350
351 if (cs->word_len <= 8) {
352 width = DMA_SLAVE_BUSWIDTH_1_BYTE;
353 es = 1;
354 } else if (cs->word_len <= 16) {
355 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
356 es = 2;
357 } else {
358 width = DMA_SLAVE_BUSWIDTH_4_BYTES;
359 es = 4;
360 }
361
362 memset(&cfg, 0, sizeof(cfg));
363 cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0;
364 cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0;
365 cfg.src_addr_width = width;
366 cfg.dst_addr_width = width;
367 cfg.src_maxburst = 1;
368 cfg.dst_maxburst = 1;
369
370 if (xfer->tx_buf && mcspi_dma->dma_tx) {
371 struct dma_async_tx_descriptor *tx;
372 struct scatterlist sg;
373
374 dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
375
376 sg_init_table(&sg, 1);
377 sg_dma_address(&sg) = xfer->tx_dma;
378 sg_dma_len(&sg) = xfer->len;
379
380 tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1,
381 DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
382 if (tx) {
383 tx->callback = omap2_mcspi_tx_callback;
384 tx->callback_param = spi;
385 dmaengine_submit(tx);
386 } else {
387 /* FIXME: fall back to PIO? */
388 }
389 }
390
391 if (xfer->rx_buf && mcspi_dma->dma_rx) {
392 struct dma_async_tx_descriptor *tx;
393 struct scatterlist sg;
394 size_t len = xfer->len - es;
395
396 dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
397
398 if (l & OMAP2_MCSPI_CHCONF_TURBO)
399 len -= es;
400
401 sg_init_table(&sg, 1);
402 sg_dma_address(&sg) = xfer->rx_dma;
403 sg_dma_len(&sg) = len;
404
405 tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1,
406 DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
407 if (tx) {
408 tx->callback = omap2_mcspi_rx_callback;
409 tx->callback_param = spi;
410 dmaengine_submit(tx);
411 } else {
412 /* FIXME: fall back to PIO? */
413 }
414 }
415
324 count = xfer->len; 416 count = xfer->len;
325 c = count;
326 word_len = cs->word_len; 417 word_len = cs->word_len;
327 418
328 base = cs->phys;
329 tx_reg = base + OMAP2_MCSPI_TX0;
330 rx_reg = base + OMAP2_MCSPI_RX0;
331 rx = xfer->rx_buf; 419 rx = xfer->rx_buf;
332 tx = xfer->tx_buf; 420 tx = xfer->tx_buf;
333 421
334 if (word_len <= 8) { 422 if (word_len <= 8) {
335 data_type = OMAP_DMA_DATA_TYPE_S8;
336 element_count = count; 423 element_count = count;
337 } else if (word_len <= 16) { 424 } else if (word_len <= 16) {
338 data_type = OMAP_DMA_DATA_TYPE_S16;
339 element_count = count >> 1; 425 element_count = count >> 1;
340 } else /* word_len <= 32 */ { 426 } else /* word_len <= 32 */ {
341 data_type = OMAP_DMA_DATA_TYPE_S32;
342 element_count = count >> 2; 427 element_count = count >> 2;
343 } 428 }
344 429
345 if (tx != NULL) { 430 if (tx != NULL) {
346 omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel, 431 dma_async_issue_pending(mcspi_dma->dma_tx);
347 data_type, element_count, 1,
348 OMAP_DMA_SYNC_ELEMENT,
349 mcspi_dma->dma_tx_sync_dev, 0);
350
351 omap_set_dma_dest_params(mcspi_dma->dma_tx_channel, 0,
352 OMAP_DMA_AMODE_CONSTANT,
353 tx_reg, 0, 0);
354
355 omap_set_dma_src_params(mcspi_dma->dma_tx_channel, 0,
356 OMAP_DMA_AMODE_POST_INC,
357 xfer->tx_dma, 0, 0);
358 }
359
360 if (rx != NULL) {
361 elements = element_count - 1;
362 if (l & OMAP2_MCSPI_CHCONF_TURBO)
363 elements--;
364
365 omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel,
366 data_type, elements, 1,
367 OMAP_DMA_SYNC_ELEMENT,
368 mcspi_dma->dma_rx_sync_dev, 1);
369
370 omap_set_dma_src_params(mcspi_dma->dma_rx_channel, 0,
371 OMAP_DMA_AMODE_CONSTANT,
372 rx_reg, 0, 0);
373
374 omap_set_dma_dest_params(mcspi_dma->dma_rx_channel, 0,
375 OMAP_DMA_AMODE_POST_INC,
376 xfer->rx_dma, 0, 0);
377 }
378
379 if (tx != NULL) {
380 omap_start_dma(mcspi_dma->dma_tx_channel);
381 omap2_mcspi_set_dma_req(spi, 0, 1); 432 omap2_mcspi_set_dma_req(spi, 0, 1);
382 } 433 }
383 434
384 if (rx != NULL) { 435 if (rx != NULL) {
385 omap_start_dma(mcspi_dma->dma_rx_channel); 436 dma_async_issue_pending(mcspi_dma->dma_rx);
386 omap2_mcspi_set_dma_req(spi, 1, 1); 437 omap2_mcspi_set_dma_req(spi, 1, 1);
387 } 438 }
388 439
@@ -408,7 +459,10 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
408 DMA_FROM_DEVICE); 459 DMA_FROM_DEVICE);
409 omap2_mcspi_set_enable(spi, 0); 460 omap2_mcspi_set_enable(spi, 0);
410 461
462 elements = element_count - 1;
463
411 if (l & OMAP2_MCSPI_CHCONF_TURBO) { 464 if (l & OMAP2_MCSPI_CHCONF_TURBO) {
465 elements--;
412 466
413 if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) 467 if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
414 & OMAP2_MCSPI_CHSTAT_RXS)) { 468 & OMAP2_MCSPI_CHSTAT_RXS)) {
@@ -725,64 +779,38 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
725 return 0; 779 return 0;
726} 780}
727 781
728static void omap2_mcspi_dma_rx_callback(int lch, u16 ch_status, void *data)
729{
730 struct spi_device *spi = data;
731 struct omap2_mcspi *mcspi;
732 struct omap2_mcspi_dma *mcspi_dma;
733
734 mcspi = spi_master_get_devdata(spi->master);
735 mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
736
737 complete(&mcspi_dma->dma_rx_completion);
738
739 /* We must disable the DMA RX request */
740 omap2_mcspi_set_dma_req(spi, 1, 0);
741}
742
743static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data)
744{
745 struct spi_device *spi = data;
746 struct omap2_mcspi *mcspi;
747 struct omap2_mcspi_dma *mcspi_dma;
748
749 mcspi = spi_master_get_devdata(spi->master);
750 mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
751
752 complete(&mcspi_dma->dma_tx_completion);
753
754 /* We must disable the DMA TX request */
755 omap2_mcspi_set_dma_req(spi, 0, 0);
756}
757
758static int omap2_mcspi_request_dma(struct spi_device *spi) 782static int omap2_mcspi_request_dma(struct spi_device *spi)
759{ 783{
760 struct spi_master *master = spi->master; 784 struct spi_master *master = spi->master;
761 struct omap2_mcspi *mcspi; 785 struct omap2_mcspi *mcspi;
762 struct omap2_mcspi_dma *mcspi_dma; 786 struct omap2_mcspi_dma *mcspi_dma;
787 dma_cap_mask_t mask;
788 unsigned sig;
763 789
764 mcspi = spi_master_get_devdata(master); 790 mcspi = spi_master_get_devdata(master);
765 mcspi_dma = mcspi->dma_channels + spi->chip_select; 791 mcspi_dma = mcspi->dma_channels + spi->chip_select;
766 792
767 if (omap_request_dma(mcspi_dma->dma_rx_sync_dev, "McSPI RX", 793 init_completion(&mcspi_dma->dma_rx_completion);
768 omap2_mcspi_dma_rx_callback, spi, 794 init_completion(&mcspi_dma->dma_tx_completion);
769 &mcspi_dma->dma_rx_channel)) { 795
770 dev_err(&spi->dev, "no RX DMA channel for McSPI\n"); 796 dma_cap_zero(mask);
797 dma_cap_set(DMA_SLAVE, mask);
798 sig = mcspi_dma->dma_rx_sync_dev;
799 mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
800 if (!mcspi_dma->dma_rx) {
801 dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n");
771 return -EAGAIN; 802 return -EAGAIN;
772 } 803 }
773 804
774 if (omap_request_dma(mcspi_dma->dma_tx_sync_dev, "McSPI TX", 805 sig = mcspi_dma->dma_tx_sync_dev;
775 omap2_mcspi_dma_tx_callback, spi, 806 mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
776 &mcspi_dma->dma_tx_channel)) { 807 if (!mcspi_dma->dma_tx) {
777 omap_free_dma(mcspi_dma->dma_rx_channel); 808 dev_err(&spi->dev, "no TX DMA engine channel for McSPI\n");
778 mcspi_dma->dma_rx_channel = -1; 809 dma_release_channel(mcspi_dma->dma_rx);
779 dev_err(&spi->dev, "no TX DMA channel for McSPI\n"); 810 mcspi_dma->dma_rx = NULL;
780 return -EAGAIN; 811 return -EAGAIN;
781 } 812 }
782 813
783 init_completion(&mcspi_dma->dma_rx_completion);
784 init_completion(&mcspi_dma->dma_tx_completion);
785
786 return 0; 814 return 0;
787} 815}
788 816
@@ -814,8 +842,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
814 list_add_tail(&cs->node, &ctx->cs); 842 list_add_tail(&cs->node, &ctx->cs);
815 } 843 }
816 844
817 if (mcspi_dma->dma_rx_channel == -1 845 if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) {
818 || mcspi_dma->dma_tx_channel == -1) {
819 ret = omap2_mcspi_request_dma(spi); 846 ret = omap2_mcspi_request_dma(spi);
820 if (ret < 0) 847 if (ret < 0)
821 return ret; 848 return ret;
@@ -850,13 +877,13 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
850 if (spi->chip_select < spi->master->num_chipselect) { 877 if (spi->chip_select < spi->master->num_chipselect) {
851 mcspi_dma = &mcspi->dma_channels[spi->chip_select]; 878 mcspi_dma = &mcspi->dma_channels[spi->chip_select];
852 879
853 if (mcspi_dma->dma_rx_channel != -1) { 880 if (mcspi_dma->dma_rx) {
854 omap_free_dma(mcspi_dma->dma_rx_channel); 881 dma_release_channel(mcspi_dma->dma_rx);
855 mcspi_dma->dma_rx_channel = -1; 882 mcspi_dma->dma_rx = NULL;
856 } 883 }
857 if (mcspi_dma->dma_tx_channel != -1) { 884 if (mcspi_dma->dma_tx) {
858 omap_free_dma(mcspi_dma->dma_tx_channel); 885 dma_release_channel(mcspi_dma->dma_tx);
859 mcspi_dma->dma_tx_channel = -1; 886 mcspi_dma->dma_tx = NULL;
860 } 887 }
861 } 888 }
862} 889}
@@ -1176,7 +1203,6 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
1176 break; 1203 break;
1177 } 1204 }
1178 1205
1179 mcspi->dma_channels[i].dma_rx_channel = -1;
1180 mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; 1206 mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start;
1181 sprintf(dma_ch_name, "tx%d", i); 1207 sprintf(dma_ch_name, "tx%d", i);
1182 dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, 1208 dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
@@ -1187,7 +1213,6 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
1187 break; 1213 break;
1188 } 1214 }
1189 1215
1190 mcspi->dma_channels[i].dma_tx_channel = -1;
1191 mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; 1216 mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;
1192 } 1217 }
1193 1218