aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/pl330.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/pl330.c')
-rw-r--r--drivers/dma/pl330.c99
1 files changed, 53 insertions, 46 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 2d8d1b041d95..09adcfcd953e 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
19#include <linux/amba/pl330.h> 19#include <linux/amba/pl330.h>
20#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
21#include <linux/scatterlist.h> 21#include <linux/scatterlist.h>
22#include <linux/of.h>
22 23
23#define NR_DEFAULT_DESC 16 24#define NR_DEFAULT_DESC 16
24 25
@@ -116,6 +117,9 @@ struct dma_pl330_desc {
116 struct dma_pl330_chan *pchan; 117 struct dma_pl330_chan *pchan;
117}; 118};
118 119
120/* forward declaration */
121static struct amba_driver pl330_driver;
122
119static inline struct dma_pl330_chan * 123static inline struct dma_pl330_chan *
120to_pchan(struct dma_chan *ch) 124to_pchan(struct dma_chan *ch)
121{ 125{
@@ -267,6 +271,32 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
267 tasklet_schedule(&pch->task); 271 tasklet_schedule(&pch->task);
268} 272}
269 273
274bool pl330_filter(struct dma_chan *chan, void *param)
275{
276 u8 *peri_id;
277
278 if (chan->device->dev->driver != &pl330_driver.drv)
279 return false;
280
281#ifdef CONFIG_OF
282 if (chan->device->dev->of_node) {
283 const __be32 *prop_value;
284 phandle phandle;
285 struct device_node *node;
286
287 prop_value = ((struct property *)param)->value;
288 phandle = be32_to_cpup(prop_value++);
289 node = of_find_node_by_phandle(phandle);
290 return ((chan->private == node) &&
291 (chan->chan_id == be32_to_cpup(prop_value)));
292 }
293#endif
294
295 peri_id = chan->private;
296 return *peri_id == (unsigned)param;
297}
298EXPORT_SYMBOL(pl330_filter);
299
270static int pl330_alloc_chan_resources(struct dma_chan *chan) 300static int pl330_alloc_chan_resources(struct dma_chan *chan)
271{ 301{
272 struct dma_pl330_chan *pch = to_pchan(chan); 302 struct dma_pl330_chan *pch = to_pchan(chan);
@@ -497,7 +527,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
497static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) 527static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
498{ 528{
499 struct dma_pl330_dmac *pdmac = pch->dmac; 529 struct dma_pl330_dmac *pdmac = pch->dmac;
500 struct dma_pl330_peri *peri = pch->chan.private; 530 u8 *peri_id = pch->chan.private;
501 struct dma_pl330_desc *desc; 531 struct dma_pl330_desc *desc;
502 532
503 /* Pluck one desc from the pool of DMAC */ 533 /* Pluck one desc from the pool of DMAC */
@@ -522,13 +552,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
522 desc->txd.cookie = 0; 552 desc->txd.cookie = 0;
523 async_tx_ack(&desc->txd); 553 async_tx_ack(&desc->txd);
524 554
525 if (peri) { 555 desc->req.peri = peri_id ? pch->chan.chan_id : 0;
526 desc->req.rqtype = peri->rqtype;
527 desc->req.peri = pch->chan.chan_id;
528 } else {
529 desc->req.rqtype = MEMTOMEM;
530 desc->req.peri = 0;
531 }
532 556
533 dma_async_tx_descriptor_init(&desc->txd, &pch->chan); 557 dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
534 558
@@ -615,12 +639,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
615 case DMA_TO_DEVICE: 639 case DMA_TO_DEVICE:
616 desc->rqcfg.src_inc = 1; 640 desc->rqcfg.src_inc = 1;
617 desc->rqcfg.dst_inc = 0; 641 desc->rqcfg.dst_inc = 0;
642 desc->req.rqtype = MEMTODEV;
618 src = dma_addr; 643 src = dma_addr;
619 dst = pch->fifo_addr; 644 dst = pch->fifo_addr;
620 break; 645 break;
621 case DMA_FROM_DEVICE: 646 case DMA_FROM_DEVICE:
622 desc->rqcfg.src_inc = 0; 647 desc->rqcfg.src_inc = 0;
623 desc->rqcfg.dst_inc = 1; 648 desc->rqcfg.dst_inc = 1;
649 desc->req.rqtype = DEVTOMEM;
624 src = pch->fifo_addr; 650 src = pch->fifo_addr;
625 dst = dma_addr; 651 dst = dma_addr;
626 break; 652 break;
@@ -646,16 +672,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
646{ 672{
647 struct dma_pl330_desc *desc; 673 struct dma_pl330_desc *desc;
648 struct dma_pl330_chan *pch = to_pchan(chan); 674 struct dma_pl330_chan *pch = to_pchan(chan);
649 struct dma_pl330_peri *peri = chan->private;
650 struct pl330_info *pi; 675 struct pl330_info *pi;
651 int burst; 676 int burst;
652 677
653 if (unlikely(!pch || !len)) 678 if (unlikely(!pch || !len))
654 return NULL; 679 return NULL;
655 680
656 if (peri && peri->rqtype != MEMTOMEM)
657 return NULL;
658
659 pi = &pch->dmac->pif; 681 pi = &pch->dmac->pif;
660 682
661 desc = __pl330_prep_dma_memcpy(pch, dst, src, len); 683 desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
@@ -664,6 +686,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
664 686
665 desc->rqcfg.src_inc = 1; 687 desc->rqcfg.src_inc = 1;
666 desc->rqcfg.dst_inc = 1; 688 desc->rqcfg.dst_inc = 1;
689 desc->req.rqtype = MEMTOMEM;
667 690
668 /* Select max possible burst size */ 691 /* Select max possible burst size */
669 burst = pi->pcfg.data_bus_width / 8; 692 burst = pi->pcfg.data_bus_width / 8;
@@ -692,25 +715,14 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
692{ 715{
693 struct dma_pl330_desc *first, *desc = NULL; 716 struct dma_pl330_desc *first, *desc = NULL;
694 struct dma_pl330_chan *pch = to_pchan(chan); 717 struct dma_pl330_chan *pch = to_pchan(chan);
695 struct dma_pl330_peri *peri = chan->private;
696 struct scatterlist *sg; 718 struct scatterlist *sg;
697 unsigned long flags; 719 unsigned long flags;
698 int i; 720 int i;
699 dma_addr_t addr; 721 dma_addr_t addr;
700 722
701 if (unlikely(!pch || !sgl || !sg_len || !peri)) 723 if (unlikely(!pch || !sgl || !sg_len))
702 return NULL; 724 return NULL;
703 725
704 /* Make sure the direction is consistent */
705 if ((direction == DMA_TO_DEVICE &&
706 peri->rqtype != MEMTODEV) ||
707 (direction == DMA_FROM_DEVICE &&
708 peri->rqtype != DEVTOMEM)) {
709 dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
710 __func__, __LINE__);
711 return NULL;
712 }
713
714 addr = pch->fifo_addr; 726 addr = pch->fifo_addr;
715 727
716 first = NULL; 728 first = NULL;
@@ -750,11 +762,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
750 if (direction == DMA_TO_DEVICE) { 762 if (direction == DMA_TO_DEVICE) {
751 desc->rqcfg.src_inc = 1; 763 desc->rqcfg.src_inc = 1;
752 desc->rqcfg.dst_inc = 0; 764 desc->rqcfg.dst_inc = 0;
765 desc->req.rqtype = MEMTODEV;
753 fill_px(&desc->px, 766 fill_px(&desc->px,
754 addr, sg_dma_address(sg), sg_dma_len(sg)); 767 addr, sg_dma_address(sg), sg_dma_len(sg));
755 } else { 768 } else {
756 desc->rqcfg.src_inc = 0; 769 desc->rqcfg.src_inc = 0;
757 desc->rqcfg.dst_inc = 1; 770 desc->rqcfg.dst_inc = 1;
771 desc->req.rqtype = DEVTOMEM;
758 fill_px(&desc->px, 772 fill_px(&desc->px,
759 sg_dma_address(sg), addr, sg_dma_len(sg)); 773 sg_dma_address(sg), addr, sg_dma_len(sg));
760 } 774 }
@@ -856,32 +870,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
856 INIT_LIST_HEAD(&pd->channels); 870 INIT_LIST_HEAD(&pd->channels);
857 871
858 /* Initialize channel parameters */ 872 /* Initialize channel parameters */
859 num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan); 873 num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
874 (u8)pi->pcfg.num_chan);
860 pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); 875 pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
861 876
862 for (i = 0; i < num_chan; i++) { 877 for (i = 0; i < num_chan; i++) {
863 pch = &pdmac->peripherals[i]; 878 pch = &pdmac->peripherals[i];
864 if (pdat) { 879 if (!adev->dev.of_node)
865 struct dma_pl330_peri *peri = &pdat->peri[i]; 880 pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
866 881 else
867 switch (peri->rqtype) { 882 pch->chan.private = adev->dev.of_node;
868 case MEMTOMEM:
869 dma_cap_set(DMA_MEMCPY, pd->cap_mask);
870 break;
871 case MEMTODEV:
872 case DEVTOMEM:
873 dma_cap_set(DMA_SLAVE, pd->cap_mask);
874 dma_cap_set(DMA_CYCLIC, pd->cap_mask);
875 break;
876 default:
877 dev_err(&adev->dev, "DEVTODEV Not Supported\n");
878 continue;
879 }
880 pch->chan.private = peri;
881 } else {
882 dma_cap_set(DMA_MEMCPY, pd->cap_mask);
883 pch->chan.private = NULL;
884 }
885 883
886 INIT_LIST_HEAD(&pch->work_list); 884 INIT_LIST_HEAD(&pch->work_list);
887 spin_lock_init(&pch->lock); 885 spin_lock_init(&pch->lock);
@@ -894,6 +892,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
894 } 892 }
895 893
896 pd->dev = &adev->dev; 894 pd->dev = &adev->dev;
895 if (pdat) {
896 pd->cap_mask = pdat->cap_mask;
897 } else {
898 dma_cap_set(DMA_MEMCPY, pd->cap_mask);
899 if (pi->pcfg.num_peri) {
900 dma_cap_set(DMA_SLAVE, pd->cap_mask);
901 dma_cap_set(DMA_CYCLIC, pd->cap_mask);
902 }
903 }
897 904
898 pd->device_alloc_chan_resources = pl330_alloc_chan_resources; 905 pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
899 pd->device_free_chan_resources = pl330_free_chan_resources; 906 pd->device_free_chan_resources = pl330_free_chan_resources;