diff options
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 147 |
1 files changed, 130 insertions, 17 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 5a93a0df551f..6802806d1f18 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -38,12 +38,15 @@ | |||
38 | #include <linux/pm_runtime.h> | 38 | #include <linux/pm_runtime.h> |
39 | #include <linux/of.h> | 39 | #include <linux/of.h> |
40 | #include <linux/of_device.h> | 40 | #include <linux/of_device.h> |
41 | #include <linux/gcd.h> | ||
41 | 42 | ||
42 | #include <linux/spi/spi.h> | 43 | #include <linux/spi/spi.h> |
43 | 44 | ||
44 | #include <linux/platform_data/spi-omap2-mcspi.h> | 45 | #include <linux/platform_data/spi-omap2-mcspi.h> |
45 | 46 | ||
46 | #define OMAP2_MCSPI_MAX_FREQ 48000000 | 47 | #define OMAP2_MCSPI_MAX_FREQ 48000000 |
48 | #define OMAP2_MCSPI_MAX_FIFODEPTH 64 | ||
49 | #define OMAP2_MCSPI_MAX_FIFOWCNT 0xFFFF | ||
47 | #define SPI_AUTOSUSPEND_TIMEOUT 2000 | 50 | #define SPI_AUTOSUSPEND_TIMEOUT 2000 |
48 | 51 | ||
49 | #define OMAP2_MCSPI_REVISION 0x00 | 52 | #define OMAP2_MCSPI_REVISION 0x00 |
@@ -53,6 +56,7 @@ | |||
53 | #define OMAP2_MCSPI_WAKEUPENABLE 0x20 | 56 | #define OMAP2_MCSPI_WAKEUPENABLE 0x20 |
54 | #define OMAP2_MCSPI_SYST 0x24 | 57 | #define OMAP2_MCSPI_SYST 0x24 |
55 | #define OMAP2_MCSPI_MODULCTRL 0x28 | 58 | #define OMAP2_MCSPI_MODULCTRL 0x28 |
59 | #define OMAP2_MCSPI_XFERLEVEL 0x7c | ||
56 | 60 | ||
57 | /* per-channel banks, 0x14 bytes each, first is: */ | 61 | /* per-channel banks, 0x14 bytes each, first is: */ |
58 | #define OMAP2_MCSPI_CHCONF0 0x2c | 62 | #define OMAP2_MCSPI_CHCONF0 0x2c |
@@ -62,6 +66,7 @@ | |||
62 | #define OMAP2_MCSPI_RX0 0x3c | 66 | #define OMAP2_MCSPI_RX0 0x3c |
63 | 67 | ||
64 | /* per-register bitmasks: */ | 68 | /* per-register bitmasks: */ |
69 | #define OMAP2_MCSPI_IRQSTATUS_EOW BIT(17) | ||
65 | 70 | ||
66 | #define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0) | 71 | #define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0) |
67 | #define OMAP2_MCSPI_MODULCTRL_MS BIT(2) | 72 | #define OMAP2_MCSPI_MODULCTRL_MS BIT(2) |
@@ -82,10 +87,13 @@ | |||
82 | #define OMAP2_MCSPI_CHCONF_IS BIT(18) | 87 | #define OMAP2_MCSPI_CHCONF_IS BIT(18) |
83 | #define OMAP2_MCSPI_CHCONF_TURBO BIT(19) | 88 | #define OMAP2_MCSPI_CHCONF_TURBO BIT(19) |
84 | #define OMAP2_MCSPI_CHCONF_FORCE BIT(20) | 89 | #define OMAP2_MCSPI_CHCONF_FORCE BIT(20) |
90 | #define OMAP2_MCSPI_CHCONF_FFET BIT(27) | ||
91 | #define OMAP2_MCSPI_CHCONF_FFER BIT(28) | ||
85 | 92 | ||
86 | #define OMAP2_MCSPI_CHSTAT_RXS BIT(0) | 93 | #define OMAP2_MCSPI_CHSTAT_RXS BIT(0) |
87 | #define OMAP2_MCSPI_CHSTAT_TXS BIT(1) | 94 | #define OMAP2_MCSPI_CHSTAT_TXS BIT(1) |
88 | #define OMAP2_MCSPI_CHSTAT_EOT BIT(2) | 95 | #define OMAP2_MCSPI_CHSTAT_EOT BIT(2) |
96 | #define OMAP2_MCSPI_CHSTAT_TXFFE BIT(3) | ||
89 | 97 | ||
90 | #define OMAP2_MCSPI_CHCTRL_EN BIT(0) | 98 | #define OMAP2_MCSPI_CHCTRL_EN BIT(0) |
91 | 99 | ||
@@ -128,6 +136,7 @@ struct omap2_mcspi { | |||
128 | struct omap2_mcspi_dma *dma_channels; | 136 | struct omap2_mcspi_dma *dma_channels; |
129 | struct device *dev; | 137 | struct device *dev; |
130 | struct omap2_mcspi_regs ctx; | 138 | struct omap2_mcspi_regs ctx; |
139 | int fifo_depth; | ||
131 | unsigned int pin_dir:1; | 140 | unsigned int pin_dir:1; |
132 | }; | 141 | }; |
133 | 142 | ||
@@ -257,6 +266,58 @@ static void omap2_mcspi_set_master_mode(struct spi_master *master) | |||
257 | ctx->modulctrl = l; | 266 | ctx->modulctrl = l; |
258 | } | 267 | } |
259 | 268 | ||
269 | static void omap2_mcspi_set_fifo(const struct spi_device *spi, | ||
270 | struct spi_transfer *t, int enable) | ||
271 | { | ||
272 | struct spi_master *master = spi->master; | ||
273 | struct omap2_mcspi_cs *cs = spi->controller_state; | ||
274 | struct omap2_mcspi *mcspi; | ||
275 | unsigned int wcnt; | ||
276 | int fifo_depth, bytes_per_word; | ||
277 | u32 chconf, xferlevel; | ||
278 | |||
279 | mcspi = spi_master_get_devdata(master); | ||
280 | |||
281 | chconf = mcspi_cached_chconf0(spi); | ||
282 | if (enable) { | ||
283 | bytes_per_word = mcspi_bytes_per_word(cs->word_len); | ||
284 | if (t->len % bytes_per_word != 0) | ||
285 | goto disable_fifo; | ||
286 | |||
287 | fifo_depth = gcd(t->len, OMAP2_MCSPI_MAX_FIFODEPTH); | ||
288 | if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0) | ||
289 | goto disable_fifo; | ||
290 | |||
291 | wcnt = t->len / bytes_per_word; | ||
292 | if (wcnt > OMAP2_MCSPI_MAX_FIFOWCNT) | ||
293 | goto disable_fifo; | ||
294 | |||
295 | xferlevel = wcnt << 16; | ||
296 | if (t->rx_buf != NULL) { | ||
297 | chconf |= OMAP2_MCSPI_CHCONF_FFER; | ||
298 | xferlevel |= (fifo_depth - 1) << 8; | ||
299 | } else { | ||
300 | chconf |= OMAP2_MCSPI_CHCONF_FFET; | ||
301 | xferlevel |= fifo_depth - 1; | ||
302 | } | ||
303 | |||
304 | mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, xferlevel); | ||
305 | mcspi_write_chconf0(spi, chconf); | ||
306 | mcspi->fifo_depth = fifo_depth; | ||
307 | |||
308 | return; | ||
309 | } | ||
310 | |||
311 | disable_fifo: | ||
312 | if (t->rx_buf != NULL) | ||
313 | chconf &= ~OMAP2_MCSPI_CHCONF_FFER; | ||
314 | else | ||
315 | chconf &= ~OMAP2_MCSPI_CHCONF_FFET; | ||
316 | |||
317 | mcspi_write_chconf0(spi, chconf); | ||
318 | mcspi->fifo_depth = 0; | ||
319 | } | ||
320 | |||
260 | static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) | 321 | static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) |
261 | { | 322 | { |
262 | struct spi_master *spi_cntrl = mcspi->master; | 323 | struct spi_master *spi_cntrl = mcspi->master; |
@@ -373,7 +434,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
373 | { | 434 | { |
374 | struct omap2_mcspi *mcspi; | 435 | struct omap2_mcspi *mcspi; |
375 | struct omap2_mcspi_dma *mcspi_dma; | 436 | struct omap2_mcspi_dma *mcspi_dma; |
376 | unsigned int count; | 437 | unsigned int count, dma_count; |
377 | u32 l; | 438 | u32 l; |
378 | int elements = 0; | 439 | int elements = 0; |
379 | int word_len, element_count; | 440 | int word_len, element_count; |
@@ -381,6 +442,11 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
381 | mcspi = spi_master_get_devdata(spi->master); | 442 | mcspi = spi_master_get_devdata(spi->master); |
382 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 443 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
383 | count = xfer->len; | 444 | count = xfer->len; |
445 | dma_count = xfer->len; | ||
446 | |||
447 | if (mcspi->fifo_depth == 0) | ||
448 | dma_count -= es; | ||
449 | |||
384 | word_len = cs->word_len; | 450 | word_len = cs->word_len; |
385 | l = mcspi_cached_chconf0(spi); | 451 | l = mcspi_cached_chconf0(spi); |
386 | 452 | ||
@@ -394,16 +460,15 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
394 | if (mcspi_dma->dma_rx) { | 460 | if (mcspi_dma->dma_rx) { |
395 | struct dma_async_tx_descriptor *tx; | 461 | struct dma_async_tx_descriptor *tx; |
396 | struct scatterlist sg; | 462 | struct scatterlist sg; |
397 | size_t len = xfer->len - es; | ||
398 | 463 | ||
399 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); | 464 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); |
400 | 465 | ||
401 | if (l & OMAP2_MCSPI_CHCONF_TURBO) | 466 | if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0) |
402 | len -= es; | 467 | dma_count -= es; |
403 | 468 | ||
404 | sg_init_table(&sg, 1); | 469 | sg_init_table(&sg, 1); |
405 | sg_dma_address(&sg) = xfer->rx_dma; | 470 | sg_dma_address(&sg) = xfer->rx_dma; |
406 | sg_dma_len(&sg) = len; | 471 | sg_dma_len(&sg) = dma_count; |
407 | 472 | ||
408 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, | 473 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, |
409 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | | 474 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | |
@@ -423,6 +488,10 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
423 | wait_for_completion(&mcspi_dma->dma_rx_completion); | 488 | wait_for_completion(&mcspi_dma->dma_rx_completion); |
424 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, | 489 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, |
425 | DMA_FROM_DEVICE); | 490 | DMA_FROM_DEVICE); |
491 | |||
492 | if (mcspi->fifo_depth > 0) | ||
493 | return count; | ||
494 | |||
426 | omap2_mcspi_set_enable(spi, 0); | 495 | omap2_mcspi_set_enable(spi, 0); |
427 | 496 | ||
428 | elements = element_count - 1; | 497 | elements = element_count - 1; |
@@ -481,7 +550,10 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
481 | struct dma_slave_config cfg; | 550 | struct dma_slave_config cfg; |
482 | enum dma_slave_buswidth width; | 551 | enum dma_slave_buswidth width; |
483 | unsigned es; | 552 | unsigned es; |
553 | u32 burst; | ||
484 | void __iomem *chstat_reg; | 554 | void __iomem *chstat_reg; |
555 | void __iomem *irqstat_reg; | ||
556 | int wait_res; | ||
485 | 557 | ||
486 | mcspi = spi_master_get_devdata(spi->master); | 558 | mcspi = spi_master_get_devdata(spi->master); |
487 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 559 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
@@ -499,19 +571,27 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
499 | es = 4; | 571 | es = 4; |
500 | } | 572 | } |
501 | 573 | ||
574 | count = xfer->len; | ||
575 | burst = 1; | ||
576 | |||
577 | if (mcspi->fifo_depth > 0) { | ||
578 | if (count > mcspi->fifo_depth) | ||
579 | burst = mcspi->fifo_depth / es; | ||
580 | else | ||
581 | burst = count / es; | ||
582 | } | ||
583 | |||
502 | memset(&cfg, 0, sizeof(cfg)); | 584 | memset(&cfg, 0, sizeof(cfg)); |
503 | cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0; | 585 | cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0; |
504 | cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0; | 586 | cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0; |
505 | cfg.src_addr_width = width; | 587 | cfg.src_addr_width = width; |
506 | cfg.dst_addr_width = width; | 588 | cfg.dst_addr_width = width; |
507 | cfg.src_maxburst = 1; | 589 | cfg.src_maxburst = burst; |
508 | cfg.dst_maxburst = 1; | 590 | cfg.dst_maxburst = burst; |
509 | 591 | ||
510 | rx = xfer->rx_buf; | 592 | rx = xfer->rx_buf; |
511 | tx = xfer->tx_buf; | 593 | tx = xfer->tx_buf; |
512 | 594 | ||
513 | count = xfer->len; | ||
514 | |||
515 | if (tx != NULL) | 595 | if (tx != NULL) |
516 | omap2_mcspi_tx_dma(spi, xfer, cfg); | 596 | omap2_mcspi_tx_dma(spi, xfer, cfg); |
517 | 597 | ||
@@ -519,18 +599,38 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
519 | count = omap2_mcspi_rx_dma(spi, xfer, cfg, es); | 599 | count = omap2_mcspi_rx_dma(spi, xfer, cfg, es); |
520 | 600 | ||
521 | if (tx != NULL) { | 601 | if (tx != NULL) { |
522 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; | ||
523 | wait_for_completion(&mcspi_dma->dma_tx_completion); | 602 | wait_for_completion(&mcspi_dma->dma_tx_completion); |
524 | dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len, | 603 | dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len, |
525 | DMA_TO_DEVICE); | 604 | DMA_TO_DEVICE); |
526 | 605 | ||
606 | if (mcspi->fifo_depth > 0) { | ||
607 | irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS; | ||
608 | |||
609 | if (mcspi_wait_for_reg_bit(irqstat_reg, | ||
610 | OMAP2_MCSPI_IRQSTATUS_EOW) < 0) | ||
611 | dev_err(&spi->dev, "EOW timed out\n"); | ||
612 | |||
613 | mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS, | ||
614 | OMAP2_MCSPI_IRQSTATUS_EOW); | ||
615 | } | ||
616 | |||
527 | /* for TX_ONLY mode, be sure all words have shifted out */ | 617 | /* for TX_ONLY mode, be sure all words have shifted out */ |
528 | if (rx == NULL) { | 618 | if (rx == NULL) { |
529 | if (mcspi_wait_for_reg_bit(chstat_reg, | 619 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; |
530 | OMAP2_MCSPI_CHSTAT_TXS) < 0) | 620 | if (mcspi->fifo_depth > 0) { |
531 | dev_err(&spi->dev, "TXS timed out\n"); | 621 | wait_res = mcspi_wait_for_reg_bit(chstat_reg, |
532 | else if (mcspi_wait_for_reg_bit(chstat_reg, | 622 | OMAP2_MCSPI_CHSTAT_TXFFE); |
533 | OMAP2_MCSPI_CHSTAT_EOT) < 0) | 623 | if (wait_res < 0) |
624 | dev_err(&spi->dev, "TXFFE timed out\n"); | ||
625 | } else { | ||
626 | wait_res = mcspi_wait_for_reg_bit(chstat_reg, | ||
627 | OMAP2_MCSPI_CHSTAT_TXS); | ||
628 | if (wait_res < 0) | ||
629 | dev_err(&spi->dev, "TXS timed out\n"); | ||
630 | } | ||
631 | if (wait_res >= 0 && | ||
632 | (mcspi_wait_for_reg_bit(chstat_reg, | ||
633 | OMAP2_MCSPI_CHSTAT_EOT) < 0)) | ||
534 | dev_err(&spi->dev, "EOT timed out\n"); | 634 | dev_err(&spi->dev, "EOT timed out\n"); |
535 | } | 635 | } |
536 | } | 636 | } |
@@ -957,7 +1057,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
957 | cs = spi->controller_state; | 1057 | cs = spi->controller_state; |
958 | cd = spi->controller_data; | 1058 | cd = spi->controller_data; |
959 | 1059 | ||
960 | omap2_mcspi_set_enable(spi, 1); | 1060 | omap2_mcspi_set_enable(spi, 0); |
961 | list_for_each_entry(t, &m->transfers, transfer_list) { | 1061 | list_for_each_entry(t, &m->transfers, transfer_list) { |
962 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { | 1062 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { |
963 | status = -EINVAL; | 1063 | status = -EINVAL; |
@@ -1005,6 +1105,12 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1005 | if (t->len) { | 1105 | if (t->len) { |
1006 | unsigned count; | 1106 | unsigned count; |
1007 | 1107 | ||
1108 | if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && | ||
1109 | (m->is_dma_mapped || t->len >= DMA_MIN_BYTES)) | ||
1110 | omap2_mcspi_set_fifo(spi, t, 1); | ||
1111 | |||
1112 | omap2_mcspi_set_enable(spi, 1); | ||
1113 | |||
1008 | /* RX_ONLY mode needs dummy data in TX reg */ | 1114 | /* RX_ONLY mode needs dummy data in TX reg */ |
1009 | if (t->tx_buf == NULL) | 1115 | if (t->tx_buf == NULL) |
1010 | __raw_writel(0, cs->base | 1116 | __raw_writel(0, cs->base |
@@ -1031,6 +1137,11 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1031 | omap2_mcspi_force_cs(spi, 0); | 1137 | omap2_mcspi_force_cs(spi, 0); |
1032 | cs_active = 0; | 1138 | cs_active = 0; |
1033 | } | 1139 | } |
1140 | |||
1141 | omap2_mcspi_set_enable(spi, 0); | ||
1142 | |||
1143 | if (mcspi->fifo_depth > 0) | ||
1144 | omap2_mcspi_set_fifo(spi, t, 0); | ||
1034 | } | 1145 | } |
1035 | /* Restore defaults if they were overriden */ | 1146 | /* Restore defaults if they were overriden */ |
1036 | if (par_override) { | 1147 | if (par_override) { |
@@ -1051,8 +1162,10 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1051 | 1162 | ||
1052 | omap2_mcspi_set_enable(spi, 0); | 1163 | omap2_mcspi_set_enable(spi, 0); |
1053 | 1164 | ||
1054 | m->status = status; | 1165 | if (mcspi->fifo_depth > 0 && t) |
1166 | omap2_mcspi_set_fifo(spi, t, 0); | ||
1055 | 1167 | ||
1168 | m->status = status; | ||
1056 | } | 1169 | } |
1057 | 1170 | ||
1058 | static int omap2_mcspi_transfer_one_message(struct spi_master *master, | 1171 | static int omap2_mcspi_transfer_one_message(struct spi_master *master, |