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