diff options
| -rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 104 |
1 files changed, 5 insertions, 99 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 9fdb7a9ae03f..26a99ae9a599 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
| @@ -20,8 +20,6 @@ | |||
| 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 | ||
| 25 | 23 | ||
| 26 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
| 27 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| @@ -43,7 +41,6 @@ | |||
| 43 | 41 | ||
| 44 | #include <linux/spi/spi.h> | 42 | #include <linux/spi/spi.h> |
| 45 | 43 | ||
| 46 | #include <plat/dma.h> | ||
| 47 | #include <plat/clock.h> | 44 | #include <plat/clock.h> |
| 48 | #include <plat/mcspi.h> | 45 | #include <plat/mcspi.h> |
| 49 | 46 | ||
| @@ -99,8 +96,6 @@ | |||
| 99 | struct omap2_mcspi_dma { | 96 | struct omap2_mcspi_dma { |
| 100 | struct dma_chan *dma_tx; | 97 | struct dma_chan *dma_tx; |
| 101 | struct dma_chan *dma_rx; | 98 | struct dma_chan *dma_rx; |
| 102 | int dma_tx_channel; | ||
| 103 | int dma_rx_channel; | ||
| 104 | 99 | ||
| 105 | int dma_tx_sync_dev; | 100 | int dma_tx_sync_dev; |
| 106 | int dma_rx_sync_dev; | 101 | int dma_rx_sync_dev; |
| @@ -336,9 +331,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
| 336 | struct omap2_mcspi *mcspi; | 331 | struct omap2_mcspi *mcspi; |
| 337 | struct omap2_mcspi_cs *cs = spi->controller_state; | 332 | struct omap2_mcspi_cs *cs = spi->controller_state; |
| 338 | struct omap2_mcspi_dma *mcspi_dma; | 333 | struct omap2_mcspi_dma *mcspi_dma; |
| 339 | unsigned int count, c; | 334 | unsigned int count; |
| 340 | unsigned long base, tx_reg, rx_reg; | 335 | int word_len, element_count; |
| 341 | int word_len, data_type, element_count; | ||
| 342 | int elements = 0; | 336 | int elements = 0; |
| 343 | u32 l; | 337 | u32 l; |
| 344 | u8 * rx; | 338 | u8 * rx; |
| @@ -420,73 +414,26 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
| 420 | } | 414 | } |
| 421 | 415 | ||
| 422 | count = xfer->len; | 416 | count = xfer->len; |
| 423 | c = count; | ||
| 424 | word_len = cs->word_len; | 417 | word_len = cs->word_len; |
| 425 | 418 | ||
| 426 | base = cs->phys; | ||
| 427 | tx_reg = base + OMAP2_MCSPI_TX0; | ||
| 428 | rx_reg = base + OMAP2_MCSPI_RX0; | ||
| 429 | rx = xfer->rx_buf; | 419 | rx = xfer->rx_buf; |
| 430 | tx = xfer->tx_buf; | 420 | tx = xfer->tx_buf; |
| 431 | 421 | ||
| 432 | if (word_len <= 8) { | 422 | if (word_len <= 8) { |
| 433 | data_type = OMAP_DMA_DATA_TYPE_S8; | ||
| 434 | element_count = count; | 423 | element_count = count; |
| 435 | } else if (word_len <= 16) { | 424 | } else if (word_len <= 16) { |
| 436 | data_type = OMAP_DMA_DATA_TYPE_S16; | ||
| 437 | element_count = count >> 1; | 425 | element_count = count >> 1; |
| 438 | } else /* word_len <= 32 */ { | 426 | } else /* word_len <= 32 */ { |
| 439 | data_type = OMAP_DMA_DATA_TYPE_S32; | ||
| 440 | element_count = count >> 2; | 427 | element_count = count >> 2; |
| 441 | } | 428 | } |
| 442 | 429 | ||
| 443 | if (tx != NULL && mcspi_dma->dma_tx_channel != -1) { | ||
| 444 | omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel, | ||
| 445 | data_type, element_count, 1, | ||
| 446 | OMAP_DMA_SYNC_ELEMENT, | ||
| 447 | mcspi_dma->dma_tx_sync_dev, 0); | ||
| 448 | |||
| 449 | omap_set_dma_dest_params(mcspi_dma->dma_tx_channel, 0, | ||
| 450 | OMAP_DMA_AMODE_CONSTANT, | ||
| 451 | tx_reg, 0, 0); | ||
| 452 | |||
| 453 | omap_set_dma_src_params(mcspi_dma->dma_tx_channel, 0, | ||
| 454 | OMAP_DMA_AMODE_POST_INC, | ||
| 455 | xfer->tx_dma, 0, 0); | ||
| 456 | } | ||
| 457 | |||
| 458 | if (rx != NULL && mcspi_dma->dma_rx_channel != -1) { | ||
| 459 | elements = element_count - 1; | ||
| 460 | if (l & OMAP2_MCSPI_CHCONF_TURBO) | ||
| 461 | elements--; | ||
| 462 | |||
| 463 | omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel, | ||
| 464 | data_type, elements, 1, | ||
| 465 | OMAP_DMA_SYNC_ELEMENT, | ||
| 466 | mcspi_dma->dma_rx_sync_dev, 1); | ||
| 467 | |||
| 468 | omap_set_dma_src_params(mcspi_dma->dma_rx_channel, 0, | ||
| 469 | OMAP_DMA_AMODE_CONSTANT, | ||
| 470 | rx_reg, 0, 0); | ||
| 471 | |||
| 472 | omap_set_dma_dest_params(mcspi_dma->dma_rx_channel, 0, | ||
| 473 | OMAP_DMA_AMODE_POST_INC, | ||
| 474 | xfer->rx_dma, 0, 0); | ||
| 475 | } | ||
| 476 | |||
| 477 | if (tx != NULL) { | 430 | if (tx != NULL) { |
| 478 | if (mcspi_dma->dma_tx) | 431 | dma_async_issue_pending(mcspi_dma->dma_tx); |
| 479 | dma_async_issue_pending(mcspi_dma->dma_tx); | ||
| 480 | else | ||
| 481 | omap_start_dma(mcspi_dma->dma_tx_channel); | ||
| 482 | omap2_mcspi_set_dma_req(spi, 0, 1); | 432 | omap2_mcspi_set_dma_req(spi, 0, 1); |
| 483 | } | 433 | } |
| 484 | 434 | ||
| 485 | if (rx != NULL) { | 435 | if (rx != NULL) { |
| 486 | if (mcspi_dma->dma_rx) | 436 | dma_async_issue_pending(mcspi_dma->dma_rx); |
| 487 | dma_async_issue_pending(mcspi_dma->dma_rx); | ||
| 488 | else | ||
| 489 | omap_start_dma(mcspi_dma->dma_rx_channel); | ||
| 490 | omap2_mcspi_set_dma_req(spi, 1, 1); | 437 | omap2_mcspi_set_dma_req(spi, 1, 1); |
| 491 | } | 438 | } |
| 492 | 439 | ||
| @@ -830,16 +777,6 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
| 830 | return 0; | 777 | return 0; |
| 831 | } | 778 | } |
| 832 | 779 | ||
| 833 | static void omap2_mcspi_dma_rx_callback(int lch, u16 ch_status, void *data) | ||
| 834 | { | ||
| 835 | omap2_mcspi_rx_callback(data); | ||
| 836 | } | ||
| 837 | |||
| 838 | static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data) | ||
| 839 | { | ||
| 840 | omap2_mcspi_tx_callback(data); | ||
| 841 | } | ||
| 842 | |||
| 843 | static int omap2_mcspi_request_dma(struct spi_device *spi) | 780 | static int omap2_mcspi_request_dma(struct spi_device *spi) |
| 844 | { | 781 | { |
| 845 | struct spi_master *master = spi->master; | 782 | struct spi_master *master = spi->master; |
| @@ -856,23 +793,13 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) | |||
| 856 | 793 | ||
| 857 | dma_cap_zero(mask); | 794 | dma_cap_zero(mask); |
| 858 | dma_cap_set(DMA_SLAVE, mask); | 795 | dma_cap_set(DMA_SLAVE, mask); |
| 859 | #ifdef USE_DMA_ENGINE_RX | ||
| 860 | sig = mcspi_dma->dma_rx_sync_dev; | 796 | sig = mcspi_dma->dma_rx_sync_dev; |
| 861 | mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig); | 797 | mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig); |
| 862 | if (!mcspi_dma->dma_rx) { | 798 | if (!mcspi_dma->dma_rx) { |
| 863 | dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n"); | 799 | dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n"); |
| 864 | return -EAGAIN; | 800 | return -EAGAIN; |
| 865 | } | 801 | } |
| 866 | #else | ||
| 867 | if (omap_request_dma(mcspi_dma->dma_rx_sync_dev, "McSPI RX", | ||
| 868 | omap2_mcspi_dma_rx_callback, spi, | ||
| 869 | &mcspi_dma->dma_rx_channel)) { | ||
| 870 | dev_err(&spi->dev, "no RX DMA channel for McSPI\n"); | ||
| 871 | return -EAGAIN; | ||
| 872 | } | ||
| 873 | #endif | ||
| 874 | 802 | ||
| 875 | #ifdef USE_DMA_ENGINE_TX | ||
| 876 | sig = mcspi_dma->dma_tx_sync_dev; | 803 | sig = mcspi_dma->dma_tx_sync_dev; |
| 877 | mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig); | 804 | mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig); |
| 878 | if (!mcspi_dma->dma_tx) { | 805 | if (!mcspi_dma->dma_tx) { |
| @@ -881,16 +808,6 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) | |||
| 881 | mcspi_dma->dma_rx = NULL; | 808 | mcspi_dma->dma_rx = NULL; |
| 882 | return -EAGAIN; | 809 | return -EAGAIN; |
| 883 | } | 810 | } |
| 884 | #else | ||
| 885 | if (omap_request_dma(mcspi_dma->dma_tx_sync_dev, "McSPI TX", | ||
| 886 | omap2_mcspi_dma_tx_callback, spi, | ||
| 887 | &mcspi_dma->dma_tx_channel)) { | ||
| 888 | omap_free_dma(mcspi_dma->dma_rx_channel); | ||
| 889 | mcspi_dma->dma_rx_channel = -1; | ||
| 890 | dev_err(&spi->dev, "no TX DMA channel for McSPI\n"); | ||
| 891 | return -EAGAIN; | ||
| 892 | } | ||
| 893 | #endif | ||
| 894 | 811 | ||
| 895 | return 0; | 812 | return 0; |
| 896 | } | 813 | } |
| @@ -923,8 +840,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
| 923 | list_add_tail(&cs->node, &ctx->cs); | 840 | list_add_tail(&cs->node, &ctx->cs); |
| 924 | } | 841 | } |
| 925 | 842 | ||
| 926 | if ((!mcspi_dma->dma_rx && mcspi_dma->dma_rx_channel == -1) || | 843 | if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) { |
| 927 | (!mcspi_dma->dma_tx && mcspi_dma->dma_tx_channel == -1)) { | ||
| 928 | ret = omap2_mcspi_request_dma(spi); | 844 | ret = omap2_mcspi_request_dma(spi); |
| 929 | if (ret < 0) | 845 | if (ret < 0) |
| 930 | return ret; | 846 | return ret; |
| @@ -967,14 +883,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
| 967 | dma_release_channel(mcspi_dma->dma_tx); | 883 | dma_release_channel(mcspi_dma->dma_tx); |
| 968 | mcspi_dma->dma_tx = NULL; | 884 | mcspi_dma->dma_tx = NULL; |
| 969 | } | 885 | } |
| 970 | if (mcspi_dma->dma_rx_channel != -1) { | ||
| 971 | omap_free_dma(mcspi_dma->dma_rx_channel); | ||
| 972 | mcspi_dma->dma_rx_channel = -1; | ||
| 973 | } | ||
| 974 | if (mcspi_dma->dma_tx_channel != -1) { | ||
| 975 | omap_free_dma(mcspi_dma->dma_tx_channel); | ||
| 976 | mcspi_dma->dma_tx_channel = -1; | ||
| 977 | } | ||
| 978 | } | 886 | } |
| 979 | } | 887 | } |
| 980 | 888 | ||
| @@ -1293,7 +1201,6 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
| 1293 | break; | 1201 | break; |
| 1294 | } | 1202 | } |
| 1295 | 1203 | ||
| 1296 | mcspi->dma_channels[i].dma_rx_channel = -1; | ||
| 1297 | mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; | 1204 | mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; |
| 1298 | sprintf(dma_ch_name, "tx%d", i); | 1205 | sprintf(dma_ch_name, "tx%d", i); |
| 1299 | dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, | 1206 | dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, |
| @@ -1304,7 +1211,6 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
| 1304 | break; | 1211 | break; |
| 1305 | } | 1212 | } |
| 1306 | 1213 | ||
| 1307 | mcspi->dma_channels[i].dma_tx_channel = -1; | ||
| 1308 | mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; | 1214 | mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; |
| 1309 | } | 1215 | } |
| 1310 | 1216 | ||
