aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2014-12-05 09:01:32 -0500
committerVinod Koul <vinod.koul@intel.com>2014-12-05 09:01:32 -0500
commit939b6ef378bfb6fd9cff61a1f3afa17e84ea0884 (patch)
treea01ba87fda921e8e60e4d938b0cf0d8d7fd37868
parentaf2d3139e19fd7da9a5d300a83812616b2d6694c (diff)
parentfef4cbf2ab830fcd695d892927386ad9ccc46339 (diff)
Merge branch 'topic/at_xdmac' into for-linus
-rw-r--r--Documentation/devicetree/bindings/dma/atmel-xdma.txt2
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/at_xdmac.c74
3 files changed, 46 insertions, 32 deletions
diff --git a/Documentation/devicetree/bindings/dma/atmel-xdma.txt b/Documentation/devicetree/bindings/dma/atmel-xdma.txt
index e75c128c53fa..0eb2b3207e08 100644
--- a/Documentation/devicetree/bindings/dma/atmel-xdma.txt
+++ b/Documentation/devicetree/bindings/dma/atmel-xdma.txt
@@ -22,7 +22,7 @@ dma1: dma-controller@f0004000 {
22 compatible = "atmel,sama5d4-dma"; 22 compatible = "atmel,sama5d4-dma";
23 reg = <0xf0004000 0x200>; 23 reg = <0xf0004000 0x200>;
24 interrupts = <50 4 0>; 24 interrupts = <50 4 0>;
25 #dma-cells = <2>; 25 #dma-cells = <1>;
26}; 26};
27 27
28 28
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index aef8b9dd4db6..f2b2c4e87aef 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -109,7 +109,7 @@ config AT_HDMAC
109 109
110config AT_XDMAC 110config AT_XDMAC
111 tristate "Atmel XDMA support" 111 tristate "Atmel XDMA support"
112 depends on (ARCH_AT91 || COMPILE_TEST) 112 depends on ARCH_AT91
113 select DMA_ENGINE 113 select DMA_ENGINE
114 help 114 help
115 Support the Atmel XDMA controller. 115 Support the Atmel XDMA controller.
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 4e9b023990ae..b60d77a22df6 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -562,6 +562,7 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
562 struct scatterlist *sg; 562 struct scatterlist *sg;
563 int i; 563 int i;
564 u32 cfg; 564 u32 cfg;
565 unsigned int xfer_size = 0;
565 566
566 if (!sgl) 567 if (!sgl)
567 return NULL; 568 return NULL;
@@ -619,15 +620,15 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
619 | (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE) /* descriptor fetch */ 620 | (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE) /* descriptor fetch */
620 | len / (1 << at_xdmac_get_dwidth(cfg)); /* microblock length */ 621 | len / (1 << at_xdmac_get_dwidth(cfg)); /* microblock length */
621 dev_dbg(chan2dev(chan), 622 dev_dbg(chan2dev(chan),
622 "%s: lld: mbr_sa=0x%08x, mbr_da=0x%08x, mbr_ubc=0x%08x\n", 623 "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n",
623 __func__, desc->lld.mbr_sa, desc->lld.mbr_da, desc->lld.mbr_ubc); 624 __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc);
624 625
625 /* Chain lld. */ 626 /* Chain lld. */
626 if (prev) { 627 if (prev) {
627 prev->lld.mbr_nda = desc->tx_dma_desc.phys; 628 prev->lld.mbr_nda = desc->tx_dma_desc.phys;
628 dev_dbg(chan2dev(chan), 629 dev_dbg(chan2dev(chan),
629 "%s: chain lld: prev=0x%p, mbr_nda=0x%08x\n", 630 "%s: chain lld: prev=0x%p, mbr_nda=%pad\n",
630 __func__, prev, prev->lld.mbr_nda); 631 __func__, prev, &prev->lld.mbr_nda);
631 } 632 }
632 633
633 prev = desc; 634 prev = desc;
@@ -637,12 +638,13 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
637 dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", 638 dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n",
638 __func__, desc, first); 639 __func__, desc, first);
639 list_add_tail(&desc->desc_node, &first->descs_list); 640 list_add_tail(&desc->desc_node, &first->descs_list);
641 xfer_size += len;
640 } 642 }
641 643
642 spin_unlock_bh(&atchan->lock); 644 spin_unlock_bh(&atchan->lock);
643 645
644 first->tx_dma_desc.flags = flags; 646 first->tx_dma_desc.flags = flags;
645 first->xfer_size = sg_len; 647 first->xfer_size = xfer_size;
646 first->direction = direction; 648 first->direction = direction;
647 649
648 return &first->tx_dma_desc; 650 return &first->tx_dma_desc;
@@ -660,8 +662,8 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
660 int i; 662 int i;
661 u32 cfg; 663 u32 cfg;
662 664
663 dev_dbg(chan2dev(chan), "%s: buf_addr=0x%08x, buf_len=%d, period_len=%d, dir=%s, flags=0x%lx\n", 665 dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n",
664 __func__, buf_addr, buf_len, period_len, 666 __func__, &buf_addr, buf_len, period_len,
665 direction == DMA_MEM_TO_DEV ? "mem2per" : "per2mem", flags); 667 direction == DMA_MEM_TO_DEV ? "mem2per" : "per2mem", flags);
666 668
667 if (!is_slave_direction(direction)) { 669 if (!is_slave_direction(direction)) {
@@ -688,8 +690,8 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
688 } 690 }
689 spin_unlock_bh(&atchan->lock); 691 spin_unlock_bh(&atchan->lock);
690 dev_dbg(chan2dev(chan), 692 dev_dbg(chan2dev(chan),
691 "%s: desc=0x%p, tx_dma_desc.phys=0x%08x\n", 693 "%s: desc=0x%p, tx_dma_desc.phys=%pad\n",
692 __func__, desc, desc->tx_dma_desc.phys); 694 __func__, desc, &desc->tx_dma_desc.phys);
693 695
694 if (direction == DMA_DEV_TO_MEM) { 696 if (direction == DMA_DEV_TO_MEM) {
695 desc->lld.mbr_sa = atchan->per_src_addr; 697 desc->lld.mbr_sa = atchan->per_src_addr;
@@ -699,7 +701,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
699 desc->lld.mbr_sa = buf_addr + i * period_len; 701 desc->lld.mbr_sa = buf_addr + i * period_len;
700 desc->lld.mbr_da = atchan->per_dst_addr; 702 desc->lld.mbr_da = atchan->per_dst_addr;
701 cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; 703 cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
702 }; 704 }
703 desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 705 desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1
704 | AT_XDMAC_MBR_UBC_NDEN 706 | AT_XDMAC_MBR_UBC_NDEN
705 | AT_XDMAC_MBR_UBC_NSEN 707 | AT_XDMAC_MBR_UBC_NSEN
@@ -707,15 +709,15 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
707 | period_len >> at_xdmac_get_dwidth(cfg); 709 | period_len >> at_xdmac_get_dwidth(cfg);
708 710
709 dev_dbg(chan2dev(chan), 711 dev_dbg(chan2dev(chan),
710 "%s: lld: mbr_sa=0x%08x, mbr_da=0x%08x, mbr_ubc=0x%08x\n", 712 "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n",
711 __func__, desc->lld.mbr_sa, desc->lld.mbr_da, desc->lld.mbr_ubc); 713 __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc);
712 714
713 /* Chain lld. */ 715 /* Chain lld. */
714 if (prev) { 716 if (prev) {
715 prev->lld.mbr_nda = desc->tx_dma_desc.phys; 717 prev->lld.mbr_nda = desc->tx_dma_desc.phys;
716 dev_dbg(chan2dev(chan), 718 dev_dbg(chan2dev(chan),
717 "%s: chain lld: prev=0x%p, mbr_nda=0x%08x\n", 719 "%s: chain lld: prev=0x%p, mbr_nda=%pad\n",
718 __func__, prev, prev->lld.mbr_nda); 720 __func__, prev, &prev->lld.mbr_nda);
719 } 721 }
720 722
721 prev = desc; 723 prev = desc;
@@ -729,8 +731,8 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
729 731
730 prev->lld.mbr_nda = first->tx_dma_desc.phys; 732 prev->lld.mbr_nda = first->tx_dma_desc.phys;
731 dev_dbg(chan2dev(chan), 733 dev_dbg(chan2dev(chan),
732 "%s: chain lld: prev=0x%p, mbr_nda=0x%08x\n", 734 "%s: chain lld: prev=0x%p, mbr_nda=%pad\n",
733 __func__, prev, prev->lld.mbr_nda); 735 __func__, prev, &prev->lld.mbr_nda);
734 first->tx_dma_desc.flags = flags; 736 first->tx_dma_desc.flags = flags;
735 first->xfer_size = buf_len; 737 first->xfer_size = buf_len;
736 first->direction = direction; 738 first->direction = direction;
@@ -762,8 +764,8 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
762 | AT_XDMAC_CC_MBSIZE_SIXTEEN 764 | AT_XDMAC_CC_MBSIZE_SIXTEEN
763 | AT_XDMAC_CC_TYPE_MEM_TRAN; 765 | AT_XDMAC_CC_TYPE_MEM_TRAN;
764 766
765 dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, len=%d, flags=0x%lx\n", 767 dev_dbg(chan2dev(chan), "%s: src=%pad, dest=%pad, len=%zd, flags=0x%lx\n",
766 __func__, src, dest, len, flags); 768 __func__, &src, &dest, len, flags);
767 769
768 if (unlikely(!len)) 770 if (unlikely(!len))
769 return NULL; 771 return NULL;
@@ -791,7 +793,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
791 while (remaining_size) { 793 while (remaining_size) {
792 struct at_xdmac_desc *desc = NULL; 794 struct at_xdmac_desc *desc = NULL;
793 795
794 dev_dbg(chan2dev(chan), "%s: remaining_size=%u\n", __func__, remaining_size); 796 dev_dbg(chan2dev(chan), "%s: remaining_size=%zu\n", __func__, remaining_size);
795 797
796 spin_lock_bh(&atchan->lock); 798 spin_lock_bh(&atchan->lock);
797 desc = at_xdmac_get_desc(atchan); 799 desc = at_xdmac_get_desc(atchan);
@@ -812,7 +814,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
812 else 814 else
813 xfer_size = remaining_size; 815 xfer_size = remaining_size;
814 816
815 dev_dbg(chan2dev(chan), "%s: xfer_size=%u\n", __func__, xfer_size); 817 dev_dbg(chan2dev(chan), "%s: xfer_size=%zu\n", __func__, xfer_size);
816 818
817 /* Check remaining length and change data width if needed. */ 819 /* Check remaining length and change data width if needed. */
818 if (!((src_addr | dst_addr | xfer_size) & 7)) { 820 if (!((src_addr | dst_addr | xfer_size) & 7)) {
@@ -843,8 +845,8 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
843 desc->lld.mbr_cfg = chan_cc; 845 desc->lld.mbr_cfg = chan_cc;
844 846
845 dev_dbg(chan2dev(chan), 847 dev_dbg(chan2dev(chan),
846 "%s: lld: mbr_sa=0x%08x, mbr_da=0x%08x, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", 848 "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n",
847 __func__, desc->lld.mbr_sa, desc->lld.mbr_da, desc->lld.mbr_ubc, desc->lld.mbr_cfg); 849 __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc, desc->lld.mbr_cfg);
848 850
849 /* Chain lld. */ 851 /* Chain lld. */
850 if (prev) { 852 if (prev) {
@@ -879,7 +881,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
879 struct list_head *descs_list; 881 struct list_head *descs_list;
880 enum dma_status ret; 882 enum dma_status ret;
881 int residue; 883 int residue;
882 u32 cur_nda; 884 u32 cur_nda, mask, value;
883 u8 dwidth = at_xdmac_get_dwidth(atchan->cfg[AT_XDMAC_CUR_CFG]); 885 u8 dwidth = at_xdmac_get_dwidth(atchan->cfg[AT_XDMAC_CUR_CFG]);
884 886
885 ret = dma_cookie_status(chan, cookie, txstate); 887 ret = dma_cookie_status(chan, cookie, txstate);
@@ -899,14 +901,22 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
899 */ 901 */
900 if (!desc->active_xfer) { 902 if (!desc->active_xfer) {
901 dma_set_residue(txstate, desc->xfer_size); 903 dma_set_residue(txstate, desc->xfer_size);
904 spin_unlock_bh(&atchan->lock);
902 return ret; 905 return ret;
903 } 906 }
904 907
905 residue = desc->xfer_size; 908 residue = desc->xfer_size;
906 /* Flush FIFO. */ 909 /*
907 at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); 910 * Flush FIFO: only relevant when the transfer is source peripheral
908 while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) 911 * synchronized.
909 cpu_relax(); 912 */
913 mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
914 value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
915 if ((atchan->cfg[AT_XDMAC_CUR_CFG] & mask) == value) {
916 at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
917 while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
918 cpu_relax();
919 }
910 920
911 cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; 921 cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
912 /* 922 /*
@@ -927,8 +937,8 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
927 dma_set_residue(txstate, residue); 937 dma_set_residue(txstate, residue);
928 938
929 dev_dbg(chan2dev(chan), 939 dev_dbg(chan2dev(chan),
930 "%s: desc=0x%p, tx_dma_desc.phys=0x%08x, tx_status=%d, cookie=%d, residue=%d\n", 940 "%s: desc=0x%p, tx_dma_desc.phys=%pad, tx_status=%d, cookie=%d, residue=%d\n",
931 __func__, desc, desc->tx_dma_desc.phys, ret, cookie, residue); 941 __func__, desc, &desc->tx_dma_desc.phys, ret, cookie, residue);
932 942
933 return ret; 943 return ret;
934} 944}
@@ -1384,6 +1394,11 @@ static int at_xdmac_probe(struct platform_device *pdev)
1384 dma_cap_set(DMA_CYCLIC, atxdmac->dma.cap_mask); 1394 dma_cap_set(DMA_CYCLIC, atxdmac->dma.cap_mask);
1385 dma_cap_set(DMA_MEMCPY, atxdmac->dma.cap_mask); 1395 dma_cap_set(DMA_MEMCPY, atxdmac->dma.cap_mask);
1386 dma_cap_set(DMA_SLAVE, atxdmac->dma.cap_mask); 1396 dma_cap_set(DMA_SLAVE, atxdmac->dma.cap_mask);
1397 /*
1398 * Without DMA_PRIVATE the driver is not able to allocate more than
1399 * one channel, second allocation fails in private_candidate.
1400 */
1401 dma_cap_set(DMA_PRIVATE, atxdmac->dma.cap_mask);
1387 atxdmac->dma.dev = &pdev->dev; 1402 atxdmac->dma.dev = &pdev->dev;
1388 atxdmac->dma.device_alloc_chan_resources = at_xdmac_alloc_chan_resources; 1403 atxdmac->dma.device_alloc_chan_resources = at_xdmac_alloc_chan_resources;
1389 atxdmac->dma.device_free_chan_resources = at_xdmac_free_chan_resources; 1404 atxdmac->dma.device_free_chan_resources = at_xdmac_free_chan_resources;
@@ -1393,7 +1408,6 @@ static int at_xdmac_probe(struct platform_device *pdev)
1393 atxdmac->dma.device_prep_dma_memcpy = at_xdmac_prep_dma_memcpy; 1408 atxdmac->dma.device_prep_dma_memcpy = at_xdmac_prep_dma_memcpy;
1394 atxdmac->dma.device_prep_slave_sg = at_xdmac_prep_slave_sg; 1409 atxdmac->dma.device_prep_slave_sg = at_xdmac_prep_slave_sg;
1395 atxdmac->dma.device_control = at_xdmac_control; 1410 atxdmac->dma.device_control = at_xdmac_control;
1396 atxdmac->dma.chancnt = nr_channels;
1397 atxdmac->dma.device_slave_caps = at_xdmac_device_slave_caps; 1411 atxdmac->dma.device_slave_caps = at_xdmac_device_slave_caps;
1398 1412
1399 /* Disable all chans and interrupts. */ 1413 /* Disable all chans and interrupts. */