diff options
Diffstat (limited to 'drivers/spi')
| -rw-r--r-- | drivers/spi/spi-ti-qspi.c | 139 |
1 files changed, 122 insertions, 17 deletions
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index ac0b072815a3..caeac66a3977 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c | |||
| @@ -41,6 +41,8 @@ struct ti_qspi_regs { | |||
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | struct ti_qspi { | 43 | struct ti_qspi { |
| 44 | struct completion transfer_complete; | ||
| 45 | |||
| 44 | /* list synchronization */ | 46 | /* list synchronization */ |
| 45 | struct mutex list_lock; | 47 | struct mutex list_lock; |
| 46 | 48 | ||
| @@ -54,6 +56,9 @@ struct ti_qspi { | |||
| 54 | 56 | ||
| 55 | struct ti_qspi_regs ctx_reg; | 57 | struct ti_qspi_regs ctx_reg; |
| 56 | 58 | ||
| 59 | dma_addr_t mmap_phys_base; | ||
| 60 | struct dma_chan *rx_chan; | ||
| 61 | |||
| 57 | u32 spi_max_frequency; | 62 | u32 spi_max_frequency; |
| 58 | u32 cmd; | 63 | u32 cmd; |
| 59 | u32 dc; | 64 | u32 dc; |
| @@ -379,6 +384,72 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t, | |||
| 379 | return 0; | 384 | return 0; |
| 380 | } | 385 | } |
| 381 | 386 | ||
| 387 | static void ti_qspi_dma_callback(void *param) | ||
| 388 | { | ||
| 389 | struct ti_qspi *qspi = param; | ||
| 390 | |||
| 391 | complete(&qspi->transfer_complete); | ||
| 392 | } | ||
| 393 | |||
| 394 | static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst, | ||
| 395 | dma_addr_t dma_src, size_t len) | ||
| 396 | { | ||
| 397 | struct dma_chan *chan = qspi->rx_chan; | ||
| 398 | struct dma_device *dma_dev = chan->device; | ||
| 399 | dma_cookie_t cookie; | ||
| 400 | enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; | ||
| 401 | struct dma_async_tx_descriptor *tx; | ||
| 402 | int ret; | ||
| 403 | |||
| 404 | tx = dma_dev->device_prep_dma_memcpy(chan, dma_dst, dma_src, | ||
| 405 | len, flags); | ||
| 406 | if (!tx) { | ||
| 407 | dev_err(qspi->dev, "device_prep_dma_memcpy error\n"); | ||
| 408 | return -EIO; | ||
| 409 | } | ||
| 410 | |||
| 411 | tx->callback = ti_qspi_dma_callback; | ||
| 412 | tx->callback_param = qspi; | ||
| 413 | cookie = tx->tx_submit(tx); | ||
| 414 | |||
| 415 | ret = dma_submit_error(cookie); | ||
| 416 | if (ret) { | ||
| 417 | dev_err(qspi->dev, "dma_submit_error %d\n", cookie); | ||
| 418 | return -EIO; | ||
| 419 | } | ||
| 420 | |||
| 421 | dma_async_issue_pending(chan); | ||
| 422 | ret = wait_for_completion_timeout(&qspi->transfer_complete, | ||
| 423 | msecs_to_jiffies(len)); | ||
| 424 | if (ret <= 0) { | ||
| 425 | dmaengine_terminate_sync(chan); | ||
| 426 | dev_err(qspi->dev, "DMA wait_for_completion_timeout\n"); | ||
| 427 | return -ETIMEDOUT; | ||
| 428 | } | ||
| 429 | |||
| 430 | return 0; | ||
| 431 | } | ||
| 432 | |||
| 433 | static int ti_qspi_dma_xfer_sg(struct ti_qspi *qspi, struct sg_table rx_sg, | ||
| 434 | loff_t from) | ||
| 435 | { | ||
| 436 | struct scatterlist *sg; | ||
| 437 | dma_addr_t dma_src = qspi->mmap_phys_base + from; | ||
| 438 | dma_addr_t dma_dst; | ||
| 439 | int i, len, ret; | ||
| 440 | |||
| 441 | for_each_sg(rx_sg.sgl, sg, rx_sg.nents, i) { | ||
| 442 | dma_dst = sg_dma_address(sg); | ||
| 443 | len = sg_dma_len(sg); | ||
| 444 | ret = ti_qspi_dma_xfer(qspi, dma_dst, dma_src, len); | ||
| 445 | if (ret) | ||
| 446 | return ret; | ||
| 447 | dma_src += len; | ||
| 448 | } | ||
| 449 | |||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | |||
| 382 | static void ti_qspi_enable_memory_map(struct spi_device *spi) | 453 | static void ti_qspi_enable_memory_map(struct spi_device *spi) |
| 383 | { | 454 | { |
| 384 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | 455 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); |
| @@ -426,7 +497,7 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi, | |||
| 426 | QSPI_SPI_SETUP_REG(spi->chip_select)); | 497 | QSPI_SPI_SETUP_REG(spi->chip_select)); |
| 427 | } | 498 | } |
| 428 | 499 | ||
| 429 | static int ti_qspi_spi_flash_read(struct spi_device *spi, | 500 | static int ti_qspi_spi_flash_read(struct spi_device *spi, |
| 430 | struct spi_flash_read_message *msg) | 501 | struct spi_flash_read_message *msg) |
| 431 | { | 502 | { |
| 432 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | 503 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); |
| @@ -437,9 +508,23 @@ static int ti_qspi_spi_flash_read(struct spi_device *spi, | |||
| 437 | if (!qspi->mmap_enabled) | 508 | if (!qspi->mmap_enabled) |
| 438 | ti_qspi_enable_memory_map(spi); | 509 | ti_qspi_enable_memory_map(spi); |
| 439 | ti_qspi_setup_mmap_read(spi, msg); | 510 | ti_qspi_setup_mmap_read(spi, msg); |
| 440 | memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len); | 511 | |
| 512 | if (qspi->rx_chan) { | ||
| 513 | if (msg->cur_msg_mapped) { | ||
| 514 | ret = ti_qspi_dma_xfer_sg(qspi, msg->rx_sg, msg->from); | ||
| 515 | if (ret) | ||
| 516 | goto err_unlock; | ||
| 517 | } else { | ||
| 518 | dev_err(qspi->dev, "Invalid address for DMA\n"); | ||
| 519 | ret = -EIO; | ||
| 520 | goto err_unlock; | ||
| 521 | } | ||
| 522 | } else { | ||
| 523 | memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len); | ||
| 524 | } | ||
| 441 | msg->retlen = msg->len; | 525 | msg->retlen = msg->len; |
| 442 | 526 | ||
| 527 | err_unlock: | ||
| 443 | mutex_unlock(&qspi->list_lock); | 528 | mutex_unlock(&qspi->list_lock); |
| 444 | 529 | ||
| 445 | return ret; | 530 | return ret; |
| @@ -536,6 +621,7 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 536 | struct device_node *np = pdev->dev.of_node; | 621 | struct device_node *np = pdev->dev.of_node; |
| 537 | u32 max_freq; | 622 | u32 max_freq; |
| 538 | int ret = 0, num_cs, irq; | 623 | int ret = 0, num_cs, irq; |
| 624 | dma_cap_mask_t mask; | ||
| 539 | 625 | ||
| 540 | master = spi_alloc_master(&pdev->dev, sizeof(*qspi)); | 626 | master = spi_alloc_master(&pdev->dev, sizeof(*qspi)); |
| 541 | if (!master) | 627 | if (!master) |
| @@ -550,6 +636,7 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 550 | master->dev.of_node = pdev->dev.of_node; | 636 | master->dev.of_node = pdev->dev.of_node; |
| 551 | master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | | 637 | master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | |
| 552 | SPI_BPW_MASK(8); | 638 | SPI_BPW_MASK(8); |
| 639 | master->spi_flash_read = ti_qspi_spi_flash_read; | ||
| 553 | 640 | ||
| 554 | if (!of_property_read_u32(np, "num-cs", &num_cs)) | 641 | if (!of_property_read_u32(np, "num-cs", &num_cs)) |
| 555 | master->num_chipselect = num_cs; | 642 | master->num_chipselect = num_cs; |
| @@ -592,17 +679,6 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 592 | goto free_master; | 679 | goto free_master; |
| 593 | } | 680 | } |
| 594 | 681 | ||
| 595 | if (res_mmap) { | ||
| 596 | qspi->mmap_base = devm_ioremap_resource(&pdev->dev, | ||
| 597 | res_mmap); | ||
| 598 | master->spi_flash_read = ti_qspi_spi_flash_read; | ||
| 599 | if (IS_ERR(qspi->mmap_base)) { | ||
| 600 | dev_err(&pdev->dev, | ||
| 601 | "falling back to PIO mode\n"); | ||
| 602 | master->spi_flash_read = NULL; | ||
| 603 | } | ||
| 604 | } | ||
| 605 | qspi->mmap_enabled = false; | ||
| 606 | 682 | ||
| 607 | if (of_property_read_bool(np, "syscon-chipselects")) { | 683 | if (of_property_read_bool(np, "syscon-chipselects")) { |
| 608 | qspi->ctrl_base = | 684 | qspi->ctrl_base = |
| @@ -633,11 +709,37 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 633 | if (!of_property_read_u32(np, "spi-max-frequency", &max_freq)) | 709 | if (!of_property_read_u32(np, "spi-max-frequency", &max_freq)) |
| 634 | qspi->spi_max_frequency = max_freq; | 710 | qspi->spi_max_frequency = max_freq; |
| 635 | 711 | ||
| 636 | ret = devm_spi_register_master(&pdev->dev, master); | 712 | dma_cap_zero(mask); |
| 637 | if (ret) | 713 | dma_cap_set(DMA_MEMCPY, mask); |
| 638 | goto free_master; | ||
| 639 | 714 | ||
| 640 | return 0; | 715 | qspi->rx_chan = dma_request_chan_by_mask(&mask); |
| 716 | if (!qspi->rx_chan) { | ||
| 717 | dev_err(qspi->dev, | ||
| 718 | "No Rx DMA available, trying mmap mode\n"); | ||
| 719 | ret = 0; | ||
| 720 | goto no_dma; | ||
| 721 | } | ||
| 722 | master->dma_rx = qspi->rx_chan; | ||
| 723 | init_completion(&qspi->transfer_complete); | ||
| 724 | if (res_mmap) | ||
| 725 | qspi->mmap_phys_base = (dma_addr_t)res_mmap->start; | ||
| 726 | |||
| 727 | no_dma: | ||
| 728 | if (!qspi->rx_chan && res_mmap) { | ||
| 729 | qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap); | ||
| 730 | if (IS_ERR(qspi->mmap_base)) { | ||
| 731 | dev_info(&pdev->dev, | ||
| 732 | "mmap failed with error %ld using PIO mode\n", | ||
| 733 | PTR_ERR(qspi->mmap_base)); | ||
| 734 | qspi->mmap_base = NULL; | ||
| 735 | master->spi_flash_read = NULL; | ||
| 736 | } | ||
| 737 | } | ||
| 738 | qspi->mmap_enabled = false; | ||
| 739 | |||
| 740 | ret = devm_spi_register_master(&pdev->dev, master); | ||
| 741 | if (!ret) | ||
| 742 | return 0; | ||
| 641 | 743 | ||
| 642 | free_master: | 744 | free_master: |
| 643 | spi_master_put(master); | 745 | spi_master_put(master); |
| @@ -656,6 +758,9 @@ static int ti_qspi_remove(struct platform_device *pdev) | |||
| 656 | pm_runtime_put_sync(&pdev->dev); | 758 | pm_runtime_put_sync(&pdev->dev); |
| 657 | pm_runtime_disable(&pdev->dev); | 759 | pm_runtime_disable(&pdev->dev); |
| 658 | 760 | ||
| 761 | if (qspi->rx_chan) | ||
| 762 | dma_release_channel(qspi->rx_chan); | ||
| 763 | |||
| 659 | return 0; | 764 | return 0; |
| 660 | } | 765 | } |
| 661 | 766 | ||
