All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Add device tree support for PL330 dma controller driver
@ 2011-08-26  8:40 ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	vinod.koul, patches, jassisinghbrar, boojin.kim

This patchset adds device tree support for PL330 driver and uses it
to add device tree support for Samsung platforms, specifically Exynos4.

First patch moves the pl330_filter function from Samsung specific wrappers
to pl330 dma driver and also adds a check to ensure that the filter function
proceeds only if it the dma channel being investigated belongs to pl330
dma controller instance.

Second patch adds support to infer the direction of the dma transfer
using the direction specified with the transfer request instead of
including this information in the platform data. This simlifies the
addition of device tree support. Third patch simplifies the platform
data for Exynos4 pl330 dma controllers. Similar patches simplifying
the platform data for other Samsung platforms is under development.

Fourth patch adds device tree support for pl330 dma controller driver.
A dma channel is represented using a phandle of the dma controller
node and the channel id within that controller. Client driver request
a dma channel using the phandle and channel id pair. Correspondingly,
the pl330 filter function has been modified to lookup a channel based
on this value.

Fifth patch adds device tree support for Samsung's DMA engine wrappers.
Client drivers retrive the channel property from their device node and
pass it to the wrappers. The wrapper functions use the property value
as the filter function parameter. Sixth patch restricts the usage of
pl330 device and platform data instances to non-dt platforms.

This patchset is based on Linux 3.1-rc3 with following patch sets
applied.

* To use DMA generic APIs for Samsung DMA - v7 - (15 patches)
* ARM: Samsung: use dma-pl330 device name for clock (3 patches)
* ARM: S5P64X0: Add the devname for DMA clock.
* ARM: SAMSUNG: register the second instance of PL330 DMAC (3 patches)

Thomas Abraham (6):
  DMA: PL330: move filter function into driver
  DMA: PL330: Infer transfer direction from transfer request instead of platform data
  ARM: EXYNOS4: Modify platform data for pl330 driver
  DMA: PL330: Add device tree support
  ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
  ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build

 .../devicetree/bindings/dma/arm-pl330.txt          |   42 ++++
 arch/arm/mach-exynos4/Kconfig                      |    7 +
 arch/arm/mach-exynos4/Makefile                     |    3 +-
 arch/arm/mach-exynos4/dma.c                        |  223 ++++++--------------
 arch/arm/plat-samsung/dma-ops.c                    |   15 +-
 arch/arm/plat-samsung/include/plat/dma-ops.h       |    1 +
 arch/arm/plat-samsung/include/plat/dma-pl330.h     |    3 +-
 drivers/dma/pl330.c                                |  133 ++++++++----
 include/linux/amba/pl330.h                         |   15 +-
 9 files changed, 216 insertions(+), 226 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/6] Add device tree support for PL330 dma controller driver
@ 2011-08-26  8:40 ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds device tree support for PL330 driver and uses it
to add device tree support for Samsung platforms, specifically Exynos4.

First patch moves the pl330_filter function from Samsung specific wrappers
to pl330 dma driver and also adds a check to ensure that the filter function
proceeds only if it the dma channel being investigated belongs to pl330
dma controller instance.

Second patch adds support to infer the direction of the dma transfer
using the direction specified with the transfer request instead of
including this information in the platform data. This simlifies the
addition of device tree support. Third patch simplifies the platform
data for Exynos4 pl330 dma controllers. Similar patches simplifying
the platform data for other Samsung platforms is under development.

Fourth patch adds device tree support for pl330 dma controller driver.
A dma channel is represented using a phandle of the dma controller
node and the channel id within that controller. Client driver request
a dma channel using the phandle and channel id pair. Correspondingly,
the pl330 filter function has been modified to lookup a channel based
on this value.

Fifth patch adds device tree support for Samsung's DMA engine wrappers.
Client drivers retrive the channel property from their device node and
pass it to the wrappers. The wrapper functions use the property value
as the filter function parameter. Sixth patch restricts the usage of
pl330 device and platform data instances to non-dt platforms.

This patchset is based on Linux 3.1-rc3 with following patch sets
applied.

* To use DMA generic APIs for Samsung DMA - v7 - (15 patches)
* ARM: Samsung: use dma-pl330 device name for clock (3 patches)
* ARM: S5P64X0: Add the devname for DMA clock.
* ARM: SAMSUNG: register the second instance of PL330 DMAC (3 patches)

Thomas Abraham (6):
  DMA: PL330: move filter function into driver
  DMA: PL330: Infer transfer direction from transfer request instead of platform data
  ARM: EXYNOS4: Modify platform data for pl330 driver
  DMA: PL330: Add device tree support
  ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
  ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build

 .../devicetree/bindings/dma/arm-pl330.txt          |   42 ++++
 arch/arm/mach-exynos4/Kconfig                      |    7 +
 arch/arm/mach-exynos4/Makefile                     |    3 +-
 arch/arm/mach-exynos4/dma.c                        |  223 ++++++--------------
 arch/arm/plat-samsung/dma-ops.c                    |   15 +-
 arch/arm/plat-samsung/include/plat/dma-ops.h       |    1 +
 arch/arm/plat-samsung/include/plat/dma-pl330.h     |    3 +-
 drivers/dma/pl330.c                                |  133 ++++++++----
 include/linux/amba/pl330.h                         |   15 +-
 9 files changed, 216 insertions(+), 226 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 1/6] DMA: PL330: move filter function into driver
  2011-08-26  8:40 ` Thomas Abraham
@ 2011-08-26  8:40   ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	vinod.koul, patches, jassisinghbrar, boojin.kim

The dma channel selection filter function is moved from plat-samsung
into the pl330 driver. In additon to that, a check is added in the
filter function to ensure that the channel on which the filter has
been invoked is pl330 channel instance (and avoid any incorrect
access of chan->private in a system with multiple types of DMA
drivers).

Suggested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/plat-samsung/dma-ops.c |    6 ------
 drivers/dma/pl330.c             |   15 +++++++++++++++
 include/linux/amba/pl330.h      |    2 ++
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 6e3d9ab..8d18425 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -17,12 +17,6 @@
 
 #include <mach/dma.h>
 
-static inline bool pl330_filter(struct dma_chan *chan, void *param)
-{
-	struct dma_pl330_peri *peri = chan->private;
-	return peri->peri_id == (unsigned)param;
-}
-
 static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
 				struct samsung_dma_info *info)
 {
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 95976cf..7df2516 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -116,6 +116,9 @@ struct dma_pl330_desc {
 	struct dma_pl330_chan *pchan;
 };
 
+/* forward declaration */
+static struct amba_driver pl330_driver;
+
 static inline struct dma_pl330_chan *
 to_pchan(struct dma_chan *ch)
 {
@@ -267,6 +270,18 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
 	tasklet_schedule(&pch->task);
 }
 
+bool pl330_filter(struct dma_chan *chan, void *param)
+{
+	struct dma_pl330_peri *peri;
+
+	if (chan->device->dev->driver != &pl330_driver.drv)
+		return false;
+
+	peri = chan->private;
+	return peri->peri_id == (unsigned)param;
+}
+EXPORT_SYMBOL(pl330_filter);
+
 static int pl330_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index d12f077..6db72da 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -12,6 +12,7 @@
 #ifndef	__AMBA_PL330_H_
 #define	__AMBA_PL330_H_
 
+#include <linux/dmaengine.h>
 #include <asm/hardware/pl330.h>
 
 struct dma_pl330_peri {
@@ -38,4 +39,5 @@ struct dma_pl330_platdata {
 	unsigned mcbuf_sz;
 };
 
+extern bool pl330_filter(struct dma_chan *chan, void *param);
 #endif	/* __AMBA_PL330_H_ */
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 1/6] DMA: PL330: move filter function into driver
@ 2011-08-26  8:40   ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

The dma channel selection filter function is moved from plat-samsung
into the pl330 driver. In additon to that, a check is added in the
filter function to ensure that the channel on which the filter has
been invoked is pl330 channel instance (and avoid any incorrect
access of chan->private in a system with multiple types of DMA
drivers).

Suggested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/plat-samsung/dma-ops.c |    6 ------
 drivers/dma/pl330.c             |   15 +++++++++++++++
 include/linux/amba/pl330.h      |    2 ++
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 6e3d9ab..8d18425 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -17,12 +17,6 @@
 
 #include <mach/dma.h>
 
-static inline bool pl330_filter(struct dma_chan *chan, void *param)
-{
-	struct dma_pl330_peri *peri = chan->private;
-	return peri->peri_id == (unsigned)param;
-}
-
 static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
 				struct samsung_dma_info *info)
 {
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 95976cf..7df2516 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -116,6 +116,9 @@ struct dma_pl330_desc {
 	struct dma_pl330_chan *pchan;
 };
 
+/* forward declaration */
+static struct amba_driver pl330_driver;
+
 static inline struct dma_pl330_chan *
 to_pchan(struct dma_chan *ch)
 {
@@ -267,6 +270,18 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
 	tasklet_schedule(&pch->task);
 }
 
+bool pl330_filter(struct dma_chan *chan, void *param)
+{
+	struct dma_pl330_peri *peri;
+
+	if (chan->device->dev->driver != &pl330_driver.drv)
+		return false;
+
+	peri = chan->private;
+	return peri->peri_id == (unsigned)param;
+}
+EXPORT_SYMBOL(pl330_filter);
+
 static int pl330_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index d12f077..6db72da 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -12,6 +12,7 @@
 #ifndef	__AMBA_PL330_H_
 #define	__AMBA_PL330_H_
 
+#include <linux/dmaengine.h>
 #include <asm/hardware/pl330.h>
 
 struct dma_pl330_peri {
@@ -38,4 +39,5 @@ struct dma_pl330_platdata {
 	unsigned mcbuf_sz;
 };
 
+extern bool pl330_filter(struct dma_chan *chan, void *param);
 #endif	/* __AMBA_PL330_H_ */
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 2/6] DMA: PL330: Infer transfer direction from transfer request instead of platform data
  2011-08-26  8:40   ` Thomas Abraham
@ 2011-08-26  8:40     ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	vinod.koul, patches, jassisinghbrar, boojin.kim

The transfer direction for a channel can be inferred from the transfer
request and the need for specifying transfer direction in platfrom data
can be eliminated. So the structure definition 'struct dma_pl330_peri'
is no longer required.

The channel's private data is set to point to a channel id specified in
the platform data (instead of an instance of type 'struct dma_pl330_peri').
The filter function is correspondingly modified to match the channel id.

With the 'struct dma_pl330_peri' removed from platform data, the dma
controller transfer capabilities cannot be inferred any more. Hence,
the dma controller capabilities is specified using platform data.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
---
 drivers/dma/pl330.c        |   65 +++++++++++---------------------------------
 include/linux/amba/pl330.h |   13 ++-------
 2 files changed, 19 insertions(+), 59 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 7df2516..9732995 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -272,13 +272,13 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
 
 bool pl330_filter(struct dma_chan *chan, void *param)
 {
-	struct dma_pl330_peri *peri;
+	u8 *peri_id;
 
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
-	peri = chan->private;
-	return peri->peri_id == (unsigned)param;
+	peri_id = chan->private;
+	return *peri_id == (unsigned)param;
 }
 EXPORT_SYMBOL(pl330_filter);
 
@@ -514,7 +514,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
 static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 {
 	struct dma_pl330_dmac *pdmac = pch->dmac;
-	struct dma_pl330_peri *peri = pch->chan.private;
+	u8 *peri_id = pch->chan.private;
 	struct dma_pl330_desc *desc;
 
 	/* Pluck one desc from the pool of DMAC */
@@ -539,13 +539,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 	desc->txd.cookie = 0;
 	async_tx_ack(&desc->txd);
 
-	if (peri) {
-		desc->req.rqtype = peri->rqtype;
-		desc->req.peri = pch->chan.chan_id;
-	} else {
-		desc->req.rqtype = MEMTOMEM;
-		desc->req.peri = 0;
-	}
+	desc->req.peri = peri_id ? pch->chan.chan_id : 0;
 
 	dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
 
@@ -632,12 +626,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
 	case DMA_TO_DEVICE:
 		desc->rqcfg.src_inc = 1;
 		desc->rqcfg.dst_inc = 0;
+		desc->req.rqtype = MEMTODEV;
 		src = dma_addr;
 		dst = pch->fifo_addr;
 		break;
 	case DMA_FROM_DEVICE:
 		desc->rqcfg.src_inc = 0;
 		desc->rqcfg.dst_inc = 1;
+		desc->req.rqtype = DEVTOMEM;
 		src = pch->fifo_addr;
 		dst = dma_addr;
 		break;
@@ -663,16 +659,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 {
 	struct dma_pl330_desc *desc;
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_peri *peri = chan->private;
 	struct pl330_info *pi;
 	int burst;
 
 	if (unlikely(!pch || !len))
 		return NULL;
 
-	if (peri && peri->rqtype != MEMTOMEM)
-		return NULL;
-
 	pi = &pch->dmac->pif;
 
 	desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
@@ -681,6 +673,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 
 	desc->rqcfg.src_inc = 1;
 	desc->rqcfg.dst_inc = 1;
+	desc->req.rqtype = MEMTOMEM;
 
 	/* Select max possible burst size */
 	burst = pi->pcfg.data_bus_width / 8;
@@ -709,24 +702,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 {
 	struct dma_pl330_desc *first, *desc = NULL;
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_peri *peri = chan->private;
 	struct scatterlist *sg;
 	unsigned long flags;
 	int i;
 	dma_addr_t addr;
 
-	if (unlikely(!pch || !sgl || !sg_len || !peri))
-		return NULL;
-
-	/* Make sure the direction is consistent */
-	if ((direction == DMA_TO_DEVICE &&
-				peri->rqtype != MEMTODEV) ||
-			(direction == DMA_FROM_DEVICE &&
-				peri->rqtype != DEVTOMEM)) {
-		dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
-				__func__, __LINE__);
+	if (unlikely(!pch || !sgl || !sg_len))
 		return NULL;
-	}
 
 	addr = pch->fifo_addr;
 
@@ -767,11 +749,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 		if (direction == DMA_TO_DEVICE) {
 			desc->rqcfg.src_inc = 1;
 			desc->rqcfg.dst_inc = 0;
+			desc->req.rqtype = MEMTODEV;
 			fill_px(&desc->px,
 				addr, sg_dma_address(sg), sg_dma_len(sg));
 		} else {
 			desc->rqcfg.src_inc = 0;
 			desc->rqcfg.dst_inc = 1;
+			desc->req.rqtype = DEVTOMEM;
 			fill_px(&desc->px,
 				sg_dma_address(sg), addr, sg_dma_len(sg));
 		}
@@ -878,28 +862,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		if (pdat) {
-			struct dma_pl330_peri *peri = &pdat->peri[i];
-
-			switch (peri->rqtype) {
-			case MEMTOMEM:
-				dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-				break;
-			case MEMTODEV:
-			case DEVTOMEM:
-				dma_cap_set(DMA_SLAVE, pd->cap_mask);
-				dma_cap_set(DMA_CYCLIC, pd->cap_mask);
-				break;
-			default:
-				dev_err(&adev->dev, "DEVTODEV Not Supported\n");
-				continue;
-			}
-			pch->chan.private = peri;
-		} else {
-			dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-			pch->chan.private = NULL;
-		}
-
+		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -913,6 +876,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 
 	pd->dev = &adev->dev;
+	if (pdat)
+		pd->cap_mask = pdat->cap_mask;
+	else
+		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index 6db72da..12e023c 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -15,15 +15,6 @@
 #include <linux/dmaengine.h>
 #include <asm/hardware/pl330.h>
 
-struct dma_pl330_peri {
-	/*
-	 * Peri_Req i/f of the DMAC that is
-	 * peripheral could be reached from.
-	 */
-	u8 peri_id; /* specific dma id */
-	enum pl330_reqtype rqtype;
-};
-
 struct dma_pl330_platdata {
 	/*
 	 * Number of valid peripherals connected to DMAC.
@@ -34,7 +25,9 @@ struct dma_pl330_platdata {
 	 */
 	u8 nr_valid_peri;
 	/* Array of valid peripherals */
-	struct dma_pl330_peri *peri;
+	u8 *peri_id;
+	/* Operational capabilities */
+	dma_cap_mask_t cap_mask;
 	/* Bytes to allocate for MC buffer */
 	unsigned mcbuf_sz;
 };
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 2/6] DMA: PL330: Infer transfer direction from transfer request instead of platform data
@ 2011-08-26  8:40     ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

The transfer direction for a channel can be inferred from the transfer
request and the need for specifying transfer direction in platfrom data
can be eliminated. So the structure definition 'struct dma_pl330_peri'
is no longer required.

The channel's private data is set to point to a channel id specified in
the platform data (instead of an instance of type 'struct dma_pl330_peri').
The filter function is correspondingly modified to match the channel id.

With the 'struct dma_pl330_peri' removed from platform data, the dma
controller transfer capabilities cannot be inferred any more. Hence,
the dma controller capabilities is specified using platform data.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
---
 drivers/dma/pl330.c        |   65 +++++++++++---------------------------------
 include/linux/amba/pl330.h |   13 ++-------
 2 files changed, 19 insertions(+), 59 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 7df2516..9732995 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -272,13 +272,13 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
 
 bool pl330_filter(struct dma_chan *chan, void *param)
 {
-	struct dma_pl330_peri *peri;
+	u8 *peri_id;
 
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
-	peri = chan->private;
-	return peri->peri_id == (unsigned)param;
+	peri_id = chan->private;
+	return *peri_id == (unsigned)param;
 }
 EXPORT_SYMBOL(pl330_filter);
 
@@ -514,7 +514,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
 static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 {
 	struct dma_pl330_dmac *pdmac = pch->dmac;
-	struct dma_pl330_peri *peri = pch->chan.private;
+	u8 *peri_id = pch->chan.private;
 	struct dma_pl330_desc *desc;
 
 	/* Pluck one desc from the pool of DMAC */
@@ -539,13 +539,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 	desc->txd.cookie = 0;
 	async_tx_ack(&desc->txd);
 
-	if (peri) {
-		desc->req.rqtype = peri->rqtype;
-		desc->req.peri = pch->chan.chan_id;
-	} else {
-		desc->req.rqtype = MEMTOMEM;
-		desc->req.peri = 0;
-	}
+	desc->req.peri = peri_id ? pch->chan.chan_id : 0;
 
 	dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
 
@@ -632,12 +626,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
 	case DMA_TO_DEVICE:
 		desc->rqcfg.src_inc = 1;
 		desc->rqcfg.dst_inc = 0;
+		desc->req.rqtype = MEMTODEV;
 		src = dma_addr;
 		dst = pch->fifo_addr;
 		break;
 	case DMA_FROM_DEVICE:
 		desc->rqcfg.src_inc = 0;
 		desc->rqcfg.dst_inc = 1;
+		desc->req.rqtype = DEVTOMEM;
 		src = pch->fifo_addr;
 		dst = dma_addr;
 		break;
@@ -663,16 +659,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 {
 	struct dma_pl330_desc *desc;
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_peri *peri = chan->private;
 	struct pl330_info *pi;
 	int burst;
 
 	if (unlikely(!pch || !len))
 		return NULL;
 
-	if (peri && peri->rqtype != MEMTOMEM)
-		return NULL;
-
 	pi = &pch->dmac->pif;
 
 	desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
@@ -681,6 +673,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 
 	desc->rqcfg.src_inc = 1;
 	desc->rqcfg.dst_inc = 1;
+	desc->req.rqtype = MEMTOMEM;
 
 	/* Select max possible burst size */
 	burst = pi->pcfg.data_bus_width / 8;
@@ -709,24 +702,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 {
 	struct dma_pl330_desc *first, *desc = NULL;
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_peri *peri = chan->private;
 	struct scatterlist *sg;
 	unsigned long flags;
 	int i;
 	dma_addr_t addr;
 
-	if (unlikely(!pch || !sgl || !sg_len || !peri))
-		return NULL;
-
-	/* Make sure the direction is consistent */
-	if ((direction == DMA_TO_DEVICE &&
-				peri->rqtype != MEMTODEV) ||
-			(direction == DMA_FROM_DEVICE &&
-				peri->rqtype != DEVTOMEM)) {
-		dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
-				__func__, __LINE__);
+	if (unlikely(!pch || !sgl || !sg_len))
 		return NULL;
-	}
 
 	addr = pch->fifo_addr;
 
@@ -767,11 +749,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 		if (direction == DMA_TO_DEVICE) {
 			desc->rqcfg.src_inc = 1;
 			desc->rqcfg.dst_inc = 0;
+			desc->req.rqtype = MEMTODEV;
 			fill_px(&desc->px,
 				addr, sg_dma_address(sg), sg_dma_len(sg));
 		} else {
 			desc->rqcfg.src_inc = 0;
 			desc->rqcfg.dst_inc = 1;
+			desc->req.rqtype = DEVTOMEM;
 			fill_px(&desc->px,
 				sg_dma_address(sg), addr, sg_dma_len(sg));
 		}
@@ -878,28 +862,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		if (pdat) {
-			struct dma_pl330_peri *peri = &pdat->peri[i];
-
-			switch (peri->rqtype) {
-			case MEMTOMEM:
-				dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-				break;
-			case MEMTODEV:
-			case DEVTOMEM:
-				dma_cap_set(DMA_SLAVE, pd->cap_mask);
-				dma_cap_set(DMA_CYCLIC, pd->cap_mask);
-				break;
-			default:
-				dev_err(&adev->dev, "DEVTODEV Not Supported\n");
-				continue;
-			}
-			pch->chan.private = peri;
-		} else {
-			dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-			pch->chan.private = NULL;
-		}
-
+		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -913,6 +876,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 
 	pd->dev = &adev->dev;
+	if (pdat)
+		pd->cap_mask = pdat->cap_mask;
+	else
+		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index 6db72da..12e023c 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -15,15 +15,6 @@
 #include <linux/dmaengine.h>
 #include <asm/hardware/pl330.h>
 
-struct dma_pl330_peri {
-	/*
-	 * Peri_Req i/f of the DMAC that is
-	 * peripheral could be reached from.
-	 */
-	u8 peri_id; /* specific dma id */
-	enum pl330_reqtype rqtype;
-};
-
 struct dma_pl330_platdata {
 	/*
 	 * Number of valid peripherals connected to DMAC.
@@ -34,7 +25,9 @@ struct dma_pl330_platdata {
 	 */
 	u8 nr_valid_peri;
 	/* Array of valid peripherals */
-	struct dma_pl330_peri *peri;
+	u8 *peri_id;
+	/* Operational capabilities */
+	dma_cap_mask_t cap_mask;
 	/* Bytes to allocate for MC buffer */
 	unsigned mcbuf_sz;
 };
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 3/6] ARM: EXYNOS4: Modify platform data for pl330 driver
  2011-08-26  8:40     ` Thomas Abraham
@ 2011-08-26  8:40       ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	vinod.koul, patches, jassisinghbrar, boojin.kim

With the 'struct dma_pl330_peri' removed, the platfrom data for dma
driver can be simplified to a simple list of peripheral request ids.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/mach-exynos4/dma.c |  223 ++++++++++++-------------------------------
 1 files changed, 62 insertions(+), 161 deletions(-)

diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index 9667c61..c3c0d17 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -35,95 +35,40 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-struct dma_pl330_peri pdma0_peri[28] = {
-	{
-		.peri_id = (u8)DMACH_PCM0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_PCM2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ0,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ2,
-	}, {
-		.peri_id = (u8)DMACH_SPI0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SPI2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0S_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART4_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART4_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS4_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS4_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_AC97_MICIN,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_AC97_PCMIN,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_AC97_PCMOUT,
-		.rqtype = MEMTODEV,
-	},
+u8 pdma0_peri[] = {
+	DMACH_PCM0_RX,
+	DMACH_PCM0_TX,
+	DMACH_PCM2_RX,
+	DMACH_PCM2_TX,
+	DMACH_MSM_REQ0,
+	DMACH_MSM_REQ2,
+	DMACH_SPI0_RX,
+	DMACH_SPI0_TX,
+	DMACH_SPI2_RX,
+	DMACH_SPI2_TX,
+	DMACH_I2S0S_TX,
+	DMACH_I2S0_RX,
+	DMACH_I2S0_TX,
+	DMACH_UART0_RX,
+	DMACH_UART0_TX,
+	DMACH_UART2_RX,
+	DMACH_UART2_TX,
+	DMACH_UART4_RX,
+	DMACH_UART4_TX,
+	DMACH_SLIMBUS0_RX,
+	DMACH_SLIMBUS0_TX,
+	DMACH_SLIMBUS2_RX,
+	DMACH_SLIMBUS2_TX,
+	DMACH_SLIMBUS4_RX,
+	DMACH_SLIMBUS4_TX,
+	DMACH_AC97_MICIN,
+	DMACH_AC97_PCMIN,
+	DMACH_AC97_PCMOUT,
 };
 
 struct dma_pl330_platdata exynos4_pdma0_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma0_peri),
-	.peri = pdma0_peri,
+	.peri_id = pdma0_peri,
 };
 
 struct amba_device exynos4_device_pdma0 = {
@@ -142,86 +87,37 @@ struct amba_device exynos4_device_pdma0 = {
 	.periphid = 0x00041330,
 };
 
-struct dma_pl330_peri pdma1_peri[25] = {
-	{
-		.peri_id = (u8)DMACH_PCM0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_PCM1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ1,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ3,
-	}, {
-		.peri_id = (u8)DMACH_SPI1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0S_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART3_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART3_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS3_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS3_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS5_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS5_TX,
-		.rqtype = MEMTODEV,
-	},
+u8 pdma1_peri[] = {
+	DMACH_PCM0_RX,
+	DMACH_PCM0_TX,
+	DMACH_PCM1_RX,
+	DMACH_PCM1_TX,
+	DMACH_MSM_REQ1,
+	DMACH_MSM_REQ3,
+	DMACH_SPI1_RX,
+	DMACH_SPI1_TX,
+	DMACH_I2S0S_TX,
+	DMACH_I2S0_RX,
+	DMACH_I2S0_TX,
+	DMACH_I2S1_RX,
+	DMACH_I2S1_TX,
+	DMACH_UART0_RX,
+	DMACH_UART0_TX,
+	DMACH_UART1_RX,
+	DMACH_UART1_TX,
+	DMACH_UART3_RX,
+	DMACH_UART3_TX,
+	DMACH_SLIMBUS1_RX,
+	DMACH_SLIMBUS1_TX,
+	DMACH_SLIMBUS3_RX,
+	DMACH_SLIMBUS3_TX,
+	DMACH_SLIMBUS5_RX,
+	DMACH_SLIMBUS5_TX,
 };
 
 struct dma_pl330_platdata exynos4_pdma1_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma1_peri),
-	.peri = pdma1_peri,
+	.peri_id = pdma1_peri,
 };
 
 struct amba_device exynos4_device_pdma1 = {
@@ -242,7 +138,12 @@ struct amba_device exynos4_device_pdma1 = {
 
 static int __init exynos4_dma_init(void)
 {
+	dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
+	dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
 	amba_device_register(&exynos4_device_pdma0, &iomem_resource);
+
+	dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
+	dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
 	amba_device_register(&exynos4_device_pdma1, &iomem_resource);
 
 	return 0;
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 3/6] ARM: EXYNOS4: Modify platform data for pl330 driver
@ 2011-08-26  8:40       ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

With the 'struct dma_pl330_peri' removed, the platfrom data for dma
driver can be simplified to a simple list of peripheral request ids.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/mach-exynos4/dma.c |  223 ++++++++++++-------------------------------
 1 files changed, 62 insertions(+), 161 deletions(-)

diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index 9667c61..c3c0d17 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -35,95 +35,40 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-struct dma_pl330_peri pdma0_peri[28] = {
-	{
-		.peri_id = (u8)DMACH_PCM0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_PCM2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ0,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ2,
-	}, {
-		.peri_id = (u8)DMACH_SPI0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SPI2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0S_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART4_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART4_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS4_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS4_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_AC97_MICIN,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_AC97_PCMIN,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_AC97_PCMOUT,
-		.rqtype = MEMTODEV,
-	},
+u8 pdma0_peri[] = {
+	DMACH_PCM0_RX,
+	DMACH_PCM0_TX,
+	DMACH_PCM2_RX,
+	DMACH_PCM2_TX,
+	DMACH_MSM_REQ0,
+	DMACH_MSM_REQ2,
+	DMACH_SPI0_RX,
+	DMACH_SPI0_TX,
+	DMACH_SPI2_RX,
+	DMACH_SPI2_TX,
+	DMACH_I2S0S_TX,
+	DMACH_I2S0_RX,
+	DMACH_I2S0_TX,
+	DMACH_UART0_RX,
+	DMACH_UART0_TX,
+	DMACH_UART2_RX,
+	DMACH_UART2_TX,
+	DMACH_UART4_RX,
+	DMACH_UART4_TX,
+	DMACH_SLIMBUS0_RX,
+	DMACH_SLIMBUS0_TX,
+	DMACH_SLIMBUS2_RX,
+	DMACH_SLIMBUS2_TX,
+	DMACH_SLIMBUS4_RX,
+	DMACH_SLIMBUS4_TX,
+	DMACH_AC97_MICIN,
+	DMACH_AC97_PCMIN,
+	DMACH_AC97_PCMOUT,
 };
 
 struct dma_pl330_platdata exynos4_pdma0_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma0_peri),
-	.peri = pdma0_peri,
+	.peri_id = pdma0_peri,
 };
 
 struct amba_device exynos4_device_pdma0 = {
@@ -142,86 +87,37 @@ struct amba_device exynos4_device_pdma0 = {
 	.periphid = 0x00041330,
 };
 
-struct dma_pl330_peri pdma1_peri[25] = {
-	{
-		.peri_id = (u8)DMACH_PCM0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_PCM1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ1,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ3,
-	}, {
-		.peri_id = (u8)DMACH_SPI1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0S_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART3_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART3_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS3_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS3_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS5_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS5_TX,
-		.rqtype = MEMTODEV,
-	},
+u8 pdma1_peri[] = {
+	DMACH_PCM0_RX,
+	DMACH_PCM0_TX,
+	DMACH_PCM1_RX,
+	DMACH_PCM1_TX,
+	DMACH_MSM_REQ1,
+	DMACH_MSM_REQ3,
+	DMACH_SPI1_RX,
+	DMACH_SPI1_TX,
+	DMACH_I2S0S_TX,
+	DMACH_I2S0_RX,
+	DMACH_I2S0_TX,
+	DMACH_I2S1_RX,
+	DMACH_I2S1_TX,
+	DMACH_UART0_RX,
+	DMACH_UART0_TX,
+	DMACH_UART1_RX,
+	DMACH_UART1_TX,
+	DMACH_UART3_RX,
+	DMACH_UART3_TX,
+	DMACH_SLIMBUS1_RX,
+	DMACH_SLIMBUS1_TX,
+	DMACH_SLIMBUS3_RX,
+	DMACH_SLIMBUS3_TX,
+	DMACH_SLIMBUS5_RX,
+	DMACH_SLIMBUS5_TX,
 };
 
 struct dma_pl330_platdata exynos4_pdma1_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma1_peri),
-	.peri = pdma1_peri,
+	.peri_id = pdma1_peri,
 };
 
 struct amba_device exynos4_device_pdma1 = {
@@ -242,7 +138,12 @@ struct amba_device exynos4_device_pdma1 = {
 
 static int __init exynos4_dma_init(void)
 {
+	dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
+	dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
 	amba_device_register(&exynos4_device_pdma0, &iomem_resource);
+
+	dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
+	dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
 	amba_device_register(&exynos4_device_pdma1, &iomem_resource);
 
 	return 0;
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-26  8:40       ` Thomas Abraham
@ 2011-08-26  8:40         ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	vinod.koul, patches, jassisinghbrar, boojin.kim

For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.

Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 .../devicetree/bindings/dma/arm-pl330.txt          |   42 +++++++++++++
 drivers/dma/pl330.c                                |   63 +++++++++++++++++++-
 2 files changed, 103 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..46a8307
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,42 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+  - compatible: should one or more of the following
+    - arm,pl330-pdma - For controllers that support mem-to-dev and dev-to-mem
+      transfers.
+    - arm,pl330-mdma - For controllers that support mem-to-mem transfers only.
+    - arm,primecell - should be included for all pl330 dma controller nodes.
+
+  - reg: physical base address of the controller and length of memory mapped
+    region.
+
+  - interrupts: interrupt number to the cpu.
+
+  - arm,primecell-periphid: should be 0x00041330.
+
+  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
+    dma controller. Maximum value is 32.
+
+Example: (from Samsung's Exynos4 processor dtsi file)
+
+	pdma0: pdma@12680000 {
+		compatible = "arm,pl330-pdma", "arm,primecell";
+		reg = <0x12680000 0x1000>;
+		interrupts = <99>;
+		arm,primecell-periphid = <0x00041330>;
+		arm,pl330-peri-reqs = <30>;
+	};
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+  [property name]  = <[phandle of the dma controller] [dma request id]>;
+
+      where 'dma request id' is the dma request number which is connected
+      to the client controller.
+
+  Example:  tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9732995..984dc18 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
 #include <linux/amba/pl330.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
+#include <linux/of.h>
 
 #define NR_DEFAULT_DESC	16
 
@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
+#ifdef CONFIG_OF
+	if (chan->device->dev->of_node) {
+		const __be32 *prop_value;
+		phandle phandle;
+		struct device_node *node;
+
+		prop_value = ((struct property *)param)->value;
+		phandle = be32_to_cpup(prop_value++);
+		node = of_find_node_by_phandle(phandle);
+		return ((chan->private == node) &&
+				(chan->chan_id == be32_to_cpup(prop_value)));
+	}
+#endif
+
 	peri_id = chan->private;
 	return *peri_id == (unsigned)param;
 }
@@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
 		return IRQ_NONE;
 }
 
+#ifdef CONFIG_OF
+static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
+{
+	struct dma_pl330_platdata *pdat;
+	const void *value;
+
+	pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
+	if (!pdat)
+		return NULL;
+
+	value = of_get_property(dev->of_node, "arm,pl330-peri-reqs", NULL);
+	if (value)
+		pdat->nr_valid_peri = be32_to_cpup(value);
+
+	if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
+		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
+		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
+	} else if (of_device_is_compatible(dev->of_node, "arm,pl330-mdma")) {
+		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
+	} else if (of_device_is_compatible(dev->of_node, "arm,primecell")) {
+		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
+		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
+		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
+	}
+
+	return pdat;
+}
+#else
+static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif
+
 static int __devinit
 pl330_probe(struct amba_device *adev, const struct amba_id *id)
 {
@@ -789,7 +838,13 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	int i, ret, irq;
 	int num_chan;
 
-	pdat = adev->dev.platform_data;
+	if (adev->dev.of_node) {
+		pdat = pl330_parse_dt(&adev->dev);
+		if (!pdat)
+			return -ENOMEM;
+	} else {
+		pdat = adev->dev.platform_data;
+	}
 
 	/* Allocate a new DMAC and its Channels */
 	pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
@@ -862,7 +917,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		if (!adev->dev.of_node)
+			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		else
+			pch->chan.private = adev->dev.of_node;
+
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-26  8:40         ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.

Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 .../devicetree/bindings/dma/arm-pl330.txt          |   42 +++++++++++++
 drivers/dma/pl330.c                                |   63 +++++++++++++++++++-
 2 files changed, 103 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..46a8307
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,42 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+  - compatible: should one or more of the following
+    - arm,pl330-pdma - For controllers that support mem-to-dev and dev-to-mem
+      transfers.
+    - arm,pl330-mdma - For controllers that support mem-to-mem transfers only.
+    - arm,primecell - should be included for all pl330 dma controller nodes.
+
+  - reg: physical base address of the controller and length of memory mapped
+    region.
+
+  - interrupts: interrupt number to the cpu.
+
+  - arm,primecell-periphid: should be 0x00041330.
+
+  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
+    dma controller. Maximum value is 32.
+
+Example: (from Samsung's Exynos4 processor dtsi file)
+
+	pdma0: pdma at 12680000 {
+		compatible = "arm,pl330-pdma", "arm,primecell";
+		reg = <0x12680000 0x1000>;
+		interrupts = <99>;
+		arm,primecell-periphid = <0x00041330>;
+		arm,pl330-peri-reqs = <30>;
+	};
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+  [property name]  = <[phandle of the dma controller] [dma request id]>;
+
+      where 'dma request id' is the dma request number which is connected
+      to the client controller.
+
+  Example:  tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9732995..984dc18 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
 #include <linux/amba/pl330.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
+#include <linux/of.h>
 
 #define NR_DEFAULT_DESC	16
 
@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
+#ifdef CONFIG_OF
+	if (chan->device->dev->of_node) {
+		const __be32 *prop_value;
+		phandle phandle;
+		struct device_node *node;
+
+		prop_value = ((struct property *)param)->value;
+		phandle = be32_to_cpup(prop_value++);
+		node = of_find_node_by_phandle(phandle);
+		return ((chan->private == node) &&
+				(chan->chan_id == be32_to_cpup(prop_value)));
+	}
+#endif
+
 	peri_id = chan->private;
 	return *peri_id == (unsigned)param;
 }
@@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
 		return IRQ_NONE;
 }
 
+#ifdef CONFIG_OF
+static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
+{
+	struct dma_pl330_platdata *pdat;
+	const void *value;
+
+	pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
+	if (!pdat)
+		return NULL;
+
+	value = of_get_property(dev->of_node, "arm,pl330-peri-reqs", NULL);
+	if (value)
+		pdat->nr_valid_peri = be32_to_cpup(value);
+
+	if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
+		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
+		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
+	} else if (of_device_is_compatible(dev->of_node, "arm,pl330-mdma")) {
+		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
+	} else if (of_device_is_compatible(dev->of_node, "arm,primecell")) {
+		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
+		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
+		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
+	}
+
+	return pdat;
+}
+#else
+static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif
+
 static int __devinit
 pl330_probe(struct amba_device *adev, const struct amba_id *id)
 {
@@ -789,7 +838,13 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	int i, ret, irq;
 	int num_chan;
 
-	pdat = adev->dev.platform_data;
+	if (adev->dev.of_node) {
+		pdat = pl330_parse_dt(&adev->dev);
+		if (!pdat)
+			return -ENOMEM;
+	} else {
+		pdat = adev->dev.platform_data;
+	}
 
 	/* Allocate a new DMAC and its Channels */
 	pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
@@ -862,7 +917,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		if (!adev->dev.of_node)
+			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		else
+			pch->chan.private = adev->dev.of_node;
+
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 5/6] ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
  2011-08-26  8:40         ` Thomas Abraham
@ 2011-08-26  8:40           ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	vinod.koul, patches, jassisinghbrar, boojin.kim

A new dma request id 'DMACH_DT_PROP' is introduced for client drivers
requesting a dma channel. This request indicates that a device tree
node property represting the dma channel is available in
'struct samsung_dma_info'. The dma channel request wrapper uses the
node property value as the value for the filter parameter.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/plat-samsung/dma-ops.c                |    9 ++++++++-
 arch/arm/plat-samsung/include/plat/dma-ops.h   |    1 +
 arch/arm/plat-samsung/include/plat/dma-pl330.h |    3 ++-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 8d18425..b1135dd 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -23,11 +23,18 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
 	struct dma_chan *chan;
 	dma_cap_mask_t mask;
 	struct dma_slave_config slave_config;
+	void *filter_param;
 
 	dma_cap_zero(mask);
 	dma_cap_set(info->cap, mask);
 
-	chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch);
+	/*
+	 * If a dma channel property of a device node from device tree is
+	 * specified, use that as the fliter parameter.
+	 */
+	filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
+				(void *)dma_ch;
+	chan = dma_request_channel(mask, pl330_filter, filter_param);
 
 	if (info->direction == DMA_FROM_DEVICE) {
 		memset(&slave_config, 0, sizeof(struct dma_slave_config));
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
index 4c1a363..22eafc3 100644
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -31,6 +31,7 @@ struct samsung_dma_info {
 	enum dma_slave_buswidth width;
 	dma_addr_t fifo;
 	struct s3c2410_dma_client *client;
+	struct property *dt_dmach_prop;
 };
 
 struct samsung_dma_ops {
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 2e55e59..c5eaad5 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -21,7 +21,8 @@
  * use these just as IDs.
  */
 enum dma_ch {
-	DMACH_UART0_RX,
+	DMACH_DT_PROP = -1,
+	DMACH_UART0_RX = 0,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
 	DMACH_UART1_TX,
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 5/6] ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
@ 2011-08-26  8:40           ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

A new dma request id 'DMACH_DT_PROP' is introduced for client drivers
requesting a dma channel. This request indicates that a device tree
node property represting the dma channel is available in
'struct samsung_dma_info'. The dma channel request wrapper uses the
node property value as the value for the filter parameter.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/plat-samsung/dma-ops.c                |    9 ++++++++-
 arch/arm/plat-samsung/include/plat/dma-ops.h   |    1 +
 arch/arm/plat-samsung/include/plat/dma-pl330.h |    3 ++-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 8d18425..b1135dd 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -23,11 +23,18 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
 	struct dma_chan *chan;
 	dma_cap_mask_t mask;
 	struct dma_slave_config slave_config;
+	void *filter_param;
 
 	dma_cap_zero(mask);
 	dma_cap_set(info->cap, mask);
 
-	chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch);
+	/*
+	 * If a dma channel property of a device node from device tree is
+	 * specified, use that as the fliter parameter.
+	 */
+	filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
+				(void *)dma_ch;
+	chan = dma_request_channel(mask, pl330_filter, filter_param);
 
 	if (info->direction == DMA_FROM_DEVICE) {
 		memset(&slave_config, 0, sizeof(struct dma_slave_config));
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
index 4c1a363..22eafc3 100644
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -31,6 +31,7 @@ struct samsung_dma_info {
 	enum dma_slave_buswidth width;
 	dma_addr_t fifo;
 	struct s3c2410_dma_client *client;
+	struct property *dt_dmach_prop;
 };
 
 struct samsung_dma_ops {
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 2e55e59..c5eaad5 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -21,7 +21,8 @@
  * use these just as IDs.
  */
 enum dma_ch {
-	DMACH_UART0_RX,
+	DMACH_DT_PROP = -1,
+	DMACH_UART0_RX = 0,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
 	DMACH_UART1_TX,
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 6/6] ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build
  2011-08-26  8:40           ` Thomas Abraham
@ 2011-08-26  8:40             ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	vinod.koul, patches, jassisinghbrar, boojin.kim

The pl330 device instances and associated platform data is required only
for non-device-tree builds. With device tree, all of this information is
obtained from the device tree.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/mach-exynos4/Kconfig  |    7 +++++++
 arch/arm/mach-exynos4/Makefile |    3 ++-
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index d4d401c..3edbf37 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -21,6 +21,13 @@ config EXYNOS4_MCT
 	help
 	  Use MCT (Multi Core Timer) as kernel timers
 
+config EXYNOS4_DEV_DMA
+	bool
+	default y if !OF
+	help
+	  Compile in amba device definitions for DMA controller if OF
+	  is not enabled.
+
 config EXYNOS4_DEV_AHCI
 	bool
 	help
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index d2bf5bf..a2f33dc 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -13,7 +13,8 @@ obj-				:=
 # Core support for EXYNOS4 system
 
 obj-$(CONFIG_CPU_EXYNOS4210)	+= cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o dma.o pmu.o
+obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o pmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DMA)	+= dma.o
 obj-$(CONFIG_PM)		+= pm.o sleep.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 6/6] ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build
@ 2011-08-26  8:40             ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-26  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

The pl330 device instances and associated platform data is required only
for non-device-tree builds. With device tree, all of this information is
obtained from the device tree.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/mach-exynos4/Kconfig  |    7 +++++++
 arch/arm/mach-exynos4/Makefile |    3 ++-
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index d4d401c..3edbf37 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -21,6 +21,13 @@ config EXYNOS4_MCT
 	help
 	  Use MCT (Multi Core Timer) as kernel timers
 
+config EXYNOS4_DEV_DMA
+	bool
+	default y if !OF
+	help
+	  Compile in amba device definitions for DMA controller if OF
+	  is not enabled.
+
 config EXYNOS4_DEV_AHCI
 	bool
 	help
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index d2bf5bf..a2f33dc 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -13,7 +13,8 @@ obj-				:=
 # Core support for EXYNOS4 system
 
 obj-$(CONFIG_CPU_EXYNOS4210)	+= cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o dma.o pmu.o
+obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o pmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DMA)	+= dma.o
 obj-$(CONFIG_PM)		+= pm.o sleep.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-26  8:40         ` Thomas Abraham
@ 2011-08-26 13:16           ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-26 13:16 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches, vinod.koul,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Thomas,

On 08/26/2011 03:40 AM, Thomas Abraham wrote:
> For PL330 dma controllers instantiated from device tree, the channel
> lookup is based on phandle of the dma controller and dma request id
> specified by the client node. During probe, the private data of each
> channel of the controller is set to point to the device node of the
> dma controller. The 'chan_id' of the each channel is used as the
> dma request id.
> 
> Client driver requesting dma channels specify the phandle of the
> dma controller and the request id. The pl330 filter function
> converts the phandle to the device node pointer and matches that
> with channel's private data. If a match is found, the request id
> from the client node and the 'chan_id' of the channel is matched.
> A channel is found if both the values match.
> 
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  .../devicetree/bindings/dma/arm-pl330.txt          |   42 +++++++++++++
>  drivers/dma/pl330.c                                |   63 +++++++++++++++++++-
>  2 files changed, 103 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> new file mode 100644
> index 0000000..46a8307
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> @@ -0,0 +1,42 @@
> +* ARM PrimeCell PL330 DMA Controller
> +
> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
> +between memory and peripherals or memory to memory.
> +
> +Required properties:
> +  - compatible: should one or more of the following
> +    - arm,pl330-pdma - For controllers that support mem-to-dev and dev-to-mem
> +      transfers.
> +    - arm,pl330-mdma - For controllers that support mem-to-mem transfers only.

And if they support both? I would think all controllers can support
mem-to-mem. If so, the distinction can be made with the number of requests.

> +    - arm,primecell - should be included for all pl330 dma controller nodes.
> +
> +  - reg: physical base address of the controller and length of memory mapped
> +    region.
> +
> +  - interrupts: interrupt number to the cpu.
> +
> +  - arm,primecell-periphid: should be 0x00041330.

Should be optional. It's only needed when the h/w value is wrong. This
is already documented in primecell.txt.

> +
> +  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
> +    dma controller. Maximum value is 32.

Perhaps could be a bitmask for sparsely populated requests. May not
matter since phandles will define the connections.

Can be optional and not present means 00 requests (mem-to-mem only).

> +
> +Example: (from Samsung's Exynos4 processor dtsi file)
> +
> +	pdma0: pdma@12680000 {
> +		compatible = "arm,pl330-pdma", "arm,primecell";
> +		reg = <0x12680000 0x1000>;
> +		interrupts = <99>;
> +		arm,primecell-periphid = <0x00041330>;
> +		arm,pl330-peri-reqs = <30>;
> +	};
> +
> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
> +as shown below.
> +
> +  [property name]  = <[phandle of the dma controller] [dma request id]>;
> +
> +      where 'dma request id' is the dma request number which is connected
> +      to the client controller.
> +
> +  Example:  tx-dma-channel = <&pdma0 12>;

I like this approach. I looked at this some and some PPC platforms do a
node for each channel/request, but this is much more simple and similar
to clock binding approach.

You need to define the property name. Probably just "dma-channel" is
enough. For peripherals with more than 1, just list them out like when
you have more than 1 interrupt. The order should be defined as part of
that device's binding (i.e. 1st channel is tx and 2nd channel is rx).

> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 9732995..984dc18 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -19,6 +19,7 @@
>  #include <linux/amba/pl330.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> +#include <linux/of.h>
>  
>  #define NR_DEFAULT_DESC	16
>  
> @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
>  	if (chan->device->dev->driver != &pl330_driver.drv)
>  		return false;
>  
> +#ifdef CONFIG_OF
> +	if (chan->device->dev->of_node) {
> +		const __be32 *prop_value;
> +		phandle phandle;
> +		struct device_node *node;
> +
> +		prop_value = ((struct property *)param)->value;
> +		phandle = be32_to_cpup(prop_value++);
> +		node = of_find_node_by_phandle(phandle);
> +		return ((chan->private == node) &&
> +				(chan->chan_id == be32_to_cpup(prop_value)));
> +	}
> +#endif
> +
>  	peri_id = chan->private;
>  	return *peri_id == (unsigned)param;
>  }
> @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
>  		return IRQ_NONE;
>  }
>  
> +#ifdef CONFIG_OF
> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
> +{
> +	struct dma_pl330_platdata *pdat;
> +	const void *value;
> +
> +	pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
> +	if (!pdat)
> +		return NULL;

Ideally, we will get rid of platform_data completely in the future, so I
don't think filling it in from DT is the right approach.

> +
> +	value = of_get_property(dev->of_node, "arm,pl330-peri-reqs", NULL);
> +	if (value)
> +		pdat->nr_valid_peri = be32_to_cpup(value);

Can't you use the u32 helper function here?

> +
> +	if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
> +		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
> +		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
> +	} else if (of_device_is_compatible(dev->of_node, "arm,pl330-mdma")) {
> +		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
> +	} else if (of_device_is_compatible(dev->of_node, "arm,primecell")) {

I don't think the driver should look at this property. This is really
just for the bus code.

Rob

> +		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
> +		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
> +		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
> +	}
> +
> +	return pdat;
> +}
> +#else
> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
> +{
> +	return NULL;
> +}
> +#endif
> +
>  static int __devinit
>  pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  {
> @@ -789,7 +838,13 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  	int i, ret, irq;
>  	int num_chan;
>  
> -	pdat = adev->dev.platform_data;
> +	if (adev->dev.of_node) {
> +		pdat = pl330_parse_dt(&adev->dev);
> +		if (!pdat)
> +			return -ENOMEM;
> +	} else {
> +		pdat = adev->dev.platform_data;
> +	}
>  
>  	/* Allocate a new DMAC and its Channels */
>  	pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
> @@ -862,7 +917,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  
>  	for (i = 0; i < num_chan; i++) {
>  		pch = &pdmac->peripherals[i];
> -		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		if (!adev->dev.of_node)
> +			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		else
> +			pch->chan.private = adev->dev.of_node;
> +
>  		INIT_LIST_HEAD(&pch->work_list);
>  		spin_lock_init(&pch->lock);
>  		pch->pl330_chid = NULL;

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-26 13:16           ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-26 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

Thomas,

On 08/26/2011 03:40 AM, Thomas Abraham wrote:
> For PL330 dma controllers instantiated from device tree, the channel
> lookup is based on phandle of the dma controller and dma request id
> specified by the client node. During probe, the private data of each
> channel of the controller is set to point to the device node of the
> dma controller. The 'chan_id' of the each channel is used as the
> dma request id.
> 
> Client driver requesting dma channels specify the phandle of the
> dma controller and the request id. The pl330 filter function
> converts the phandle to the device node pointer and matches that
> with channel's private data. If a match is found, the request id
> from the client node and the 'chan_id' of the channel is matched.
> A channel is found if both the values match.
> 
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  .../devicetree/bindings/dma/arm-pl330.txt          |   42 +++++++++++++
>  drivers/dma/pl330.c                                |   63 +++++++++++++++++++-
>  2 files changed, 103 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> new file mode 100644
> index 0000000..46a8307
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> @@ -0,0 +1,42 @@
> +* ARM PrimeCell PL330 DMA Controller
> +
> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
> +between memory and peripherals or memory to memory.
> +
> +Required properties:
> +  - compatible: should one or more of the following
> +    - arm,pl330-pdma - For controllers that support mem-to-dev and dev-to-mem
> +      transfers.
> +    - arm,pl330-mdma - For controllers that support mem-to-mem transfers only.

And if they support both? I would think all controllers can support
mem-to-mem. If so, the distinction can be made with the number of requests.

> +    - arm,primecell - should be included for all pl330 dma controller nodes.
> +
> +  - reg: physical base address of the controller and length of memory mapped
> +    region.
> +
> +  - interrupts: interrupt number to the cpu.
> +
> +  - arm,primecell-periphid: should be 0x00041330.

Should be optional. It's only needed when the h/w value is wrong. This
is already documented in primecell.txt.

> +
> +  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
> +    dma controller. Maximum value is 32.

Perhaps could be a bitmask for sparsely populated requests. May not
matter since phandles will define the connections.

Can be optional and not present means 00 requests (mem-to-mem only).

> +
> +Example: (from Samsung's Exynos4 processor dtsi file)
> +
> +	pdma0: pdma at 12680000 {
> +		compatible = "arm,pl330-pdma", "arm,primecell";
> +		reg = <0x12680000 0x1000>;
> +		interrupts = <99>;
> +		arm,primecell-periphid = <0x00041330>;
> +		arm,pl330-peri-reqs = <30>;
> +	};
> +
> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
> +as shown below.
> +
> +  [property name]  = <[phandle of the dma controller] [dma request id]>;
> +
> +      where 'dma request id' is the dma request number which is connected
> +      to the client controller.
> +
> +  Example:  tx-dma-channel = <&pdma0 12>;

I like this approach. I looked at this some and some PPC platforms do a
node for each channel/request, but this is much more simple and similar
to clock binding approach.

You need to define the property name. Probably just "dma-channel" is
enough. For peripherals with more than 1, just list them out like when
you have more than 1 interrupt. The order should be defined as part of
that device's binding (i.e. 1st channel is tx and 2nd channel is rx).

> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 9732995..984dc18 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -19,6 +19,7 @@
>  #include <linux/amba/pl330.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> +#include <linux/of.h>
>  
>  #define NR_DEFAULT_DESC	16
>  
> @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
>  	if (chan->device->dev->driver != &pl330_driver.drv)
>  		return false;
>  
> +#ifdef CONFIG_OF
> +	if (chan->device->dev->of_node) {
> +		const __be32 *prop_value;
> +		phandle phandle;
> +		struct device_node *node;
> +
> +		prop_value = ((struct property *)param)->value;
> +		phandle = be32_to_cpup(prop_value++);
> +		node = of_find_node_by_phandle(phandle);
> +		return ((chan->private == node) &&
> +				(chan->chan_id == be32_to_cpup(prop_value)));
> +	}
> +#endif
> +
>  	peri_id = chan->private;
>  	return *peri_id == (unsigned)param;
>  }
> @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
>  		return IRQ_NONE;
>  }
>  
> +#ifdef CONFIG_OF
> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
> +{
> +	struct dma_pl330_platdata *pdat;
> +	const void *value;
> +
> +	pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
> +	if (!pdat)
> +		return NULL;

Ideally, we will get rid of platform_data completely in the future, so I
don't think filling it in from DT is the right approach.

> +
> +	value = of_get_property(dev->of_node, "arm,pl330-peri-reqs", NULL);
> +	if (value)
> +		pdat->nr_valid_peri = be32_to_cpup(value);

Can't you use the u32 helper function here?

> +
> +	if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
> +		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
> +		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
> +	} else if (of_device_is_compatible(dev->of_node, "arm,pl330-mdma")) {
> +		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
> +	} else if (of_device_is_compatible(dev->of_node, "arm,primecell")) {

I don't think the driver should look at this property. This is really
just for the bus code.

Rob

> +		dma_cap_set(DMA_SLAVE, pdat->cap_mask);
> +		dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
> +		dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
> +	}
> +
> +	return pdat;
> +}
> +#else
> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
> +{
> +	return NULL;
> +}
> +#endif
> +
>  static int __devinit
>  pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  {
> @@ -789,7 +838,13 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  	int i, ret, irq;
>  	int num_chan;
>  
> -	pdat = adev->dev.platform_data;
> +	if (adev->dev.of_node) {
> +		pdat = pl330_parse_dt(&adev->dev);
> +		if (!pdat)
> +			return -ENOMEM;
> +	} else {
> +		pdat = adev->dev.platform_data;
> +	}
>  
>  	/* Allocate a new DMAC and its Channels */
>  	pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
> @@ -862,7 +917,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  
>  	for (i = 0; i < num_chan; i++) {
>  		pch = &pdmac->peripherals[i];
> -		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		if (!adev->dev.of_node)
> +			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		else
> +			pch->chan.private = adev->dev.of_node;
> +
>  		INIT_LIST_HEAD(&pch->work_list);
>  		spin_lock_init(&pch->lock);
>  		pch->pl330_chid = NULL;

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-26 13:16           ` Rob Herring
@ 2011-08-26 14:23             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2011-08-26 14:23 UTC (permalink / raw)
  To: Rob Herring
  Cc: Thomas Abraham, boojin.kim, kgene.kim, patches, vinod.koul,
	devicetree-discuss, jassisinghbrar, linux-samsung-soc,
	linux-arm-kernel

On Fri, Aug 26, 2011 at 08:16:11AM -0500, Rob Herring wrote:
> Thomas,
> 
> On 08/26/2011 03:40 AM, Thomas Abraham wrote:
> > +  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
> > +    dma controller. Maximum value is 32.
> 
> Perhaps could be a bitmask for sparsely populated requests. May not
> matter since phandles will define the connections.
> 
> Can be optional and not present means 00 requests (mem-to-mem only).

The number of peripheral requests is readable from configuration register
zero, so this is discoverable.  Why should we put this information into
DT if its provided by the hardware?

The number of DMA channels available is also configurable by the SoC
designer, yet you don't specify that in DT.  And there's a whole bunch
of other configuration options available to the SoC designer, most of
which are discoverable from the configuration registers.

So, I don't think you should be specifying the number of requests.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-26 14:23             ` Russell King - ARM Linux
  0 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2011-08-26 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Aug 26, 2011 at 08:16:11AM -0500, Rob Herring wrote:
> Thomas,
> 
> On 08/26/2011 03:40 AM, Thomas Abraham wrote:
> > +  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
> > +    dma controller. Maximum value is 32.
> 
> Perhaps could be a bitmask for sparsely populated requests. May not
> matter since phandles will define the connections.
> 
> Can be optional and not present means 00 requests (mem-to-mem only).

The number of peripheral requests is readable from configuration register
zero, so this is discoverable.  Why should we put this information into
DT if its provided by the hardware?

The number of DMA channels available is also configurable by the SoC
designer, yet you don't specify that in DT.  And there's a whole bunch
of other configuration options available to the SoC designer, most of
which are discoverable from the configuration registers.

So, I don't think you should be specifying the number of requests.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/6] Add device tree support for PL330 dma controller driver
  2011-08-26  8:40 ` Thomas Abraham
@ 2011-08-29 17:29   ` Vinod Koul
  -1 siblings, 0 replies; 47+ messages in thread
From: Vinod Koul @ 2011-08-29 17:29 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches,
	jassisinghbrar, grant.likely, linux-samsung-soc,
	linux-arm-kernel

On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
> This patchset adds device tree support for PL330 driver and uses it
> to add device tree support for Samsung platforms, specifically Exynos4.
The DMA patches looks good to me. Do you want this to go thru slave-dma
tree or somewhere else.
I will need acks on 3, 5 and 6th patch to carry them.

-- 
~Vinod

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/6] Add device tree support for PL330 dma controller driver
@ 2011-08-29 17:29   ` Vinod Koul
  0 siblings, 0 replies; 47+ messages in thread
From: Vinod Koul @ 2011-08-29 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
> This patchset adds device tree support for PL330 driver and uses it
> to add device tree support for Samsung platforms, specifically Exynos4.
The DMA patches looks good to me. Do you want this to go thru slave-dma
tree or somewhere else.
I will need acks on 3, 5 and 6th patch to carry them.

-- 
~Vinod

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
       [not found]           ` <4E579C9B.7030807-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2011-08-30 12:18             ` Thomas Abraham
  2011-08-30 13:19                 ` Rob Herring
  0 siblings, 1 reply; 47+ messages in thread
From: Thomas Abraham @ 2011-08-30 12:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: boojin.kim-Sze3O3UU22JBDgjK7y7TUQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, patches-QSEj5FYQhm4dnm+yROfE0A,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r


[-- Attachment #1.1: Type: text/plain, Size: 7900 bytes --]

Hi Rob,

On 26 August 2011 18:46, Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Thomas,
>
> On 08/26/2011 03:40 AM, Thomas Abraham wrote:
> > For PL330 dma controllers instantiated from device tree, the channel
> > lookup is based on phandle of the dma controller and dma request id
> > specified by the client node. During probe, the private data of each
> > channel of the controller is set to point to the device node of the
> > dma controller. The 'chan_id' of the each channel is used as the
> > dma request id.
> >
> > Client driver requesting dma channels specify the phandle of the
> > dma controller and the request id. The pl330 filter function
> > converts the phandle to the device node pointer and matches that
> > with channel's private data. If a match is found, the request id
> > from the client node and the 'chan_id' of the channel is matched.
> > A channel is found if both the values match.
> >
> > Signed-off-by: Thomas Abraham <thomas.abraham-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > ---
> >  .../devicetree/bindings/dma/arm-pl330.txt          |   42 +++++++++++++
> >  drivers/dma/pl330.c                                |   63
> +++++++++++++++++++-
> >  2 files changed, 103 insertions(+), 2 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
> >
> > diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
> b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> > new file mode 100644
> > index 0000000..46a8307
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> > @@ -0,0 +1,42 @@
> > +* ARM PrimeCell PL330 DMA Controller
> > +
> > +The ARM PrimeCell PL330 DMA controller can move blocks of memory
> contents
> > +between memory and peripherals or memory to memory.
> > +
> > +Required properties:
> > +  - compatible: should one or more of the following
> > +    - arm,pl330-pdma - For controllers that support mem-to-dev and
> dev-to-mem
> > +      transfers.
> > +    - arm,pl330-mdma - For controllers that support mem-to-mem transfers
> only.
>
> And if they support both? I would think all controllers can support
> mem-to-mem. If so, the distinction can be made with the number of requests.
>
>
If a controller supports both types of transfer, the device node should not
claim compatibility for "arm,pl330-pdma" or "arm,pl330-mdma". Compatible
should be "arm,primecell".


> > +    - arm,primecell - should be included for all pl330 dma controller
> nodes.
> > +
> > +  - reg: physical base address of the controller and length of memory
> mapped
> > +    region.
> > +
> > +  - interrupts: interrupt number to the cpu.
> > +
> > +  - arm,primecell-periphid: should be 0x00041330.
>
> Should be optional. It's only needed when the h/w value is wrong. This
> is already documented in primecell.txt.
>

Ok. This will be made optional.


>
> > +
> > +  - arm,pl330-peri-reqs: number of actual peripheral requests connected
> to the
> > +    dma controller. Maximum value is 32.
>
> Perhaps could be a bitmask for sparsely populated requests. May not
> matter since phandles will define the connections.
>
> Can be optional and not present means 00 requests (mem-to-mem only).
>
>
As suggested by Russell, this property will be removed and its value will be
read from the configuration register.


>  > +
> > +Example: (from Samsung's Exynos4 processor dtsi file)
> > +
> > +     pdma0: pdma@12680000 {
> > +             compatible = "arm,pl330-pdma", "arm,primecell";
> > +             reg = <0x12680000 0x1000>;
> > +             interrupts = <99>;
> > +             arm,primecell-periphid = <0x00041330>;
> > +             arm,pl330-peri-reqs = <30>;
> > +     };
> > +
> > +Client drivers (device nodes requiring dma transfers from dev-to-mem or
> > +mem-to-dev) should specify the DMA channel numbers using a two-value
> pair
> > +as shown below.
> > +
> > +  [property name]  = <[phandle of the dma controller] [dma request id]>;
> > +
> > +      where 'dma request id' is the dma request number which is
> connected
> > +      to the client controller.
> > +
> > +  Example:  tx-dma-channel = <&pdma0 12>;
>
> I like this approach. I looked at this some and some PPC platforms do a
> node for each channel/request, but this is much more simple and similar
> to clock binding approach.
>
> You need to define the property name. Probably just "dma-channel" is
> enough. For peripherals with more than 1, just list them out like when
> you have more than 1 interrupt. The order should be defined as part of
> that device's binding (i.e. 1st channel is tx and 2nd channel is rx).
>
>
I am little hesitant to do this the way you suggested. A controller could
have dma request lines connected to multiple dma controllers. So the phandle
could be different for each dma channel. Also, the client drivers specify
the property value for each dma channel requested (the property value gets
assigned to chan->private and then used by the filter function to lookup the
dma channel). So changing it the way you have suggested would make things
complex.


> > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> > index 9732995..984dc18 100644
> > --- a/drivers/dma/pl330.c
> > +++ b/drivers/dma/pl330.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/amba/pl330.h>
> >  #include <linux/pm_runtime.h>
> >  #include <linux/scatterlist.h>
> > +#include <linux/of.h>
> >
> >  #define NR_DEFAULT_DESC      16
> >
> > @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void
> *param)
> >       if (chan->device->dev->driver != &pl330_driver.drv)
> >               return false;
> >
> > +#ifdef CONFIG_OF
> > +     if (chan->device->dev->of_node) {
> > +             const __be32 *prop_value;
> > +             phandle phandle;
> > +             struct device_node *node;
> > +
> > +             prop_value = ((struct property *)param)->value;
> > +             phandle = be32_to_cpup(prop_value++);
> > +             node = of_find_node_by_phandle(phandle);
> > +             return ((chan->private == node) &&
> > +                             (chan->chan_id ==
> be32_to_cpup(prop_value)));
> > +     }
> > +#endif
> > +
> >       peri_id = chan->private;
> >       return *peri_id == (unsigned)param;
> >  }
> > @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq, void
> *data)
> >               return IRQ_NONE;
> >  }
> >
> > +#ifdef CONFIG_OF
> > +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
> > +{
> > +     struct dma_pl330_platdata *pdat;
> > +     const void *value;
> > +
> > +     pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
> > +     if (!pdat)
> > +             return NULL;
>
> Ideally, we will get rid of platform_data completely in the future, so I
> don't think filling it in from DT is the right approach.
>
>
Ok. I will drop the usage of platform data.


>  > +
> > +     value = of_get_property(dev->of_node, "arm,pl330-peri-reqs", NULL);
> > +     if (value)
> > +             pdat->nr_valid_peri = be32_to_cpup(value);
>
> Can't you use the u32 helper function here?
>
>
This will go away now since the number of peripherals connected will be read
from the configuration register.


>  > +
> > +     if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
> > +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
> > +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
> > +     } else if (of_device_is_compatible(dev->of_node, "arm,pl330-mdma"))
> {
> > +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
> > +     } else if (of_device_is_compatible(dev->of_node, "arm,primecell"))
> {
>
> I don't think the driver should look at this property. This is really
> just for the bus code.
>

The dma capabilities are derived from the compatible value by the driver.
Sorry, I do not understand your suggestion for this.

Thanks for your help.

Regards,
Thomas.


> Rob
>
>

[-- Attachment #1.2: Type: text/html, Size: 10793 bytes --]

[-- Attachment #2: Type: text/plain, Size: 192 bytes --]

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-26 14:23             ` Russell King - ARM Linux
@ 2011-08-30 12:21               ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-30 12:21 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Rob Herring, boojin.kim, kgene.kim, patches, vinod.koul,
	devicetree-discuss, jassisinghbrar, linux-samsung-soc,
	linux-arm-kernel

Hi Russell,

On 26 August 2011 19:53, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
>
> On Fri, Aug 26, 2011 at 08:16:11AM -0500, Rob Herring wrote:
> > Thomas,
> >
> > On 08/26/2011 03:40 AM, Thomas Abraham wrote:
> > > +  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
> > > +    dma controller. Maximum value is 32.
> >
> > Perhaps could be a bitmask for sparsely populated requests. May not
> > matter since phandles will define the connections.
> >
> > Can be optional and not present means 00 requests (mem-to-mem only).
>
> The number of peripheral requests is readable from configuration register
> zero, so this is discoverable.  Why should we put this information into
> DT if its provided by the hardware?
>
> The number of DMA channels available is also configurable by the SoC
> designer, yet you don't specify that in DT.  And there's a whole bunch
> of other configuration options available to the SoC designer, most of
> which are discoverable from the configuration registers.
>
> So, I don't think you should be specifying the number of requests.

Ok. The property specifying the number of peripheral requests will be dropped.

Thanks,
Thomas.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-30 12:21               ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-30 12:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On 26 August 2011 19:53, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
>
> On Fri, Aug 26, 2011 at 08:16:11AM -0500, Rob Herring wrote:
> > Thomas,
> >
> > On 08/26/2011 03:40 AM, Thomas Abraham wrote:
> > > + ?- arm,pl330-peri-reqs: number of actual peripheral requests connected to the
> > > + ? ?dma controller. Maximum value is 32.
> >
> > Perhaps could be a bitmask for sparsely populated requests. May not
> > matter since phandles will define the connections.
> >
> > Can be optional and not present means 00 requests (mem-to-mem only).
>
> The number of peripheral requests is readable from configuration register
> zero, so this is discoverable. ?Why should we put this information into
> DT if its provided by the hardware?
>
> The number of DMA channels available is also configurable by the SoC
> designer, yet you don't specify that in DT. ?And there's a whole bunch
> of other configuration options available to the SoC designer, most of
> which are discoverable from the configuration registers.
>
> So, I don't think you should be specifying the number of requests.

Ok. The property specifying the number of peripheral requests will be dropped.

Thanks,
Thomas.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/6] Add device tree support for PL330 dma controller driver
  2011-08-29 17:29   ` Vinod Koul
@ 2011-08-30 12:28     ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-30 12:28 UTC (permalink / raw)
  To: Vinod Koul
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches,
	jassisinghbrar, grant.likely, linux-samsung-soc,
	linux-arm-kernel

Hi Vinod,

On 29 August 2011 22:59, Vinod Koul <vinod.koul@linux.intel.com> wrote:
> On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
>> This patchset adds device tree support for PL330 driver and uses it
>> to add device tree support for Samsung platforms, specifically Exynos4.
> The DMA patches looks good to me. Do you want this to go thru slave-dma
> tree or somewhere else.
> I will need acks on 3, 5 and 6th patch to carry them.

There are couple of changes required in patch 4/6 of this series. I
will do that and resubmit.

Since these patches are based on Boojin's pl330 driver update patches,
it would be easier to take the same route which Boojin's patches will
take. I will try to get acks' for the patches that you have listed.

Thanks for your help.

Regards,
Thomas.

>
> --
> ~Vinod
>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/6] Add device tree support for PL330 dma controller driver
@ 2011-08-30 12:28     ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-30 12:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod,

On 29 August 2011 22:59, Vinod Koul <vinod.koul@linux.intel.com> wrote:
> On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
>> This patchset adds device tree support for PL330 driver and uses it
>> to add device tree support for Samsung platforms, specifically Exynos4.
> The DMA patches looks good to me. Do you want this to go thru slave-dma
> tree or somewhere else.
> I will need acks on 3, 5 and 6th patch to carry them.

There are couple of changes required in patch 4/6 of this series. I
will do that and resubmit.

Since these patches are based on Boojin's pl330 driver update patches,
it would be easier to take the same route which Boojin's patches will
take. I will try to get acks' for the patches that you have listed.

Thanks for your help.

Regards,
Thomas.

>
> --
> ~Vinod
>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-26 13:16           ` Rob Herring
@ 2011-08-30 13:09             ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-30 13:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: boojin.kim, kgene.kim, patches, vinod.koul, devicetree-discuss,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Hi Rob,

On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,
>
> On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>> For PL330 dma controllers instantiated from device tree, the channel
>> lookup is based on phandle of the dma controller and dma request id
>> specified by the client node. During probe, the private data of each
>> channel of the controller is set to point to the device node of the
>> dma controller. The 'chan_id' of the each channel is used as the
>> dma request id.
>>
>> Client driver requesting dma channels specify the phandle of the
>> dma controller and the request id. The pl330 filter function
>> converts the phandle to the device node pointer and matches that
>> with channel's private data. If a match is found, the request id
>> from the client node and the 'chan_id' of the channel is matched.
>> A channel is found if both the values match.
>>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>>  .../devicetree/bindings/dma/arm-pl330.txt          |   42 +++++++++++++
>>  drivers/dma/pl330.c                                |   63 +++++++++++++++++++-
>>  2 files changed, 103 insertions(+), 2 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> new file mode 100644
>> index 0000000..46a8307
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> @@ -0,0 +1,42 @@
>> +* ARM PrimeCell PL330 DMA Controller
>> +
>> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
>> +between memory and peripherals or memory to memory.
>> +
>> +Required properties:
>> +  - compatible: should one or more of the following
>> +    - arm,pl330-pdma - For controllers that support mem-to-dev and dev-to-mem
>> +      transfers.
>> +    - arm,pl330-mdma - For controllers that support mem-to-mem transfers only.
>
> And if they support both? I would think all controllers can support
> mem-to-mem. If so, the distinction can be made with the number of requests.

If a controller supports both types of transfer, the device node
should not claim compatibility for "arm,pl330-pdma" or
"arm,pl330-mdma". Compatible should be "arm,primecell".

>
>> +    - arm,primecell - should be included for all pl330 dma controller nodes.
>> +
>> +  - reg: physical base address of the controller and length of memory mapped
>> +    region.
>> +
>> +  - interrupts: interrupt number to the cpu.
>> +
>> +  - arm,primecell-periphid: should be 0x00041330.
>
> Should be optional. It's only needed when the h/w value is wrong. This
> is already documented in primecell.txt.

Ok. This will be made optional.

>
>> +
>> +  - arm,pl330-peri-reqs: number of actual peripheral requests connected to the
>> +    dma controller. Maximum value is 32.
>
> Perhaps could be a bitmask for sparsely populated requests. May not
> matter since phandles will define the connections.
>
> Can be optional and not present means 00 requests (mem-to-mem only).

As suggested by Russell, this property will be removed and its value
will be read from the configuration register.

>
>> +
>> +Example: (from Samsung's Exynos4 processor dtsi file)
>> +
>> +     pdma0: pdma@12680000 {
>> +             compatible = "arm,pl330-pdma", "arm,primecell";
>> +             reg = <0x12680000 0x1000>;
>> +             interrupts = <99>;
>> +             arm,primecell-periphid = <0x00041330>;
>> +             arm,pl330-peri-reqs = <30>;
>> +     };
>> +
>> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
>> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
>> +as shown below.
>> +
>> +  [property name]  = <[phandle of the dma controller] [dma request id]>;
>> +
>> +      where 'dma request id' is the dma request number which is connected
>> +      to the client controller.
>> +
>> +  Example:  tx-dma-channel = <&pdma0 12>;
>
> I like this approach. I looked at this some and some PPC platforms do a
> node for each channel/request, but this is much more simple and similar
> to clock binding approach.
>
> You need to define the property name. Probably just "dma-channel" is
> enough. For peripherals with more than 1, just list them out like when
> you have more than 1 interrupt. The order should be defined as part of
> that device's binding (i.e. 1st channel is tx and 2nd channel is rx).

I am little hesitant to do this the way you suggested. A controller
could have dma request lines connected to multiple dma controllers. So
the phandle could be different for each dma channel. Also, the client
drivers specify the property value for each dma channel requested (the
property value gets assigned to chan->private and then used by the
filter function to lookup the dma channel). So changing it the way you
have suggested would make things complex.

>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index 9732995..984dc18 100644
>> --- a/drivers/dma/pl330.c
>> +++ b/drivers/dma/pl330.c
>> @@ -19,6 +19,7 @@
>>  #include <linux/amba/pl330.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/scatterlist.h>
>> +#include <linux/of.h>
>>
>>  #define NR_DEFAULT_DESC      16
>>
>> @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
>>       if (chan->device->dev->driver != &pl330_driver.drv)
>>               return false;
>>
>> +#ifdef CONFIG_OF
>> +     if (chan->device->dev->of_node) {
>> +             const __be32 *prop_value;
>> +             phandle phandle;
>> +             struct device_node *node;
>> +
>> +             prop_value = ((struct property *)param)->value;
>> +             phandle = be32_to_cpup(prop_value++);
>> +             node = of_find_node_by_phandle(phandle);
>> +             return ((chan->private == node) &&
>> +                             (chan->chan_id == be32_to_cpup(prop_value)));
>> +     }
>> +#endif
>> +
>>       peri_id = chan->private;
>>       return *peri_id == (unsigned)param;
>>  }
>> @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
>>               return IRQ_NONE;
>>  }
>>
>> +#ifdef CONFIG_OF
>> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>> +{
>> +     struct dma_pl330_platdata *pdat;
>> +     const void *value;
>> +
>> +     pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>> +     if (!pdat)
>> +             return NULL;
>
> Ideally, we will get rid of platform_data completely in the future, so I
> don't think filling it in from DT is the right approach.

Ok. I will drop the usage of platform data.

>
>> +
>> +     value = of_get_property(dev->of_node, "arm,pl330-peri-reqs", NULL);
>> +     if (value)
>> +             pdat->nr_valid_peri = be32_to_cpup(value);
>
> Can't you use the u32 helper function here?

This will go away now since the number of peripherals connected will
be read from the configuration register.

>
>> +
>> +     if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>> +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>> +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>> +     } else if (of_device_is_compatible(dev->of_node, "arm,pl330-mdma")) {
>> +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>> +     } else if (of_device_is_compatible(dev->of_node, "arm,primecell")) {
>
> I don't think the driver should look at this property. This is really
> just for the bus code.

The dma capabilities are derived from the compatible value by the
driver. Sorry, I do not understand your suggestion for this.

Thanks for your help.

Regards,
Thomas.

>
> Rob
>
>> +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>> +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>> +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>> +     }
>> +
>> +     return pdat;
>> +}
>> +#else
>> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>> +{
>> +     return NULL;
>> +}
>> +#endif
>> +
>>  static int __devinit
>>  pl330_probe(struct amba_device *adev, const struct amba_id *id)
>>  {
>> @@ -789,7 +838,13 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>>       int i, ret, irq;
>>       int num_chan;
>>
>> -     pdat = adev->dev.platform_data;
>> +     if (adev->dev.of_node) {
>> +             pdat = pl330_parse_dt(&adev->dev);
>> +             if (!pdat)
>> +                     return -ENOMEM;
>> +     } else {
>> +             pdat = adev->dev.platform_data;
>> +     }
>>
>>       /* Allocate a new DMAC and its Channels */
>>       pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
>> @@ -862,7 +917,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>>
>>       for (i = 0; i < num_chan; i++) {
>>               pch = &pdmac->peripherals[i];
>> -             pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
>> +             if (!adev->dev.of_node)
>> +                     pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
>> +             else
>> +                     pch->chan.private = adev->dev.of_node;
>> +
>>               INIT_LIST_HEAD(&pch->work_list);
>>               spin_lock_init(&pch->lock);
>>               pch->pl330_chid = NULL;
>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-30 13:09             ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-30 13:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,
>
> On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>> For PL330 dma controllers instantiated from device tree, the channel
>> lookup is based on phandle of the dma controller and dma request id
>> specified by the client node. During probe, the private data of each
>> channel of the controller is set to point to the device node of the
>> dma controller. The 'chan_id' of the each channel is used as the
>> dma request id.
>>
>> Client driver requesting dma channels specify the phandle of the
>> dma controller and the request id. The pl330 filter function
>> converts the phandle to the device node pointer and matches that
>> with channel's private data. If a match is found, the request id
>> from the client node and the 'chan_id' of the channel is matched.
>> A channel is found if both the values match.
>>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> ?.../devicetree/bindings/dma/arm-pl330.txt ? ? ? ? ?| ? 42 +++++++++++++
>> ?drivers/dma/pl330.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 63 +++++++++++++++++++-
>> ?2 files changed, 103 insertions(+), 2 deletions(-)
>> ?create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> new file mode 100644
>> index 0000000..46a8307
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> @@ -0,0 +1,42 @@
>> +* ARM PrimeCell PL330 DMA Controller
>> +
>> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
>> +between memory and peripherals or memory to memory.
>> +
>> +Required properties:
>> + ?- compatible: should one or more of the following
>> + ? ?- arm,pl330-pdma - For controllers that support mem-to-dev and dev-to-mem
>> + ? ? ?transfers.
>> + ? ?- arm,pl330-mdma - For controllers that support mem-to-mem transfers only.
>
> And if they support both? I would think all controllers can support
> mem-to-mem. If so, the distinction can be made with the number of requests.

If a controller supports both types of transfer, the device node
should not claim compatibility for "arm,pl330-pdma" or
"arm,pl330-mdma". Compatible should be "arm,primecell".

>
>> + ? ?- arm,primecell - should be included for all pl330 dma controller nodes.
>> +
>> + ?- reg: physical base address of the controller and length of memory mapped
>> + ? ?region.
>> +
>> + ?- interrupts: interrupt number to the cpu.
>> +
>> + ?- arm,primecell-periphid: should be 0x00041330.
>
> Should be optional. It's only needed when the h/w value is wrong. This
> is already documented in primecell.txt.

Ok. This will be made optional.

>
>> +
>> + ?- arm,pl330-peri-reqs: number of actual peripheral requests connected to the
>> + ? ?dma controller. Maximum value is 32.
>
> Perhaps could be a bitmask for sparsely populated requests. May not
> matter since phandles will define the connections.
>
> Can be optional and not present means 00 requests (mem-to-mem only).

As suggested by Russell, this property will be removed and its value
will be read from the configuration register.

>
>> +
>> +Example: (from Samsung's Exynos4 processor dtsi file)
>> +
>> + ? ? pdma0: pdma at 12680000 {
>> + ? ? ? ? ? ? compatible = "arm,pl330-pdma", "arm,primecell";
>> + ? ? ? ? ? ? reg = <0x12680000 0x1000>;
>> + ? ? ? ? ? ? interrupts = <99>;
>> + ? ? ? ? ? ? arm,primecell-periphid = <0x00041330>;
>> + ? ? ? ? ? ? arm,pl330-peri-reqs = <30>;
>> + ? ? };
>> +
>> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
>> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
>> +as shown below.
>> +
>> + ?[property name] ?= <[phandle of the dma controller] [dma request id]>;
>> +
>> + ? ? ?where 'dma request id' is the dma request number which is connected
>> + ? ? ?to the client controller.
>> +
>> + ?Example: ?tx-dma-channel = <&pdma0 12>;
>
> I like this approach. I looked at this some and some PPC platforms do a
> node for each channel/request, but this is much more simple and similar
> to clock binding approach.
>
> You need to define the property name. Probably just "dma-channel" is
> enough. For peripherals with more than 1, just list them out like when
> you have more than 1 interrupt. The order should be defined as part of
> that device's binding (i.e. 1st channel is tx and 2nd channel is rx).

I am little hesitant to do this the way you suggested. A controller
could have dma request lines connected to multiple dma controllers. So
the phandle could be different for each dma channel. Also, the client
drivers specify the property value for each dma channel requested (the
property value gets assigned to chan->private and then used by the
filter function to lookup the dma channel). So changing it the way you
have suggested would make things complex.

>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index 9732995..984dc18 100644
>> --- a/drivers/dma/pl330.c
>> +++ b/drivers/dma/pl330.c
>> @@ -19,6 +19,7 @@
>> ?#include <linux/amba/pl330.h>
>> ?#include <linux/pm_runtime.h>
>> ?#include <linux/scatterlist.h>
>> +#include <linux/of.h>
>>
>> ?#define NR_DEFAULT_DESC ? ? ?16
>>
>> @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
>> ? ? ? if (chan->device->dev->driver != &pl330_driver.drv)
>> ? ? ? ? ? ? ? return false;
>>
>> +#ifdef CONFIG_OF
>> + ? ? if (chan->device->dev->of_node) {
>> + ? ? ? ? ? ? const __be32 *prop_value;
>> + ? ? ? ? ? ? phandle phandle;
>> + ? ? ? ? ? ? struct device_node *node;
>> +
>> + ? ? ? ? ? ? prop_value = ((struct property *)param)->value;
>> + ? ? ? ? ? ? phandle = be32_to_cpup(prop_value++);
>> + ? ? ? ? ? ? node = of_find_node_by_phandle(phandle);
>> + ? ? ? ? ? ? return ((chan->private == node) &&
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? (chan->chan_id == be32_to_cpup(prop_value)));
>> + ? ? }
>> +#endif
>> +
>> ? ? ? peri_id = chan->private;
>> ? ? ? return *peri_id == (unsigned)param;
>> ?}
>> @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
>> ? ? ? ? ? ? ? return IRQ_NONE;
>> ?}
>>
>> +#ifdef CONFIG_OF
>> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>> +{
>> + ? ? struct dma_pl330_platdata *pdat;
>> + ? ? const void *value;
>> +
>> + ? ? pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>> + ? ? if (!pdat)
>> + ? ? ? ? ? ? return NULL;
>
> Ideally, we will get rid of platform_data completely in the future, so I
> don't think filling it in from DT is the right approach.

Ok. I will drop the usage of platform data.

>
>> +
>> + ? ? value = of_get_property(dev->of_node, "arm,pl330-peri-reqs", NULL);
>> + ? ? if (value)
>> + ? ? ? ? ? ? pdat->nr_valid_peri = be32_to_cpup(value);
>
> Can't you use the u32 helper function here?

This will go away now since the number of peripherals connected will
be read from the configuration register.

>
>> +
>> + ? ? if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>> + ? ? ? ? ? ? dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>> + ? ? ? ? ? ? dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>> + ? ? } else if (of_device_is_compatible(dev->of_node, "arm,pl330-mdma")) {
>> + ? ? ? ? ? ? dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>> + ? ? } else if (of_device_is_compatible(dev->of_node, "arm,primecell")) {
>
> I don't think the driver should look at this property. This is really
> just for the bus code.

The dma capabilities are derived from the compatible value by the
driver. Sorry, I do not understand your suggestion for this.

Thanks for your help.

Regards,
Thomas.

>
> Rob
>
>> + ? ? ? ? ? ? dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>> + ? ? ? ? ? ? dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>> + ? ? ? ? ? ? dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>> + ? ? }
>> +
>> + ? ? return pdat;
>> +}
>> +#else
>> +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>> +{
>> + ? ? return NULL;
>> +}
>> +#endif
>> +
>> ?static int __devinit
>> ?pl330_probe(struct amba_device *adev, const struct amba_id *id)
>> ?{
>> @@ -789,7 +838,13 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>> ? ? ? int i, ret, irq;
>> ? ? ? int num_chan;
>>
>> - ? ? pdat = adev->dev.platform_data;
>> + ? ? if (adev->dev.of_node) {
>> + ? ? ? ? ? ? pdat = pl330_parse_dt(&adev->dev);
>> + ? ? ? ? ? ? if (!pdat)
>> + ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
>> + ? ? } else {
>> + ? ? ? ? ? ? pdat = adev->dev.platform_data;
>> + ? ? }
>>
>> ? ? ? /* Allocate a new DMAC and its Channels */
>> ? ? ? pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
>> @@ -862,7 +917,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>>
>> ? ? ? for (i = 0; i < num_chan; i++) {
>> ? ? ? ? ? ? ? pch = &pdmac->peripherals[i];
>> - ? ? ? ? ? ? pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
>> + ? ? ? ? ? ? if (!adev->dev.of_node)
>> + ? ? ? ? ? ? ? ? ? ? pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
>> + ? ? ? ? ? ? else
>> + ? ? ? ? ? ? ? ? ? ? pch->chan.private = adev->dev.of_node;
>> +
>> ? ? ? ? ? ? ? INIT_LIST_HEAD(&pch->work_list);
>> ? ? ? ? ? ? ? spin_lock_init(&pch->lock);
>> ? ? ? ? ? ? ? pch->pl330_chid = NULL;
>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-30 12:18             ` Thomas Abraham
@ 2011-08-30 13:19                 ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-30 13:19 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches, vinod.koul,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Thomas,

On 08/30/2011 07:18 AM, Thomas Abraham wrote:
> Hi Rob,
> 
> On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com
> <mailto:robherring2@gmail.com>> wrote:
> 
>     Thomas,
> 
>     On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>     > For PL330 dma controllers instantiated from device tree, the channel
>     > lookup is based on phandle of the dma controller and dma request id
>     > specified by the client node. During probe, the private data of each
>     > channel of the controller is set to point to the device node of the
>     > dma controller. The 'chan_id' of the each channel is used as the
>     > dma request id.
>     >
>     > Client driver requesting dma channels specify the phandle of the
>     > dma controller and the request id. The pl330 filter function
>     > converts the phandle to the device node pointer and matches that
>     > with channel's private data. If a match is found, the request id
>     > from the client node and the 'chan_id' of the channel is matched.
>     > A channel is found if both the values match.
>     >
>     > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org
>     <mailto:thomas.abraham@linaro.org>>
>     > ---
>     >  .../devicetree/bindings/dma/arm-pl330.txt          |   42
>     +++++++++++++
>     >  drivers/dma/pl330.c                                |   63
>     +++++++++++++++++++-
>     >  2 files changed, 103 insertions(+), 2 deletions(-)
>     >  create mode 100644
>     Documentation/devicetree/bindings/dma/arm-pl330.txt
>     >
>     > diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>     b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>     > new file mode 100644
>     > index 0000000..46a8307
>     > --- /dev/null
>     > +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>     > @@ -0,0 +1,42 @@
>     > +* ARM PrimeCell PL330 DMA Controller
>     > +
>     > +The ARM PrimeCell PL330 DMA controller can move blocks of memory
>     contents
>     > +between memory and peripherals or memory to memory.
>     > +
>     > +Required properties:
>     > +  - compatible: should one or more of the following
>     > +    - arm,pl330-pdma - For controllers that support mem-to-dev
>     and dev-to-mem
>     > +      transfers.
>     > +    - arm,pl330-mdma - For controllers that support mem-to-mem
>     transfers only.
> 
>     And if they support both? I would think all controllers can support
>     mem-to-mem. If so, the distinction can be made with the number of
>     requests.
> 
> 
> If a controller supports both types of transfer, the device node should
> not claim compatibility for "arm,pl330-pdma" or "arm,pl330-mdma".
> Compatible should be "arm,primecell".

No, every Primecell peripheral has "arm,primecell", so it is not
specific enough for a driver to use.

Is there a case that a controller with peripheral requests cannot
support mem-to-mem transfers? I don't think there is. You could decide
you don't want to for other reasons like you don't have enough free
channels, but that's really a s/w decision, not a h/w description.

>  
> 
>     > +    - arm,primecell - should be included for all pl330 dma
>     controller nodes.
>     > +
>     > +  - reg: physical base address of the controller and length of
>     memory mapped
>     > +    region.
>     > +
>     > +  - interrupts: interrupt number to the cpu.
>     > +
>     > +  - arm,primecell-periphid: should be 0x00041330.
> 
>     Should be optional. It's only needed when the h/w value is wrong. This
>     is already documented in primecell.txt.
> 
> 
> Ok. This will be made optional.
>  
> 
> 
>     > +
>     > +  - arm,pl330-peri-reqs: number of actual peripheral requests
>     connected to the
>     > +    dma controller. Maximum value is 32.
> 
>     Perhaps could be a bitmask for sparsely populated requests. May not
>     matter since phandles will define the connections.
> 
>     Can be optional and not present means 00 requests (mem-to-mem only).
> 
> 
> As suggested by Russell, this property will be removed and its value
> will be read from the configuration register.
>  

Good. Reading a value of 0 requests can still be used to determine the
controller is mem-to-mem only.

> 
>     > +
>     > +Example: (from Samsung's Exynos4 processor dtsi file)
>     > +
>     > +     pdma0: pdma@12680000 {
>     > +             compatible = "arm,pl330-pdma", "arm,primecell";
>     > +             reg = <0x12680000 0x1000>;
>     > +             interrupts = <99>;
>     > +             arm,primecell-periphid = <0x00041330>;
>     > +             arm,pl330-peri-reqs = <30>;
>     > +     };
>     > +
>     > +Client drivers (device nodes requiring dma transfers from
>     dev-to-mem or
>     > +mem-to-dev) should specify the DMA channel numbers using a
>     two-value pair
>     > +as shown below.
>     > +
>     > +  [property name]  = <[phandle of the dma controller] [dma
>     request id]>;
>     > +
>     > +      where 'dma request id' is the dma request number which is
>     connected
>     > +      to the client controller.
>     > +
>     > +  Example:  tx-dma-channel = <&pdma0 12>;
> 
>     I like this approach. I looked at this some and some PPC platforms do a
>     node for each channel/request, but this is much more simple and similar
>     to clock binding approach.
> 
>     You need to define the property name. Probably just "dma-channel" is
>     enough. For peripherals with more than 1, just list them out like when
>     you have more than 1 interrupt. The order should be defined as part of
>     that device's binding (i.e. 1st channel is tx and 2nd channel is rx).
> 
> 
> I am little hesitant to do this the way you suggested. A controller
> could have dma request lines connected to multiple dma controllers. So
> the phandle could be different for each dma channel. Also, the client
> drivers specify the property value for each dma channel requested (the
> property value gets assigned to chan->private and then used by the
> filter function to lookup the dma channel). So changing it the way you
> have suggested would make things complex.
>  

Perhaps you could make private point to the array entry rather than the
property.

But I don't have s strong opinion either way.

> 
>     > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>     > index 9732995..984dc18 100644
>     > --- a/drivers/dma/pl330.c
>     > +++ b/drivers/dma/pl330.c
>     > @@ -19,6 +19,7 @@
>     >  #include <linux/amba/pl330.h>
>     >  #include <linux/pm_runtime.h>
>     >  #include <linux/scatterlist.h>
>     > +#include <linux/of.h>
>     >
>     >  #define NR_DEFAULT_DESC      16
>     >
>     > @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void
>     *param)
>     >       if (chan->device->dev->driver != &pl330_driver.drv)
>     >               return false;
>     >
>     > +#ifdef CONFIG_OF
>     > +     if (chan->device->dev->of_node) {
>     > +             const __be32 *prop_value;
>     > +             phandle phandle;
>     > +             struct device_node *node;
>     > +
>     > +             prop_value = ((struct property *)param)->value;
>     > +             phandle = be32_to_cpup(prop_value++);
>     > +             node = of_find_node_by_phandle(phandle);
>     > +             return ((chan->private == node) &&
>     > +                             (chan->chan_id ==
>     be32_to_cpup(prop_value)));
>     > +     }
>     > +#endif
>     > +
>     >       peri_id = chan->private;
>     >       return *peri_id == (unsigned)param;
>     >  }
>     > @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq,
>     void *data)
>     >               return IRQ_NONE;
>     >  }
>     >
>     > +#ifdef CONFIG_OF
>     > +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>     > +{
>     > +     struct dma_pl330_platdata *pdat;
>     > +     const void *value;
>     > +
>     > +     pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>     > +     if (!pdat)
>     > +             return NULL;
> 
>     Ideally, we will get rid of platform_data completely in the future, so I
>     don't think filling it in from DT is the right approach.
> 
> 
> Ok. I will drop the usage of platform data.
>  
> 
>     > +
>     > +     value = of_get_property(dev->of_node, "arm,pl330-peri-reqs",
>     NULL);
>     > +     if (value)
>     > +             pdat->nr_valid_peri = be32_to_cpup(value);
> 
>     Can't you use the u32 helper function here?
> 
> 
> This will go away now since the number of peripherals connected will be
> read from the configuration register.
>  
> 
>     > +
>     > +     if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>     > +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>     > +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>     > +     } else if (of_device_is_compatible(dev->of_node,
>     "arm,pl330-mdma")) {
>     > +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>     > +     } else if (of_device_is_compatible(dev->of_node,
>     "arm,primecell")) {
> 
>     I don't think the driver should look at this property. This is really
>     just for the bus code.
> 
> 
> The dma capabilities are derived from the compatible value by the
> driver. Sorry, I do not understand your suggestion for this.
>  

"arm,primecell" is purely for identifying peripherals with the Primecell
ID registers and in turn used to create amba_device instances. You
cannot imply that it is a DMA controller.

Rob


> Thanks for your help.
> 
> Regards,
> Thomas.
> 
> 
>     Rob
> 
> 

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-30 13:19                 ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-30 13:19 UTC (permalink / raw)
  To: linux-arm-kernel

Thomas,

On 08/30/2011 07:18 AM, Thomas Abraham wrote:
> Hi Rob,
> 
> On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com
> <mailto:robherring2@gmail.com>> wrote:
> 
>     Thomas,
> 
>     On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>     > For PL330 dma controllers instantiated from device tree, the channel
>     > lookup is based on phandle of the dma controller and dma request id
>     > specified by the client node. During probe, the private data of each
>     > channel of the controller is set to point to the device node of the
>     > dma controller. The 'chan_id' of the each channel is used as the
>     > dma request id.
>     >
>     > Client driver requesting dma channels specify the phandle of the
>     > dma controller and the request id. The pl330 filter function
>     > converts the phandle to the device node pointer and matches that
>     > with channel's private data. If a match is found, the request id
>     > from the client node and the 'chan_id' of the channel is matched.
>     > A channel is found if both the values match.
>     >
>     > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org
>     <mailto:thomas.abraham@linaro.org>>
>     > ---
>     >  .../devicetree/bindings/dma/arm-pl330.txt          |   42
>     +++++++++++++
>     >  drivers/dma/pl330.c                                |   63
>     +++++++++++++++++++-
>     >  2 files changed, 103 insertions(+), 2 deletions(-)
>     >  create mode 100644
>     Documentation/devicetree/bindings/dma/arm-pl330.txt
>     >
>     > diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>     b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>     > new file mode 100644
>     > index 0000000..46a8307
>     > --- /dev/null
>     > +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>     > @@ -0,0 +1,42 @@
>     > +* ARM PrimeCell PL330 DMA Controller
>     > +
>     > +The ARM PrimeCell PL330 DMA controller can move blocks of memory
>     contents
>     > +between memory and peripherals or memory to memory.
>     > +
>     > +Required properties:
>     > +  - compatible: should one or more of the following
>     > +    - arm,pl330-pdma - For controllers that support mem-to-dev
>     and dev-to-mem
>     > +      transfers.
>     > +    - arm,pl330-mdma - For controllers that support mem-to-mem
>     transfers only.
> 
>     And if they support both? I would think all controllers can support
>     mem-to-mem. If so, the distinction can be made with the number of
>     requests.
> 
> 
> If a controller supports both types of transfer, the device node should
> not claim compatibility for "arm,pl330-pdma" or "arm,pl330-mdma".
> Compatible should be "arm,primecell".

No, every Primecell peripheral has "arm,primecell", so it is not
specific enough for a driver to use.

Is there a case that a controller with peripheral requests cannot
support mem-to-mem transfers? I don't think there is. You could decide
you don't want to for other reasons like you don't have enough free
channels, but that's really a s/w decision, not a h/w description.

>  
> 
>     > +    - arm,primecell - should be included for all pl330 dma
>     controller nodes.
>     > +
>     > +  - reg: physical base address of the controller and length of
>     memory mapped
>     > +    region.
>     > +
>     > +  - interrupts: interrupt number to the cpu.
>     > +
>     > +  - arm,primecell-periphid: should be 0x00041330.
> 
>     Should be optional. It's only needed when the h/w value is wrong. This
>     is already documented in primecell.txt.
> 
> 
> Ok. This will be made optional.
>  
> 
> 
>     > +
>     > +  - arm,pl330-peri-reqs: number of actual peripheral requests
>     connected to the
>     > +    dma controller. Maximum value is 32.
> 
>     Perhaps could be a bitmask for sparsely populated requests. May not
>     matter since phandles will define the connections.
> 
>     Can be optional and not present means 00 requests (mem-to-mem only).
> 
> 
> As suggested by Russell, this property will be removed and its value
> will be read from the configuration register.
>  

Good. Reading a value of 0 requests can still be used to determine the
controller is mem-to-mem only.

> 
>     > +
>     > +Example: (from Samsung's Exynos4 processor dtsi file)
>     > +
>     > +     pdma0: pdma at 12680000 {
>     > +             compatible = "arm,pl330-pdma", "arm,primecell";
>     > +             reg = <0x12680000 0x1000>;
>     > +             interrupts = <99>;
>     > +             arm,primecell-periphid = <0x00041330>;
>     > +             arm,pl330-peri-reqs = <30>;
>     > +     };
>     > +
>     > +Client drivers (device nodes requiring dma transfers from
>     dev-to-mem or
>     > +mem-to-dev) should specify the DMA channel numbers using a
>     two-value pair
>     > +as shown below.
>     > +
>     > +  [property name]  = <[phandle of the dma controller] [dma
>     request id]>;
>     > +
>     > +      where 'dma request id' is the dma request number which is
>     connected
>     > +      to the client controller.
>     > +
>     > +  Example:  tx-dma-channel = <&pdma0 12>;
> 
>     I like this approach. I looked at this some and some PPC platforms do a
>     node for each channel/request, but this is much more simple and similar
>     to clock binding approach.
> 
>     You need to define the property name. Probably just "dma-channel" is
>     enough. For peripherals with more than 1, just list them out like when
>     you have more than 1 interrupt. The order should be defined as part of
>     that device's binding (i.e. 1st channel is tx and 2nd channel is rx).
> 
> 
> I am little hesitant to do this the way you suggested. A controller
> could have dma request lines connected to multiple dma controllers. So
> the phandle could be different for each dma channel. Also, the client
> drivers specify the property value for each dma channel requested (the
> property value gets assigned to chan->private and then used by the
> filter function to lookup the dma channel). So changing it the way you
> have suggested would make things complex.
>  

Perhaps you could make private point to the array entry rather than the
property.

But I don't have s strong opinion either way.

> 
>     > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>     > index 9732995..984dc18 100644
>     > --- a/drivers/dma/pl330.c
>     > +++ b/drivers/dma/pl330.c
>     > @@ -19,6 +19,7 @@
>     >  #include <linux/amba/pl330.h>
>     >  #include <linux/pm_runtime.h>
>     >  #include <linux/scatterlist.h>
>     > +#include <linux/of.h>
>     >
>     >  #define NR_DEFAULT_DESC      16
>     >
>     > @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void
>     *param)
>     >       if (chan->device->dev->driver != &pl330_driver.drv)
>     >               return false;
>     >
>     > +#ifdef CONFIG_OF
>     > +     if (chan->device->dev->of_node) {
>     > +             const __be32 *prop_value;
>     > +             phandle phandle;
>     > +             struct device_node *node;
>     > +
>     > +             prop_value = ((struct property *)param)->value;
>     > +             phandle = be32_to_cpup(prop_value++);
>     > +             node = of_find_node_by_phandle(phandle);
>     > +             return ((chan->private == node) &&
>     > +                             (chan->chan_id ==
>     be32_to_cpup(prop_value)));
>     > +     }
>     > +#endif
>     > +
>     >       peri_id = chan->private;
>     >       return *peri_id == (unsigned)param;
>     >  }
>     > @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq,
>     void *data)
>     >               return IRQ_NONE;
>     >  }
>     >
>     > +#ifdef CONFIG_OF
>     > +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>     > +{
>     > +     struct dma_pl330_platdata *pdat;
>     > +     const void *value;
>     > +
>     > +     pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>     > +     if (!pdat)
>     > +             return NULL;
> 
>     Ideally, we will get rid of platform_data completely in the future, so I
>     don't think filling it in from DT is the right approach.
> 
> 
> Ok. I will drop the usage of platform data.
>  
> 
>     > +
>     > +     value = of_get_property(dev->of_node, "arm,pl330-peri-reqs",
>     NULL);
>     > +     if (value)
>     > +             pdat->nr_valid_peri = be32_to_cpup(value);
> 
>     Can't you use the u32 helper function here?
> 
> 
> This will go away now since the number of peripherals connected will be
> read from the configuration register.
>  
> 
>     > +
>     > +     if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>     > +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>     > +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>     > +     } else if (of_device_is_compatible(dev->of_node,
>     "arm,pl330-mdma")) {
>     > +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>     > +     } else if (of_device_is_compatible(dev->of_node,
>     "arm,primecell")) {
> 
>     I don't think the driver should look at this property. This is really
>     just for the bus code.
> 
> 
> The dma capabilities are derived from the compatible value by the
> driver. Sorry, I do not understand your suggestion for this.
>  

"arm,primecell" is purely for identifying peripherals with the Primecell
ID registers and in turn used to create amba_device instances. You
cannot imply that it is a DMA controller.

Rob


> Thanks for your help.
> 
> Regards,
> Thomas.
> 
> 
>     Rob
> 
> 

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-30 13:19                 ` Rob Herring
@ 2011-08-31  6:46                   ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-31  6:46 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches, vinod.koul,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Hi Rob,

On 30 August 2011 18:49, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,
>
> On 08/30/2011 07:18 AM, Thomas Abraham wrote:
>> Hi Rob,
>>
>> On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com
>> <mailto:robherring2@gmail.com>> wrote:
>>
>>     Thomas,
>>
>>     On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>>     > For PL330 dma controllers instantiated from device tree, the channel
>>     > lookup is based on phandle of the dma controller and dma request id
>>     > specified by the client node. During probe, the private data of each
>>     > channel of the controller is set to point to the device node of the
>>     > dma controller. The 'chan_id' of the each channel is used as the
>>     > dma request id.
>>     >
>>     > Client driver requesting dma channels specify the phandle of the
>>     > dma controller and the request id. The pl330 filter function
>>     > converts the phandle to the device node pointer and matches that
>>     > with channel's private data. If a match is found, the request id
>>     > from the client node and the 'chan_id' of the channel is matched.
>>     > A channel is found if both the values match.
>>     >
>>     > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org
>>     <mailto:thomas.abraham@linaro.org>>
>>     > ---
>>     >  .../devicetree/bindings/dma/arm-pl330.txt          |   42
>>     +++++++++++++
>>     >  drivers/dma/pl330.c                                |   63
>>     +++++++++++++++++++-
>>     >  2 files changed, 103 insertions(+), 2 deletions(-)
>>     >  create mode 100644
>>     Documentation/devicetree/bindings/dma/arm-pl330.txt
>>     >
>>     > diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>     b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>     > new file mode 100644
>>     > index 0000000..46a8307
>>     > --- /dev/null
>>     > +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>     > @@ -0,0 +1,42 @@
>>     > +* ARM PrimeCell PL330 DMA Controller
>>     > +
>>     > +The ARM PrimeCell PL330 DMA controller can move blocks of memory
>>     contents
>>     > +between memory and peripherals or memory to memory.
>>     > +
>>     > +Required properties:
>>     > +  - compatible: should one or more of the following
>>     > +    - arm,pl330-pdma - For controllers that support mem-to-dev
>>     and dev-to-mem
>>     > +      transfers.
>>     > +    - arm,pl330-mdma - For controllers that support mem-to-mem
>>     transfers only.
>>
>>     And if they support both? I would think all controllers can support
>>     mem-to-mem. If so, the distinction can be made with the number of
>>     requests.
>>
>>
>> If a controller supports both types of transfer, the device node should
>> not claim compatibility for "arm,pl330-pdma" or "arm,pl330-mdma".
>> Compatible should be "arm,primecell".
>
> No, every Primecell peripheral has "arm,primecell", so it is not
> specific enough for a driver to use.
>
> Is there a case that a controller with peripheral requests cannot
> support mem-to-mem transfers? I don't think there is. You could decide
> you don't want to for other reasons like you don't have enough free
> channels, but that's really a s/w decision, not a h/w description.

Ok. The driver has now been changed in a way that DMA_MEMCPY
capability is assigned by default to a pl330 dma controller. The
DMA_SLAVE and DMA_CYCLIC capability are assigned if the controller
supports peripheral request interface. For mem-to-mem transfer channel
requests, the filter function specified for the request should check
for the right match.

>
>>
>>
>>     > +    - arm,primecell - should be included for all pl330 dma
>>     controller nodes.
>>     > +
>>     > +  - reg: physical base address of the controller and length of
>>     memory mapped
>>     > +    region.
>>     > +
>>     > +  - interrupts: interrupt number to the cpu.
>>     > +
>>     > +  - arm,primecell-periphid: should be 0x00041330.
>>
>>     Should be optional. It's only needed when the h/w value is wrong. This
>>     is already documented in primecell.txt.
>>
>>
>> Ok. This will be made optional.
>>
>>
>>
>>     > +
>>     > +  - arm,pl330-peri-reqs: number of actual peripheral requests
>>     connected to the
>>     > +    dma controller. Maximum value is 32.
>>
>>     Perhaps could be a bitmask for sparsely populated requests. May not
>>     matter since phandles will define the connections.
>>
>>     Can be optional and not present means 00 requests (mem-to-mem only).
>>
>>
>> As suggested by Russell, this property will be removed and its value
>> will be read from the configuration register.
>>
>
> Good. Reading a value of 0 requests can still be used to determine the
> controller is mem-to-mem only.
>
>>
>>     > +
>>     > +Example: (from Samsung's Exynos4 processor dtsi file)
>>     > +
>>     > +     pdma0: pdma@12680000 {
>>     > +             compatible = "arm,pl330-pdma", "arm,primecell";
>>     > +             reg = <0x12680000 0x1000>;
>>     > +             interrupts = <99>;
>>     > +             arm,primecell-periphid = <0x00041330>;
>>     > +             arm,pl330-peri-reqs = <30>;
>>     > +     };
>>     > +
>>     > +Client drivers (device nodes requiring dma transfers from
>>     dev-to-mem or
>>     > +mem-to-dev) should specify the DMA channel numbers using a
>>     two-value pair
>>     > +as shown below.
>>     > +
>>     > +  [property name]  = <[phandle of the dma controller] [dma
>>     request id]>;
>>     > +
>>     > +      where 'dma request id' is the dma request number which is
>>     connected
>>     > +      to the client controller.
>>     > +
>>     > +  Example:  tx-dma-channel = <&pdma0 12>;
>>
>>     I like this approach. I looked at this some and some PPC platforms do a
>>     node for each channel/request, but this is much more simple and similar
>>     to clock binding approach.
>>
>>     You need to define the property name. Probably just "dma-channel" is
>>     enough. For peripherals with more than 1, just list them out like when
>>     you have more than 1 interrupt. The order should be defined as part of
>>     that device's binding (i.e. 1st channel is tx and 2nd channel is rx).
>>
>>
>> I am little hesitant to do this the way you suggested. A controller
>> could have dma request lines connected to multiple dma controllers. So
>> the phandle could be different for each dma channel. Also, the client
>> drivers specify the property value for each dma channel requested (the
>> property value gets assigned to chan->private and then used by the
>> filter function to lookup the dma channel). So changing it the way you
>> have suggested would make things complex.
>>
>
> Perhaps you could make private point to the array entry rather than the
> property.
>
> But I don't have s strong opinion either way.

There could be cases where tx could be polled and rx uses dma transfer
and such this could vary across platforms. This would make parsing the
property value a little complex and so I still perfer to use property
for each dma channel required in the client device nodes.

>
>>
>>     > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>>     > index 9732995..984dc18 100644
>>     > --- a/drivers/dma/pl330.c
>>     > +++ b/drivers/dma/pl330.c
>>     > @@ -19,6 +19,7 @@
>>     >  #include <linux/amba/pl330.h>
>>     >  #include <linux/pm_runtime.h>
>>     >  #include <linux/scatterlist.h>
>>     > +#include <linux/of.h>
>>     >
>>     >  #define NR_DEFAULT_DESC      16
>>     >
>>     > @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void
>>     *param)
>>     >       if (chan->device->dev->driver != &pl330_driver.drv)
>>     >               return false;
>>     >
>>     > +#ifdef CONFIG_OF
>>     > +     if (chan->device->dev->of_node) {
>>     > +             const __be32 *prop_value;
>>     > +             phandle phandle;
>>     > +             struct device_node *node;
>>     > +
>>     > +             prop_value = ((struct property *)param)->value;
>>     > +             phandle = be32_to_cpup(prop_value++);
>>     > +             node = of_find_node_by_phandle(phandle);
>>     > +             return ((chan->private == node) &&
>>     > +                             (chan->chan_id ==
>>     be32_to_cpup(prop_value)));
>>     > +     }
>>     > +#endif
>>     > +
>>     >       peri_id = chan->private;
>>     >       return *peri_id == (unsigned)param;
>>     >  }
>>     > @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq,
>>     void *data)
>>     >               return IRQ_NONE;
>>     >  }
>>     >
>>     > +#ifdef CONFIG_OF
>>     > +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>>     > +{
>>     > +     struct dma_pl330_platdata *pdat;
>>     > +     const void *value;
>>     > +
>>     > +     pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>>     > +     if (!pdat)
>>     > +             return NULL;
>>
>>     Ideally, we will get rid of platform_data completely in the future, so I
>>     don't think filling it in from DT is the right approach.
>>
>>
>> Ok. I will drop the usage of platform data.
>>
>>
>>     > +
>>     > +     value = of_get_property(dev->of_node, "arm,pl330-peri-reqs",
>>     NULL);
>>     > +     if (value)
>>     > +             pdat->nr_valid_peri = be32_to_cpup(value);
>>
>>     Can't you use the u32 helper function here?
>>
>>
>> This will go away now since the number of peripherals connected will be
>> read from the configuration register.
>>
>>
>>     > +
>>     > +     if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>>     > +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>>     > +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>>     > +     } else if (of_device_is_compatible(dev->of_node,
>>     "arm,pl330-mdma")) {
>>     > +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>>     > +     } else if (of_device_is_compatible(dev->of_node,
>>     "arm,primecell")) {
>>
>>     I don't think the driver should look at this property. This is really
>>     just for the bus code.
>>
>>
>> The dma capabilities are derived from the compatible value by the
>> driver. Sorry, I do not understand your suggestion for this.
>>
>
> "arm,primecell" is purely for identifying peripherals with the Primecell
> ID registers and in turn used to create amba_device instances. You
> cannot imply that it is a DMA controller.

This has been changed as you suggested. Could you have a look at the
updated patch listed below?


For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.

Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 .../devicetree/bindings/dma/arm-pl330.txt          |   29 ++++++++++++++++
 drivers/dma/pl330.c                                |   35 +++++++++++++++++---
 2 files changed, 59 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..89f4b9c
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,29 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+  - compatible: should be "arm,primecell".
+  - reg: physical base address of the controller and length of memory mapped
+    region.
+  - interrupts: interrupt number to the cpu.
+
+Example: (from Samsung's Exynos4 processor dtsi file)
+
+	pdma0: pdma@12680000 {
+		compatible = "arm,primecell";
+		reg = <0x12680000 0x1000>;
+		interrupts = <99>;
+	};
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+  [property name]  = <[phandle of the dma controller] [dma request id]>;
+
+      where 'dma request id' is the dma request number which is connected
+      to the client controller.
+
+  Example:  tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9732995..0c55de4 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
 #include <linux/amba/pl330.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
+#include <linux/of.h>

 #define NR_DEFAULT_DESC	16

@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;

+#ifdef CONFIG_OF
+	if (chan->device->dev->of_node) {
+		const __be32 *prop_value;
+		phandle phandle;
+		struct device_node *node;
+
+		prop_value = ((struct property *)param)->value;
+		phandle = be32_to_cpup(prop_value++);
+		node = of_find_node_by_phandle(phandle);
+		return ((chan->private == node) &&
+				(chan->chan_id == be32_to_cpup(prop_value)));
+	}
+#endif
+
 	peri_id = chan->private;
 	return *peri_id == (unsigned)param;
 }
@@ -857,12 +872,17 @@ pl330_probe(struct amba_device *adev, const
struct amba_id *id)
 	INIT_LIST_HEAD(&pd->channels);

 	/* Initialize channel parameters */
-	num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
+	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
+			(u8)pi->pcfg.num_chan);
 	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);

 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		if (!adev->dev.of_node)
+			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		else
+			pch->chan.private = adev->dev.of_node;
+
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -876,11 +896,16 @@ pl330_probe(struct amba_device *adev, const
struct amba_id *id)
 	}

 	pd->dev = &adev->dev;
-	if (pdat)
+	if (pdat) {
 		pd->cap_mask = pdat->cap_mask;
-	else
+	} else {
 		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-
+		if (pi->pcfg.num_peri) {
+			dma_cap_set(DMA_SLAVE, pd->cap_mask);
+			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+		}	
+	}
+	
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
 	pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;
-- 
1.6.6.rc2



>
> Rob
>
>
>> Thanks for your help.
>>
>> Regards,
>> Thomas.
>>
>>
>>     Rob
>>
>>
>
>

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-31  6:46                   ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-31  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

On 30 August 2011 18:49, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,
>
> On 08/30/2011 07:18 AM, Thomas Abraham wrote:
>> Hi Rob,
>>
>> On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com
>> <mailto:robherring2@gmail.com>> wrote:
>>
>> ? ? Thomas,
>>
>> ? ? On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>> ? ? > For PL330 dma controllers instantiated from device tree, the channel
>> ? ? > lookup is based on phandle of the dma controller and dma request id
>> ? ? > specified by the client node. During probe, the private data of each
>> ? ? > channel of the controller is set to point to the device node of the
>> ? ? > dma controller. The 'chan_id' of the each channel is used as the
>> ? ? > dma request id.
>> ? ? >
>> ? ? > Client driver requesting dma channels specify the phandle of the
>> ? ? > dma controller and the request id. The pl330 filter function
>> ? ? > converts the phandle to the device node pointer and matches that
>> ? ? > with channel's private data. If a match is found, the request id
>> ? ? > from the client node and the 'chan_id' of the channel is matched.
>> ? ? > A channel is found if both the values match.
>> ? ? >
>> ? ? > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org
>> ? ? <mailto:thomas.abraham@linaro.org>>
>> ? ? > ---
>> ? ? > ?.../devicetree/bindings/dma/arm-pl330.txt ? ? ? ? ?| ? 42
>> ? ? +++++++++++++
>> ? ? > ?drivers/dma/pl330.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 63
>> ? ? +++++++++++++++++++-
>> ? ? > ?2 files changed, 103 insertions(+), 2 deletions(-)
>> ? ? > ?create mode 100644
>> ? ? Documentation/devicetree/bindings/dma/arm-pl330.txt
>> ? ? >
>> ? ? > diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> ? ? b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> ? ? > new file mode 100644
>> ? ? > index 0000000..46a8307
>> ? ? > --- /dev/null
>> ? ? > +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> ? ? > @@ -0,0 +1,42 @@
>> ? ? > +* ARM PrimeCell PL330 DMA Controller
>> ? ? > +
>> ? ? > +The ARM PrimeCell PL330 DMA controller can move blocks of memory
>> ? ? contents
>> ? ? > +between memory and peripherals or memory to memory.
>> ? ? > +
>> ? ? > +Required properties:
>> ? ? > + ?- compatible: should one or more of the following
>> ? ? > + ? ?- arm,pl330-pdma - For controllers that support mem-to-dev
>> ? ? and dev-to-mem
>> ? ? > + ? ? ?transfers.
>> ? ? > + ? ?- arm,pl330-mdma - For controllers that support mem-to-mem
>> ? ? transfers only.
>>
>> ? ? And if they support both? I would think all controllers can support
>> ? ? mem-to-mem. If so, the distinction can be made with the number of
>> ? ? requests.
>>
>>
>> If a controller supports both types of transfer, the device node should
>> not claim compatibility for "arm,pl330-pdma" or "arm,pl330-mdma".
>> Compatible should be "arm,primecell".
>
> No, every Primecell peripheral has "arm,primecell", so it is not
> specific enough for a driver to use.
>
> Is there a case that a controller with peripheral requests cannot
> support mem-to-mem transfers? I don't think there is. You could decide
> you don't want to for other reasons like you don't have enough free
> channels, but that's really a s/w decision, not a h/w description.

Ok. The driver has now been changed in a way that DMA_MEMCPY
capability is assigned by default to a pl330 dma controller. The
DMA_SLAVE and DMA_CYCLIC capability are assigned if the controller
supports peripheral request interface. For mem-to-mem transfer channel
requests, the filter function specified for the request should check
for the right match.

>
>>
>>
>> ? ? > + ? ?- arm,primecell - should be included for all pl330 dma
>> ? ? controller nodes.
>> ? ? > +
>> ? ? > + ?- reg: physical base address of the controller and length of
>> ? ? memory mapped
>> ? ? > + ? ?region.
>> ? ? > +
>> ? ? > + ?- interrupts: interrupt number to the cpu.
>> ? ? > +
>> ? ? > + ?- arm,primecell-periphid: should be 0x00041330.
>>
>> ? ? Should be optional. It's only needed when the h/w value is wrong. This
>> ? ? is already documented in primecell.txt.
>>
>>
>> Ok. This will be made optional.
>>
>>
>>
>> ? ? > +
>> ? ? > + ?- arm,pl330-peri-reqs: number of actual peripheral requests
>> ? ? connected to the
>> ? ? > + ? ?dma controller. Maximum value is 32.
>>
>> ? ? Perhaps could be a bitmask for sparsely populated requests. May not
>> ? ? matter since phandles will define the connections.
>>
>> ? ? Can be optional and not present means 00 requests (mem-to-mem only).
>>
>>
>> As suggested by Russell, this property will be removed and its value
>> will be read from the configuration register.
>>
>
> Good. Reading a value of 0 requests can still be used to determine the
> controller is mem-to-mem only.
>
>>
>> ? ? > +
>> ? ? > +Example: (from Samsung's Exynos4 processor dtsi file)
>> ? ? > +
>> ? ? > + ? ? pdma0: pdma at 12680000 {
>> ? ? > + ? ? ? ? ? ? compatible = "arm,pl330-pdma", "arm,primecell";
>> ? ? > + ? ? ? ? ? ? reg = <0x12680000 0x1000>;
>> ? ? > + ? ? ? ? ? ? interrupts = <99>;
>> ? ? > + ? ? ? ? ? ? arm,primecell-periphid = <0x00041330>;
>> ? ? > + ? ? ? ? ? ? arm,pl330-peri-reqs = <30>;
>> ? ? > + ? ? };
>> ? ? > +
>> ? ? > +Client drivers (device nodes requiring dma transfers from
>> ? ? dev-to-mem or
>> ? ? > +mem-to-dev) should specify the DMA channel numbers using a
>> ? ? two-value pair
>> ? ? > +as shown below.
>> ? ? > +
>> ? ? > + ?[property name] ?= <[phandle of the dma controller] [dma
>> ? ? request id]>;
>> ? ? > +
>> ? ? > + ? ? ?where 'dma request id' is the dma request number which is
>> ? ? connected
>> ? ? > + ? ? ?to the client controller.
>> ? ? > +
>> ? ? > + ?Example: ?tx-dma-channel = <&pdma0 12>;
>>
>> ? ? I like this approach. I looked at this some and some PPC platforms do a
>> ? ? node for each channel/request, but this is much more simple and similar
>> ? ? to clock binding approach.
>>
>> ? ? You need to define the property name. Probably just "dma-channel" is
>> ? ? enough. For peripherals with more than 1, just list them out like when
>> ? ? you have more than 1 interrupt. The order should be defined as part of
>> ? ? that device's binding (i.e. 1st channel is tx and 2nd channel is rx).
>>
>>
>> I am little hesitant to do this the way you suggested. A controller
>> could have dma request lines connected to multiple dma controllers. So
>> the phandle could be different for each dma channel. Also, the client
>> drivers specify the property value for each dma channel requested (the
>> property value gets assigned to chan->private and then used by the
>> filter function to lookup the dma channel). So changing it the way you
>> have suggested would make things complex.
>>
>
> Perhaps you could make private point to the array entry rather than the
> property.
>
> But I don't have s strong opinion either way.

There could be cases where tx could be polled and rx uses dma transfer
and such this could vary across platforms. This would make parsing the
property value a little complex and so I still perfer to use property
for each dma channel required in the client device nodes.

>
>>
>> ? ? > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> ? ? > index 9732995..984dc18 100644
>> ? ? > --- a/drivers/dma/pl330.c
>> ? ? > +++ b/drivers/dma/pl330.c
>> ? ? > @@ -19,6 +19,7 @@
>> ? ? > ?#include <linux/amba/pl330.h>
>> ? ? > ?#include <linux/pm_runtime.h>
>> ? ? > ?#include <linux/scatterlist.h>
>> ? ? > +#include <linux/of.h>
>> ? ? >
>> ? ? > ?#define NR_DEFAULT_DESC ? ? ?16
>> ? ? >
>> ? ? > @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void
>> ? ? *param)
>> ? ? > ? ? ? if (chan->device->dev->driver != &pl330_driver.drv)
>> ? ? > ? ? ? ? ? ? ? return false;
>> ? ? >
>> ? ? > +#ifdef CONFIG_OF
>> ? ? > + ? ? if (chan->device->dev->of_node) {
>> ? ? > + ? ? ? ? ? ? const __be32 *prop_value;
>> ? ? > + ? ? ? ? ? ? phandle phandle;
>> ? ? > + ? ? ? ? ? ? struct device_node *node;
>> ? ? > +
>> ? ? > + ? ? ? ? ? ? prop_value = ((struct property *)param)->value;
>> ? ? > + ? ? ? ? ? ? phandle = be32_to_cpup(prop_value++);
>> ? ? > + ? ? ? ? ? ? node = of_find_node_by_phandle(phandle);
>> ? ? > + ? ? ? ? ? ? return ((chan->private == node) &&
>> ? ? > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? (chan->chan_id ==
>> ? ? be32_to_cpup(prop_value)));
>> ? ? > + ? ? }
>> ? ? > +#endif
>> ? ? > +
>> ? ? > ? ? ? peri_id = chan->private;
>> ? ? > ? ? ? return *peri_id == (unsigned)param;
>> ? ? > ?}
>> ? ? > @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq,
>> ? ? void *data)
>> ? ? > ? ? ? ? ? ? ? return IRQ_NONE;
>> ? ? > ?}
>> ? ? >
>> ? ? > +#ifdef CONFIG_OF
>> ? ? > +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>> ? ? > +{
>> ? ? > + ? ? struct dma_pl330_platdata *pdat;
>> ? ? > + ? ? const void *value;
>> ? ? > +
>> ? ? > + ? ? pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>> ? ? > + ? ? if (!pdat)
>> ? ? > + ? ? ? ? ? ? return NULL;
>>
>> ? ? Ideally, we will get rid of platform_data completely in the future, so I
>> ? ? don't think filling it in from DT is the right approach.
>>
>>
>> Ok. I will drop the usage of platform data.
>>
>>
>> ? ? > +
>> ? ? > + ? ? value = of_get_property(dev->of_node, "arm,pl330-peri-reqs",
>> ? ? NULL);
>> ? ? > + ? ? if (value)
>> ? ? > + ? ? ? ? ? ? pdat->nr_valid_peri = be32_to_cpup(value);
>>
>> ? ? Can't you use the u32 helper function here?
>>
>>
>> This will go away now since the number of peripherals connected will be
>> read from the configuration register.
>>
>>
>> ? ? > +
>> ? ? > + ? ? if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>> ? ? > + ? ? ? ? ? ? dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>> ? ? > + ? ? ? ? ? ? dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>> ? ? > + ? ? } else if (of_device_is_compatible(dev->of_node,
>> ? ? "arm,pl330-mdma")) {
>> ? ? > + ? ? ? ? ? ? dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>> ? ? > + ? ? } else if (of_device_is_compatible(dev->of_node,
>> ? ? "arm,primecell")) {
>>
>> ? ? I don't think the driver should look at this property. This is really
>> ? ? just for the bus code.
>>
>>
>> The dma capabilities are derived from the compatible value by the
>> driver. Sorry, I do not understand your suggestion for this.
>>
>
> "arm,primecell" is purely for identifying peripherals with the Primecell
> ID registers and in turn used to create amba_device instances. You
> cannot imply that it is a DMA controller.

This has been changed as you suggested. Could you have a look at the
updated patch listed below?


For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.

Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 .../devicetree/bindings/dma/arm-pl330.txt          |   29 ++++++++++++++++
 drivers/dma/pl330.c                                |   35 +++++++++++++++++---
 2 files changed, 59 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..89f4b9c
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,29 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+  - compatible: should be "arm,primecell".
+  - reg: physical base address of the controller and length of memory mapped
+    region.
+  - interrupts: interrupt number to the cpu.
+
+Example: (from Samsung's Exynos4 processor dtsi file)
+
+	pdma0: pdma at 12680000 {
+		compatible = "arm,primecell";
+		reg = <0x12680000 0x1000>;
+		interrupts = <99>;
+	};
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+  [property name]  = <[phandle of the dma controller] [dma request id]>;
+
+      where 'dma request id' is the dma request number which is connected
+      to the client controller.
+
+  Example:  tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9732995..0c55de4 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
 #include <linux/amba/pl330.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
+#include <linux/of.h>

 #define NR_DEFAULT_DESC	16

@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;

+#ifdef CONFIG_OF
+	if (chan->device->dev->of_node) {
+		const __be32 *prop_value;
+		phandle phandle;
+		struct device_node *node;
+
+		prop_value = ((struct property *)param)->value;
+		phandle = be32_to_cpup(prop_value++);
+		node = of_find_node_by_phandle(phandle);
+		return ((chan->private == node) &&
+				(chan->chan_id == be32_to_cpup(prop_value)));
+	}
+#endif
+
 	peri_id = chan->private;
 	return *peri_id == (unsigned)param;
 }
@@ -857,12 +872,17 @@ pl330_probe(struct amba_device *adev, const
struct amba_id *id)
 	INIT_LIST_HEAD(&pd->channels);

 	/* Initialize channel parameters */
-	num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
+	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
+			(u8)pi->pcfg.num_chan);
 	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);

 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		if (!adev->dev.of_node)
+			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		else
+			pch->chan.private = adev->dev.of_node;
+
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -876,11 +896,16 @@ pl330_probe(struct amba_device *adev, const
struct amba_id *id)
 	}

 	pd->dev = &adev->dev;
-	if (pdat)
+	if (pdat) {
 		pd->cap_mask = pdat->cap_mask;
-	else
+	} else {
 		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-
+		if (pi->pcfg.num_peri) {
+			dma_cap_set(DMA_SLAVE, pd->cap_mask);
+			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+		}	
+	}
+	
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
 	pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;
-- 
1.6.6.rc2



>
> Rob
>
>
>> Thanks for your help.
>>
>> Regards,
>> Thomas.
>>
>>
>> ? ? Rob
>>
>>
>
>

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-31  6:46                   ` Thomas Abraham
@ 2011-08-31 12:51                     ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-31 12:51 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: boojin.kim, kgene.kim, patches, vinod.koul, devicetree-discuss,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Thomas,

On 08/31/2011 01:46 AM, Thomas Abraham wrote:
> Hi Rob,
> 
> On 30 August 2011 18:49, Rob Herring <robherring2@gmail.com> wrote:
>> Thomas,
>>
>> On 08/30/2011 07:18 AM, Thomas Abraham wrote:
>>> Hi Rob,
>>>
>>> On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com
>>> <mailto:robherring2@gmail.com>> wrote:
>>>
>>>     Thomas,
>>>
>>>     On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>>>     > For PL330 dma controllers instantiated from device tree, the channel
>>>     > lookup is based on phandle of the dma controller and dma request id
>>>     > specified by the client node. During probe, the private data of each
>>>     > channel of the controller is set to point to the device node of the
>>>     > dma controller. The 'chan_id' of the each channel is used as the
>>>     > dma request id.
>>>     >
>>>     > Client driver requesting dma channels specify the phandle of the
>>>     > dma controller and the request id. The pl330 filter function
>>>     > converts the phandle to the device node pointer and matches that
>>>     > with channel's private data. If a match is found, the request id
>>>     > from the client node and the 'chan_id' of the channel is matched.
>>>     > A channel is found if both the values match.
>>>     >
>>>     > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org
>>>     <mailto:thomas.abraham@linaro.org>>
>>>     > ---
>>>     >  .../devicetree/bindings/dma/arm-pl330.txt          |   42
>>>     +++++++++++++
>>>     >  drivers/dma/pl330.c                                |   63
>>>     +++++++++++++++++++-
>>>     >  2 files changed, 103 insertions(+), 2 deletions(-)
>>>     >  create mode 100644
>>>     Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     >
>>>     > diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     > new file mode 100644
>>>     > index 0000000..46a8307
>>>     > --- /dev/null
>>>     > +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     > @@ -0,0 +1,42 @@
>>>     > +* ARM PrimeCell PL330 DMA Controller
>>>     > +
>>>     > +The ARM PrimeCell PL330 DMA controller can move blocks of memory
>>>     contents
>>>     > +between memory and peripherals or memory to memory.
>>>     > +
>>>     > +Required properties:
>>>     > +  - compatible: should one or more of the following
>>>     > +    - arm,pl330-pdma - For controllers that support mem-to-dev
>>>     and dev-to-mem
>>>     > +      transfers.
>>>     > +    - arm,pl330-mdma - For controllers that support mem-to-mem
>>>     transfers only.
>>>
>>>     And if they support both? I would think all controllers can support
>>>     mem-to-mem. If so, the distinction can be made with the number of
>>>     requests.
>>>
>>>
>>> If a controller supports both types of transfer, the device node should
>>> not claim compatibility for "arm,pl330-pdma" or "arm,pl330-mdma".
>>> Compatible should be "arm,primecell".
>>
>> No, every Primecell peripheral has "arm,primecell", so it is not
>> specific enough for a driver to use.
>>
>> Is there a case that a controller with peripheral requests cannot
>> support mem-to-mem transfers? I don't think there is. You could decide
>> you don't want to for other reasons like you don't have enough free
>> channels, but that's really a s/w decision, not a h/w description.
> 
> Ok. The driver has now been changed in a way that DMA_MEMCPY
> capability is assigned by default to a pl330 dma controller. The
> DMA_SLAVE and DMA_CYCLIC capability are assigned if the controller
> supports peripheral request interface. For mem-to-mem transfer channel
> requests, the filter function specified for the request should check
> for the right match.
> 
>>
>>>
>>>
>>>     > +    - arm,primecell - should be included for all pl330 dma
>>>     controller nodes.
>>>     > +
>>>     > +  - reg: physical base address of the controller and length of
>>>     memory mapped
>>>     > +    region.
>>>     > +
>>>     > +  - interrupts: interrupt number to the cpu.
>>>     > +
>>>     > +  - arm,primecell-periphid: should be 0x00041330.
>>>
>>>     Should be optional. It's only needed when the h/w value is wrong. This
>>>     is already documented in primecell.txt.
>>>
>>>
>>> Ok. This will be made optional.
>>>
>>>
>>>
>>>     > +
>>>     > +  - arm,pl330-peri-reqs: number of actual peripheral requests
>>>     connected to the
>>>     > +    dma controller. Maximum value is 32.
>>>
>>>     Perhaps could be a bitmask for sparsely populated requests. May not
>>>     matter since phandles will define the connections.
>>>
>>>     Can be optional and not present means 00 requests (mem-to-mem only).
>>>
>>>
>>> As suggested by Russell, this property will be removed and its value
>>> will be read from the configuration register.
>>>
>>
>> Good. Reading a value of 0 requests can still be used to determine the
>> controller is mem-to-mem only.
>>
>>>
>>>     > +
>>>     > +Example: (from Samsung's Exynos4 processor dtsi file)
>>>     > +
>>>     > +     pdma0: pdma@12680000 {
>>>     > +             compatible = "arm,pl330-pdma", "arm,primecell";
>>>     > +             reg = <0x12680000 0x1000>;
>>>     > +             interrupts = <99>;
>>>     > +             arm,primecell-periphid = <0x00041330>;
>>>     > +             arm,pl330-peri-reqs = <30>;
>>>     > +     };
>>>     > +
>>>     > +Client drivers (device nodes requiring dma transfers from
>>>     dev-to-mem or
>>>     > +mem-to-dev) should specify the DMA channel numbers using a
>>>     two-value pair
>>>     > +as shown below.
>>>     > +
>>>     > +  [property name]  = <[phandle of the dma controller] [dma
>>>     request id]>;
>>>     > +
>>>     > +      where 'dma request id' is the dma request number which is
>>>     connected
>>>     > +      to the client controller.
>>>     > +
>>>     > +  Example:  tx-dma-channel = <&pdma0 12>;
>>>
>>>     I like this approach. I looked at this some and some PPC platforms do a
>>>     node for each channel/request, but this is much more simple and similar
>>>     to clock binding approach.
>>>
>>>     You need to define the property name. Probably just "dma-channel" is
>>>     enough. For peripherals with more than 1, just list them out like when
>>>     you have more than 1 interrupt. The order should be defined as part of
>>>     that device's binding (i.e. 1st channel is tx and 2nd channel is rx).
>>>
>>>
>>> I am little hesitant to do this the way you suggested. A controller
>>> could have dma request lines connected to multiple dma controllers. So
>>> the phandle could be different for each dma channel. Also, the client
>>> drivers specify the property value for each dma channel requested (the
>>> property value gets assigned to chan->private and then used by the
>>> filter function to lookup the dma channel). So changing it the way you
>>> have suggested would make things complex.
>>>
>>
>> Perhaps you could make private point to the array entry rather than the
>> property.
>>
>> But I don't have s strong opinion either way.
> 
> There could be cases where tx could be polled and rx uses dma transfer
> and such this could vary across platforms. This would make parsing the
> property value a little complex and so I still perfer to use property
> for each dma channel required in the client device nodes.
> 
>>
>>>
>>>     > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>>>     > index 9732995..984dc18 100644
>>>     > --- a/drivers/dma/pl330.c
>>>     > +++ b/drivers/dma/pl330.c
>>>     > @@ -19,6 +19,7 @@
>>>     >  #include <linux/amba/pl330.h>
>>>     >  #include <linux/pm_runtime.h>
>>>     >  #include <linux/scatterlist.h>
>>>     > +#include <linux/of.h>
>>>     >
>>>     >  #define NR_DEFAULT_DESC      16
>>>     >
>>>     > @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void
>>>     *param)
>>>     >       if (chan->device->dev->driver != &pl330_driver.drv)
>>>     >               return false;
>>>     >
>>>     > +#ifdef CONFIG_OF
>>>     > +     if (chan->device->dev->of_node) {
>>>     > +             const __be32 *prop_value;
>>>     > +             phandle phandle;
>>>     > +             struct device_node *node;
>>>     > +
>>>     > +             prop_value = ((struct property *)param)->value;
>>>     > +             phandle = be32_to_cpup(prop_value++);
>>>     > +             node = of_find_node_by_phandle(phandle);
>>>     > +             return ((chan->private == node) &&
>>>     > +                             (chan->chan_id ==
>>>     be32_to_cpup(prop_value)));
>>>     > +     }
>>>     > +#endif
>>>     > +
>>>     >       peri_id = chan->private;
>>>     >       return *peri_id == (unsigned)param;
>>>     >  }
>>>     > @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq,
>>>     void *data)
>>>     >               return IRQ_NONE;
>>>     >  }
>>>     >
>>>     > +#ifdef CONFIG_OF
>>>     > +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>>>     > +{
>>>     > +     struct dma_pl330_platdata *pdat;
>>>     > +     const void *value;
>>>     > +
>>>     > +     pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>>>     > +     if (!pdat)
>>>     > +             return NULL;
>>>
>>>     Ideally, we will get rid of platform_data completely in the future, so I
>>>     don't think filling it in from DT is the right approach.
>>>
>>>
>>> Ok. I will drop the usage of platform data.
>>>
>>>
>>>     > +
>>>     > +     value = of_get_property(dev->of_node, "arm,pl330-peri-reqs",
>>>     NULL);
>>>     > +     if (value)
>>>     > +             pdat->nr_valid_peri = be32_to_cpup(value);
>>>
>>>     Can't you use the u32 helper function here?
>>>
>>>
>>> This will go away now since the number of peripherals connected will be
>>> read from the configuration register.
>>>
>>>
>>>     > +
>>>     > +     if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>>>     > +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>>>     > +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>>>     > +     } else if (of_device_is_compatible(dev->of_node,
>>>     "arm,pl330-mdma")) {
>>>     > +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>>>     > +     } else if (of_device_is_compatible(dev->of_node,
>>>     "arm,primecell")) {
>>>
>>>     I don't think the driver should look at this property. This is really
>>>     just for the bus code.
>>>
>>>
>>> The dma capabilities are derived from the compatible value by the
>>> driver. Sorry, I do not understand your suggestion for this.
>>>
>>
>> "arm,primecell" is purely for identifying peripherals with the Primecell
>> ID registers and in turn used to create amba_device instances. You
>> cannot imply that it is a DMA controller.
> 
> This has been changed as you suggested. Could you have a look at the
> updated patch listed below?
> 
> 
> For PL330 dma controllers instantiated from device tree, the channel
> lookup is based on phandle of the dma controller and dma request id
> specified by the client node. During probe, the private data of each
> channel of the controller is set to point to the device node of the
> dma controller. The 'chan_id' of the each channel is used as the
> dma request id.
> 
> Client driver requesting dma channels specify the phandle of the
> dma controller and the request id. The pl330 filter function
> converts the phandle to the device node pointer and matches that
> with channel's private data. If a match is found, the request id
> from the client node and the 'chan_id' of the channel is matched.
> A channel is found if both the values match.
> 
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  .../devicetree/bindings/dma/arm-pl330.txt          |   29 ++++++++++++++++
>  drivers/dma/pl330.c                                |   35 +++++++++++++++++---
>  2 files changed, 59 insertions(+), 5 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
> b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> new file mode 100644
> index 0000000..89f4b9c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> @@ -0,0 +1,29 @@
> +* ARM PrimeCell PL330 DMA Controller
> +
> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
> +between memory and peripherals or memory to memory.
> +
> +Required properties:
> +  - compatible: should be "arm,primecell".

Sorry, I guess I wasn't clear. This has to be "arm,primecell" plus
something else. In this case, "arm,pl330". If the IP is modified from
standard ARM version (like ST likes to do), then something like
"samsung,pl330" would be appropriate.

This is not actually used by the kernel at the moment, but could if
modified versions of pl330 show up.

> +  - reg: physical base address of the controller and length of memory mapped
> +    region.
> +  - interrupts: interrupt number to the cpu.
> +
> +Example: (from Samsung's Exynos4 processor dtsi file)
> +
> +	pdma0: pdma@12680000 {
> +		compatible = "arm,primecell";
> +		reg = <0x12680000 0x1000>;
> +		interrupts = <99>;
> +	};
> +
> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
> +as shown below.
> +
> +  [property name]  = <[phandle of the dma controller] [dma request id]>;

At least fix the "-dma-channel" part of the name. It not clear if that's
the case or just an example.

[name]-dma-channel = <[phandle of the dma controller] [dma request id]>;


The rest looks good.

Rob

> +
> +      where 'dma request id' is the dma request number which is connected
> +      to the client controller.
> +
> +  Example:  tx-dma-channel = <&pdma0 12>;
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 9732995..0c55de4 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -19,6 +19,7 @@
>  #include <linux/amba/pl330.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> +#include <linux/of.h>
> 
>  #define NR_DEFAULT_DESC	16
> 
> @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
>  	if (chan->device->dev->driver != &pl330_driver.drv)
>  		return false;
> 
> +#ifdef CONFIG_OF
> +	if (chan->device->dev->of_node) {
> +		const __be32 *prop_value;
> +		phandle phandle;
> +		struct device_node *node;
> +
> +		prop_value = ((struct property *)param)->value;
> +		phandle = be32_to_cpup(prop_value++);
> +		node = of_find_node_by_phandle(phandle);
> +		return ((chan->private == node) &&
> +				(chan->chan_id == be32_to_cpup(prop_value)));
> +	}
> +#endif
> +
>  	peri_id = chan->private;
>  	return *peri_id == (unsigned)param;
>  }
> @@ -857,12 +872,17 @@ pl330_probe(struct amba_device *adev, const
> struct amba_id *id)
>  	INIT_LIST_HEAD(&pd->channels);
> 
>  	/* Initialize channel parameters */
> -	num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
> +	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
> +			(u8)pi->pcfg.num_chan);
>  	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
> 
>  	for (i = 0; i < num_chan; i++) {
>  		pch = &pdmac->peripherals[i];
> -		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		if (!adev->dev.of_node)
> +			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		else
> +			pch->chan.private = adev->dev.of_node;
> +
>  		INIT_LIST_HEAD(&pch->work_list);
>  		spin_lock_init(&pch->lock);
>  		pch->pl330_chid = NULL;
> @@ -876,11 +896,16 @@ pl330_probe(struct amba_device *adev, const
> struct amba_id *id)
>  	}
> 
>  	pd->dev = &adev->dev;
> -	if (pdat)
> +	if (pdat) {
>  		pd->cap_mask = pdat->cap_mask;
> -	else
> +	} else {
>  		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
> -
> +		if (pi->pcfg.num_peri) {
> +			dma_cap_set(DMA_SLAVE, pd->cap_mask);
> +			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
> +		}	
> +	}
> +	
>  	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
>  	pd->device_free_chan_resources = pl330_free_chan_resources;
>  	pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-31 12:51                     ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-31 12:51 UTC (permalink / raw)
  To: linux-arm-kernel

Thomas,

On 08/31/2011 01:46 AM, Thomas Abraham wrote:
> Hi Rob,
> 
> On 30 August 2011 18:49, Rob Herring <robherring2@gmail.com> wrote:
>> Thomas,
>>
>> On 08/30/2011 07:18 AM, Thomas Abraham wrote:
>>> Hi Rob,
>>>
>>> On 26 August 2011 18:46, Rob Herring <robherring2@gmail.com
>>> <mailto:robherring2@gmail.com>> wrote:
>>>
>>>     Thomas,
>>>
>>>     On 08/26/2011 03:40 AM, Thomas Abraham wrote:
>>>     > For PL330 dma controllers instantiated from device tree, the channel
>>>     > lookup is based on phandle of the dma controller and dma request id
>>>     > specified by the client node. During probe, the private data of each
>>>     > channel of the controller is set to point to the device node of the
>>>     > dma controller. The 'chan_id' of the each channel is used as the
>>>     > dma request id.
>>>     >
>>>     > Client driver requesting dma channels specify the phandle of the
>>>     > dma controller and the request id. The pl330 filter function
>>>     > converts the phandle to the device node pointer and matches that
>>>     > with channel's private data. If a match is found, the request id
>>>     > from the client node and the 'chan_id' of the channel is matched.
>>>     > A channel is found if both the values match.
>>>     >
>>>     > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org
>>>     <mailto:thomas.abraham@linaro.org>>
>>>     > ---
>>>     >  .../devicetree/bindings/dma/arm-pl330.txt          |   42
>>>     +++++++++++++
>>>     >  drivers/dma/pl330.c                                |   63
>>>     +++++++++++++++++++-
>>>     >  2 files changed, 103 insertions(+), 2 deletions(-)
>>>     >  create mode 100644
>>>     Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     >
>>>     > diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     > new file mode 100644
>>>     > index 0000000..46a8307
>>>     > --- /dev/null
>>>     > +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>     > @@ -0,0 +1,42 @@
>>>     > +* ARM PrimeCell PL330 DMA Controller
>>>     > +
>>>     > +The ARM PrimeCell PL330 DMA controller can move blocks of memory
>>>     contents
>>>     > +between memory and peripherals or memory to memory.
>>>     > +
>>>     > +Required properties:
>>>     > +  - compatible: should one or more of the following
>>>     > +    - arm,pl330-pdma - For controllers that support mem-to-dev
>>>     and dev-to-mem
>>>     > +      transfers.
>>>     > +    - arm,pl330-mdma - For controllers that support mem-to-mem
>>>     transfers only.
>>>
>>>     And if they support both? I would think all controllers can support
>>>     mem-to-mem. If so, the distinction can be made with the number of
>>>     requests.
>>>
>>>
>>> If a controller supports both types of transfer, the device node should
>>> not claim compatibility for "arm,pl330-pdma" or "arm,pl330-mdma".
>>> Compatible should be "arm,primecell".
>>
>> No, every Primecell peripheral has "arm,primecell", so it is not
>> specific enough for a driver to use.
>>
>> Is there a case that a controller with peripheral requests cannot
>> support mem-to-mem transfers? I don't think there is. You could decide
>> you don't want to for other reasons like you don't have enough free
>> channels, but that's really a s/w decision, not a h/w description.
> 
> Ok. The driver has now been changed in a way that DMA_MEMCPY
> capability is assigned by default to a pl330 dma controller. The
> DMA_SLAVE and DMA_CYCLIC capability are assigned if the controller
> supports peripheral request interface. For mem-to-mem transfer channel
> requests, the filter function specified for the request should check
> for the right match.
> 
>>
>>>
>>>
>>>     > +    - arm,primecell - should be included for all pl330 dma
>>>     controller nodes.
>>>     > +
>>>     > +  - reg: physical base address of the controller and length of
>>>     memory mapped
>>>     > +    region.
>>>     > +
>>>     > +  - interrupts: interrupt number to the cpu.
>>>     > +
>>>     > +  - arm,primecell-periphid: should be 0x00041330.
>>>
>>>     Should be optional. It's only needed when the h/w value is wrong. This
>>>     is already documented in primecell.txt.
>>>
>>>
>>> Ok. This will be made optional.
>>>
>>>
>>>
>>>     > +
>>>     > +  - arm,pl330-peri-reqs: number of actual peripheral requests
>>>     connected to the
>>>     > +    dma controller. Maximum value is 32.
>>>
>>>     Perhaps could be a bitmask for sparsely populated requests. May not
>>>     matter since phandles will define the connections.
>>>
>>>     Can be optional and not present means 00 requests (mem-to-mem only).
>>>
>>>
>>> As suggested by Russell, this property will be removed and its value
>>> will be read from the configuration register.
>>>
>>
>> Good. Reading a value of 0 requests can still be used to determine the
>> controller is mem-to-mem only.
>>
>>>
>>>     > +
>>>     > +Example: (from Samsung's Exynos4 processor dtsi file)
>>>     > +
>>>     > +     pdma0: pdma at 12680000 {
>>>     > +             compatible = "arm,pl330-pdma", "arm,primecell";
>>>     > +             reg = <0x12680000 0x1000>;
>>>     > +             interrupts = <99>;
>>>     > +             arm,primecell-periphid = <0x00041330>;
>>>     > +             arm,pl330-peri-reqs = <30>;
>>>     > +     };
>>>     > +
>>>     > +Client drivers (device nodes requiring dma transfers from
>>>     dev-to-mem or
>>>     > +mem-to-dev) should specify the DMA channel numbers using a
>>>     two-value pair
>>>     > +as shown below.
>>>     > +
>>>     > +  [property name]  = <[phandle of the dma controller] [dma
>>>     request id]>;
>>>     > +
>>>     > +      where 'dma request id' is the dma request number which is
>>>     connected
>>>     > +      to the client controller.
>>>     > +
>>>     > +  Example:  tx-dma-channel = <&pdma0 12>;
>>>
>>>     I like this approach. I looked at this some and some PPC platforms do a
>>>     node for each channel/request, but this is much more simple and similar
>>>     to clock binding approach.
>>>
>>>     You need to define the property name. Probably just "dma-channel" is
>>>     enough. For peripherals with more than 1, just list them out like when
>>>     you have more than 1 interrupt. The order should be defined as part of
>>>     that device's binding (i.e. 1st channel is tx and 2nd channel is rx).
>>>
>>>
>>> I am little hesitant to do this the way you suggested. A controller
>>> could have dma request lines connected to multiple dma controllers. So
>>> the phandle could be different for each dma channel. Also, the client
>>> drivers specify the property value for each dma channel requested (the
>>> property value gets assigned to chan->private and then used by the
>>> filter function to lookup the dma channel). So changing it the way you
>>> have suggested would make things complex.
>>>
>>
>> Perhaps you could make private point to the array entry rather than the
>> property.
>>
>> But I don't have s strong opinion either way.
> 
> There could be cases where tx could be polled and rx uses dma transfer
> and such this could vary across platforms. This would make parsing the
> property value a little complex and so I still perfer to use property
> for each dma channel required in the client device nodes.
> 
>>
>>>
>>>     > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>>>     > index 9732995..984dc18 100644
>>>     > --- a/drivers/dma/pl330.c
>>>     > +++ b/drivers/dma/pl330.c
>>>     > @@ -19,6 +19,7 @@
>>>     >  #include <linux/amba/pl330.h>
>>>     >  #include <linux/pm_runtime.h>
>>>     >  #include <linux/scatterlist.h>
>>>     > +#include <linux/of.h>
>>>     >
>>>     >  #define NR_DEFAULT_DESC      16
>>>     >
>>>     > @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void
>>>     *param)
>>>     >       if (chan->device->dev->driver != &pl330_driver.drv)
>>>     >               return false;
>>>     >
>>>     > +#ifdef CONFIG_OF
>>>     > +     if (chan->device->dev->of_node) {
>>>     > +             const __be32 *prop_value;
>>>     > +             phandle phandle;
>>>     > +             struct device_node *node;
>>>     > +
>>>     > +             prop_value = ((struct property *)param)->value;
>>>     > +             phandle = be32_to_cpup(prop_value++);
>>>     > +             node = of_find_node_by_phandle(phandle);
>>>     > +             return ((chan->private == node) &&
>>>     > +                             (chan->chan_id ==
>>>     be32_to_cpup(prop_value)));
>>>     > +     }
>>>     > +#endif
>>>     > +
>>>     >       peri_id = chan->private;
>>>     >       return *peri_id == (unsigned)param;
>>>     >  }
>>>     > @@ -777,6 +792,40 @@ static irqreturn_t pl330_irq_handler(int irq,
>>>     void *data)
>>>     >               return IRQ_NONE;
>>>     >  }
>>>     >
>>>     > +#ifdef CONFIG_OF
>>>     > +static struct dma_pl330_platdata *pl330_parse_dt(struct device *dev)
>>>     > +{
>>>     > +     struct dma_pl330_platdata *pdat;
>>>     > +     const void *value;
>>>     > +
>>>     > +     pdat = devm_kzalloc(dev, sizeof(*pdat), GFP_KERNEL);
>>>     > +     if (!pdat)
>>>     > +             return NULL;
>>>
>>>     Ideally, we will get rid of platform_data completely in the future, so I
>>>     don't think filling it in from DT is the right approach.
>>>
>>>
>>> Ok. I will drop the usage of platform data.
>>>
>>>
>>>     > +
>>>     > +     value = of_get_property(dev->of_node, "arm,pl330-peri-reqs",
>>>     NULL);
>>>     > +     if (value)
>>>     > +             pdat->nr_valid_peri = be32_to_cpup(value);
>>>
>>>     Can't you use the u32 helper function here?
>>>
>>>
>>> This will go away now since the number of peripherals connected will be
>>> read from the configuration register.
>>>
>>>
>>>     > +
>>>     > +     if (of_device_is_compatible(dev->of_node, "arm,pl330-pdma")) {
>>>     > +             dma_cap_set(DMA_SLAVE, pdat->cap_mask);
>>>     > +             dma_cap_set(DMA_CYCLIC, pdat->cap_mask);
>>>     > +     } else if (of_device_is_compatible(dev->of_node,
>>>     "arm,pl330-mdma")) {
>>>     > +             dma_cap_set(DMA_MEMCPY, pdat->cap_mask);
>>>     > +     } else if (of_device_is_compatible(dev->of_node,
>>>     "arm,primecell")) {
>>>
>>>     I don't think the driver should look at this property. This is really
>>>     just for the bus code.
>>>
>>>
>>> The dma capabilities are derived from the compatible value by the
>>> driver. Sorry, I do not understand your suggestion for this.
>>>
>>
>> "arm,primecell" is purely for identifying peripherals with the Primecell
>> ID registers and in turn used to create amba_device instances. You
>> cannot imply that it is a DMA controller.
> 
> This has been changed as you suggested. Could you have a look at the
> updated patch listed below?
> 
> 
> For PL330 dma controllers instantiated from device tree, the channel
> lookup is based on phandle of the dma controller and dma request id
> specified by the client node. During probe, the private data of each
> channel of the controller is set to point to the device node of the
> dma controller. The 'chan_id' of the each channel is used as the
> dma request id.
> 
> Client driver requesting dma channels specify the phandle of the
> dma controller and the request id. The pl330 filter function
> converts the phandle to the device node pointer and matches that
> with channel's private data. If a match is found, the request id
> from the client node and the 'chan_id' of the channel is matched.
> A channel is found if both the values match.
> 
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  .../devicetree/bindings/dma/arm-pl330.txt          |   29 ++++++++++++++++
>  drivers/dma/pl330.c                                |   35 +++++++++++++++++---
>  2 files changed, 59 insertions(+), 5 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
> b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> new file mode 100644
> index 0000000..89f4b9c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> @@ -0,0 +1,29 @@
> +* ARM PrimeCell PL330 DMA Controller
> +
> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
> +between memory and peripherals or memory to memory.
> +
> +Required properties:
> +  - compatible: should be "arm,primecell".

Sorry, I guess I wasn't clear. This has to be "arm,primecell" plus
something else. In this case, "arm,pl330". If the IP is modified from
standard ARM version (like ST likes to do), then something like
"samsung,pl330" would be appropriate.

This is not actually used by the kernel at the moment, but could if
modified versions of pl330 show up.

> +  - reg: physical base address of the controller and length of memory mapped
> +    region.
> +  - interrupts: interrupt number to the cpu.
> +
> +Example: (from Samsung's Exynos4 processor dtsi file)
> +
> +	pdma0: pdma at 12680000 {
> +		compatible = "arm,primecell";
> +		reg = <0x12680000 0x1000>;
> +		interrupts = <99>;
> +	};
> +
> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
> +as shown below.
> +
> +  [property name]  = <[phandle of the dma controller] [dma request id]>;

At least fix the "-dma-channel" part of the name. It not clear if that's
the case or just an example.

[name]-dma-channel = <[phandle of the dma controller] [dma request id]>;


The rest looks good.

Rob

> +
> +      where 'dma request id' is the dma request number which is connected
> +      to the client controller.
> +
> +  Example:  tx-dma-channel = <&pdma0 12>;
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 9732995..0c55de4 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -19,6 +19,7 @@
>  #include <linux/amba/pl330.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> +#include <linux/of.h>
> 
>  #define NR_DEFAULT_DESC	16
> 
> @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
>  	if (chan->device->dev->driver != &pl330_driver.drv)
>  		return false;
> 
> +#ifdef CONFIG_OF
> +	if (chan->device->dev->of_node) {
> +		const __be32 *prop_value;
> +		phandle phandle;
> +		struct device_node *node;
> +
> +		prop_value = ((struct property *)param)->value;
> +		phandle = be32_to_cpup(prop_value++);
> +		node = of_find_node_by_phandle(phandle);
> +		return ((chan->private == node) &&
> +				(chan->chan_id == be32_to_cpup(prop_value)));
> +	}
> +#endif
> +
>  	peri_id = chan->private;
>  	return *peri_id == (unsigned)param;
>  }
> @@ -857,12 +872,17 @@ pl330_probe(struct amba_device *adev, const
> struct amba_id *id)
>  	INIT_LIST_HEAD(&pd->channels);
> 
>  	/* Initialize channel parameters */
> -	num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
> +	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
> +			(u8)pi->pcfg.num_chan);
>  	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
> 
>  	for (i = 0; i < num_chan; i++) {
>  		pch = &pdmac->peripherals[i];
> -		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		if (!adev->dev.of_node)
> +			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
> +		else
> +			pch->chan.private = adev->dev.of_node;
> +
>  		INIT_LIST_HEAD(&pch->work_list);
>  		spin_lock_init(&pch->lock);
>  		pch->pl330_chid = NULL;
> @@ -876,11 +896,16 @@ pl330_probe(struct amba_device *adev, const
> struct amba_id *id)
>  	}
> 
>  	pd->dev = &adev->dev;
> -	if (pdat)
> +	if (pdat) {
>  		pd->cap_mask = pdat->cap_mask;
> -	else
> +	} else {
>  		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
> -
> +		if (pi->pcfg.num_peri) {
> +			dma_cap_set(DMA_SLAVE, pd->cap_mask);
> +			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
> +		}	
> +	}
> +	
>  	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
>  	pd->device_free_chan_resources = pl330_free_chan_resources;
>  	pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-31 12:51                     ` Rob Herring
@ 2011-08-31 15:46                       ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-31 15:46 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches, vinod.koul,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Hi Rob,

On 31 August 2011 18:21, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,

[...]

>> For PL330 dma controllers instantiated from device tree, the channel
>> lookup is based on phandle of the dma controller and dma request id
>> specified by the client node. During probe, the private data of each
>> channel of the controller is set to point to the device node of the
>> dma controller. The 'chan_id' of the each channel is used as the
>> dma request id.
>>
>> Client driver requesting dma channels specify the phandle of the
>> dma controller and the request id. The pl330 filter function
>> converts the phandle to the device node pointer and matches that
>> with channel's private data. If a match is found, the request id
>> from the client node and the 'chan_id' of the channel is matched.
>> A channel is found if both the values match.
>>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>>  .../devicetree/bindings/dma/arm-pl330.txt          |   29 ++++++++++++++++
>>  drivers/dma/pl330.c                                |   35 +++++++++++++++++---
>>  2 files changed, 59 insertions(+), 5 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> new file mode 100644
>> index 0000000..89f4b9c
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> @@ -0,0 +1,29 @@
>> +* ARM PrimeCell PL330 DMA Controller
>> +
>> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
>> +between memory and peripherals or memory to memory.
>> +
>> +Required properties:
>> +  - compatible: should be "arm,primecell".
>
> Sorry, I guess I wasn't clear. This has to be "arm,primecell" plus
> something else. In this case, "arm,pl330". If the IP is modified from
> standard ARM version (like ST likes to do), then something like
> "samsung,pl330" would be appropriate.
>
> This is not actually used by the kernel at the moment, but could if
> modified versions of pl330 show up.

of_platform_bus_create() checks for  "arm,primecell" compatible value
to instantiate a amba device from device tree. The peripheral_id is
also noted in the amba device instance. The amba drivers register with
a with a peripheral_id and peripheral_id is used match amba device
with a driver.

In cases of modified version of the same IP, the peripheral_id would
be different. So, "arm,primecell" would just be enough for now. Any
other compatible value would anyway go unused. I did use
"arm,primecell-pdma" and "arm-primecell-mdma" to derive the dma_cap
value. But, as per your comments, I dropped it.

So, for now, I will just list "arm,primecell" as required compatible
value. Please let me know if "arm,pl330" would be required here.

>
>> +  - reg: physical base address of the controller and length of memory mapped
>> +    region.
>> +  - interrupts: interrupt number to the cpu.
>> +
>> +Example: (from Samsung's Exynos4 processor dtsi file)
>> +
>> +     pdma0: pdma@12680000 {
>> +             compatible = "arm,primecell";
>> +             reg = <0x12680000 0x1000>;
>> +             interrupts = <99>;
>> +     };
>> +
>> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
>> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
>> +as shown below.
>> +
>> +  [property name]  = <[phandle of the dma controller] [dma request id]>;
>
> At least fix the "-dma-channel" part of the name. It not clear if that's
> the case or just an example.
>
> [name]-dma-channel = <[phandle of the dma controller] [dma request id]>;

The name of the property that specifies the dma channel to use is
decided by the client device node. It is not enforced by the dma
device node. So, there will be no specific requirement stated in the
documentation for pl330 device node.

>
>
> The rest looks good.

Thanks for your review and comments.

Regards,
Thomas.

>
> Rob
>

[...]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-31 15:46                       ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-08-31 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

On 31 August 2011 18:21, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,

[...]

>> For PL330 dma controllers instantiated from device tree, the channel
>> lookup is based on phandle of the dma controller and dma request id
>> specified by the client node. During probe, the private data of each
>> channel of the controller is set to point to the device node of the
>> dma controller. The 'chan_id' of the each channel is used as the
>> dma request id.
>>
>> Client driver requesting dma channels specify the phandle of the
>> dma controller and the request id. The pl330 filter function
>> converts the phandle to the device node pointer and matches that
>> with channel's private data. If a match is found, the request id
>> from the client node and the 'chan_id' of the channel is matched.
>> A channel is found if both the values match.
>>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> ?.../devicetree/bindings/dma/arm-pl330.txt ? ? ? ? ?| ? 29 ++++++++++++++++
>> ?drivers/dma/pl330.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 35 +++++++++++++++++---
>> ?2 files changed, 59 insertions(+), 5 deletions(-)
>> ?create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> new file mode 100644
>> index 0000000..89f4b9c
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> @@ -0,0 +1,29 @@
>> +* ARM PrimeCell PL330 DMA Controller
>> +
>> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
>> +between memory and peripherals or memory to memory.
>> +
>> +Required properties:
>> + ?- compatible: should be "arm,primecell".
>
> Sorry, I guess I wasn't clear. This has to be "arm,primecell" plus
> something else. In this case, "arm,pl330". If the IP is modified from
> standard ARM version (like ST likes to do), then something like
> "samsung,pl330" would be appropriate.
>
> This is not actually used by the kernel at the moment, but could if
> modified versions of pl330 show up.

of_platform_bus_create() checks for  "arm,primecell" compatible value
to instantiate a amba device from device tree. The peripheral_id is
also noted in the amba device instance. The amba drivers register with
a with a peripheral_id and peripheral_id is used match amba device
with a driver.

In cases of modified version of the same IP, the peripheral_id would
be different. So, "arm,primecell" would just be enough for now. Any
other compatible value would anyway go unused. I did use
"arm,primecell-pdma" and "arm-primecell-mdma" to derive the dma_cap
value. But, as per your comments, I dropped it.

So, for now, I will just list "arm,primecell" as required compatible
value. Please let me know if "arm,pl330" would be required here.

>
>> + ?- reg: physical base address of the controller and length of memory mapped
>> + ? ?region.
>> + ?- interrupts: interrupt number to the cpu.
>> +
>> +Example: (from Samsung's Exynos4 processor dtsi file)
>> +
>> + ? ? pdma0: pdma at 12680000 {
>> + ? ? ? ? ? ? compatible = "arm,primecell";
>> + ? ? ? ? ? ? reg = <0x12680000 0x1000>;
>> + ? ? ? ? ? ? interrupts = <99>;
>> + ? ? };
>> +
>> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
>> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
>> +as shown below.
>> +
>> + ?[property name] ?= <[phandle of the dma controller] [dma request id]>;
>
> At least fix the "-dma-channel" part of the name. It not clear if that's
> the case or just an example.
>
> [name]-dma-channel = <[phandle of the dma controller] [dma request id]>;

The name of the property that specifies the dma channel to use is
decided by the client device node. It is not enforced by the dma
device node. So, there will be no specific requirement stated in the
documentation for pl330 device node.

>
>
> The rest looks good.

Thanks for your review and comments.

Regards,
Thomas.

>
> Rob
>

[...]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-31 15:46                       ` Thomas Abraham
@ 2011-08-31 16:04                         ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-31 16:04 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches, vinod.koul,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Thomas,

On 08/31/2011 10:46 AM, Thomas Abraham wrote:
> Hi Rob,
> 
> On 31 August 2011 18:21, Rob Herring <robherring2@gmail.com> wrote:
>> Thomas,
> 
> [...]
> 
>>> For PL330 dma controllers instantiated from device tree, the channel
>>> lookup is based on phandle of the dma controller and dma request id
>>> specified by the client node. During probe, the private data of each
>>> channel of the controller is set to point to the device node of the
>>> dma controller. The 'chan_id' of the each channel is used as the
>>> dma request id.
>>>
>>> Client driver requesting dma channels specify the phandle of the
>>> dma controller and the request id. The pl330 filter function
>>> converts the phandle to the device node pointer and matches that
>>> with channel's private data. If a match is found, the request id
>>> from the client node and the 'chan_id' of the channel is matched.
>>> A channel is found if both the values match.
>>>
>>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>>> ---
>>>  .../devicetree/bindings/dma/arm-pl330.txt          |   29 ++++++++++++++++
>>>  drivers/dma/pl330.c                                |   35 +++++++++++++++++---
>>>  2 files changed, 59 insertions(+), 5 deletions(-)
>>>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>> b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>> new file mode 100644
>>> index 0000000..89f4b9c
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>> @@ -0,0 +1,29 @@
>>> +* ARM PrimeCell PL330 DMA Controller
>>> +
>>> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
>>> +between memory and peripherals or memory to memory.
>>> +
>>> +Required properties:
>>> +  - compatible: should be "arm,primecell".
>>
>> Sorry, I guess I wasn't clear. This has to be "arm,primecell" plus
>> something else. In this case, "arm,pl330". If the IP is modified from
>> standard ARM version (like ST likes to do), then something like
>> "samsung,pl330" would be appropriate.
>>
>> This is not actually used by the kernel at the moment, but could if
>> modified versions of pl330 show up.
> 
> of_platform_bus_create() checks for  "arm,primecell" compatible value
> to instantiate a amba device from device tree. The peripheral_id is
> also noted in the amba device instance. The amba drivers register with
> a with a peripheral_id and peripheral_id is used match amba device
> with a driver.
> 
> In cases of modified version of the same IP, the peripheral_id would
> be different. So, "arm,primecell" would just be enough for now. Any
> other compatible value would anyway go unused. I did use
> "arm,primecell-pdma" and "arm-primecell-mdma" to derive the dma_cap
> value. But, as per your comments, I dropped it.
> 
> So, for now, I will just list "arm,primecell" as required compatible
> value. Please let me know if "arm,pl330" would be required here.
> 
>>
>>> +  - reg: physical base address of the controller and length of memory mapped
>>> +    region.
>>> +  - interrupts: interrupt number to the cpu.
>>> +
>>> +Example: (from Samsung's Exynos4 processor dtsi file)
>>> +
>>> +     pdma0: pdma@12680000 {
>>> +             compatible = "arm,primecell";
>>> +             reg = <0x12680000 0x1000>;
>>> +             interrupts = <99>;
>>> +     };
>>> +
>>> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
>>> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
>>> +as shown below.
>>> +
>>> +  [property name]  = <[phandle of the dma controller] [dma request id]>;
>>
>> At least fix the "-dma-channel" part of the name. It not clear if that's
>> the case or just an example.
>>
>> [name]-dma-channel = <[phandle of the dma controller] [dma request id]>;
> 
> The name of the property that specifies the dma channel to use is
> decided by the client device node. It is not enforced by the dma
> device node. So, there will be no specific requirement stated in the
> documentation for pl330 device node.
> 

As it says in Documentation/devicetree/bindings/arm/primecell.txt, you
should have "arm,primecell" and a value for the specific peripheral. It
should be in order of most specific to least specific.

What Linux uses currently from the binding is a bit irrelevant. The
binding is supposed to be future proof. An OS could choose to not use
the primecell ID at all and only match with compatible string.

Rob

>>
>>
>> The rest looks good.
> 
> Thanks for your review and comments.
> 
> Regards,
> Thomas.
> 
>>
>> Rob
>>
> 
> [...]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-08-31 16:04                         ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2011-08-31 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

Thomas,

On 08/31/2011 10:46 AM, Thomas Abraham wrote:
> Hi Rob,
> 
> On 31 August 2011 18:21, Rob Herring <robherring2@gmail.com> wrote:
>> Thomas,
> 
> [...]
> 
>>> For PL330 dma controllers instantiated from device tree, the channel
>>> lookup is based on phandle of the dma controller and dma request id
>>> specified by the client node. During probe, the private data of each
>>> channel of the controller is set to point to the device node of the
>>> dma controller. The 'chan_id' of the each channel is used as the
>>> dma request id.
>>>
>>> Client driver requesting dma channels specify the phandle of the
>>> dma controller and the request id. The pl330 filter function
>>> converts the phandle to the device node pointer and matches that
>>> with channel's private data. If a match is found, the request id
>>> from the client node and the 'chan_id' of the channel is matched.
>>> A channel is found if both the values match.
>>>
>>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>>> ---
>>>  .../devicetree/bindings/dma/arm-pl330.txt          |   29 ++++++++++++++++
>>>  drivers/dma/pl330.c                                |   35 +++++++++++++++++---
>>>  2 files changed, 59 insertions(+), 5 deletions(-)
>>>  create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>> b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>> new file mode 100644
>>> index 0000000..89f4b9c
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>>> @@ -0,0 +1,29 @@
>>> +* ARM PrimeCell PL330 DMA Controller
>>> +
>>> +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
>>> +between memory and peripherals or memory to memory.
>>> +
>>> +Required properties:
>>> +  - compatible: should be "arm,primecell".
>>
>> Sorry, I guess I wasn't clear. This has to be "arm,primecell" plus
>> something else. In this case, "arm,pl330". If the IP is modified from
>> standard ARM version (like ST likes to do), then something like
>> "samsung,pl330" would be appropriate.
>>
>> This is not actually used by the kernel at the moment, but could if
>> modified versions of pl330 show up.
> 
> of_platform_bus_create() checks for  "arm,primecell" compatible value
> to instantiate a amba device from device tree. The peripheral_id is
> also noted in the amba device instance. The amba drivers register with
> a with a peripheral_id and peripheral_id is used match amba device
> with a driver.
> 
> In cases of modified version of the same IP, the peripheral_id would
> be different. So, "arm,primecell" would just be enough for now. Any
> other compatible value would anyway go unused. I did use
> "arm,primecell-pdma" and "arm-primecell-mdma" to derive the dma_cap
> value. But, as per your comments, I dropped it.
> 
> So, for now, I will just list "arm,primecell" as required compatible
> value. Please let me know if "arm,pl330" would be required here.
> 
>>
>>> +  - reg: physical base address of the controller and length of memory mapped
>>> +    region.
>>> +  - interrupts: interrupt number to the cpu.
>>> +
>>> +Example: (from Samsung's Exynos4 processor dtsi file)
>>> +
>>> +     pdma0: pdma at 12680000 {
>>> +             compatible = "arm,primecell";
>>> +             reg = <0x12680000 0x1000>;
>>> +             interrupts = <99>;
>>> +     };
>>> +
>>> +Client drivers (device nodes requiring dma transfers from dev-to-mem or
>>> +mem-to-dev) should specify the DMA channel numbers using a two-value pair
>>> +as shown below.
>>> +
>>> +  [property name]  = <[phandle of the dma controller] [dma request id]>;
>>
>> At least fix the "-dma-channel" part of the name. It not clear if that's
>> the case or just an example.
>>
>> [name]-dma-channel = <[phandle of the dma controller] [dma request id]>;
> 
> The name of the property that specifies the dma channel to use is
> decided by the client device node. It is not enforced by the dma
> device node. So, there will be no specific requirement stated in the
> documentation for pl330 device node.
> 

As it says in Documentation/devicetree/bindings/arm/primecell.txt, you
should have "arm,primecell" and a value for the specific peripheral. It
should be in order of most specific to least specific.

What Linux uses currently from the binding is a bit irrelevant. The
binding is supposed to be future proof. An OS could choose to not use
the primecell ID at all and only match with compatible string.

Rob

>>
>>
>> The rest looks good.
> 
> Thanks for your review and comments.
> 
> Regards,
> Thomas.
> 
>>
>> Rob
>>
> 
> [...]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 4/6] DMA: PL330: Add device tree support
  2011-08-31 16:04                         ` Rob Herring
@ 2011-09-01  9:03                           ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-09-01  9:03 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches, vinod.koul,
	jassisinghbrar, linux-samsung-soc, linux-arm-kernel

Hi Rob,

On 31 August 2011 21:34, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,

[...]

>
> As it says in Documentation/devicetree/bindings/arm/primecell.txt, you
> should have "arm,primecell" and a value for the specific peripheral. It
> should be in order of most specific to least specific.
>
> What Linux uses currently from the binding is a bit irrelevant. The
> binding is supposed to be future proof. An OS could choose to not use
> the primecell ID at all and only match with compatible string.

Thanks for pointing this out. "arm,pl330" has been added as another
mandatory compatible string for the pl330 device node.

Regards,
Thomas.

>
> Rob
>

[...]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-09-01  9:03                           ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-09-01  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

On 31 August 2011 21:34, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,

[...]

>
> As it says in Documentation/devicetree/bindings/arm/primecell.txt, you
> should have "arm,primecell" and a value for the specific peripheral. It
> should be in order of most specific to least specific.
>
> What Linux uses currently from the binding is a bit irrelevant. The
> binding is supposed to be future proof. An OS could choose to not use
> the primecell ID at all and only match with compatible string.

Thanks for pointing this out. "arm,pl330" has been added as another
mandatory compatible string for the pl330 device node.

Regards,
Thomas.

>
> Rob
>

[...]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH 0/6] Add device tree support for PL330 dma controller driver
  2011-08-29 17:29   ` Vinod Koul
@ 2011-09-05  5:17     ` Kukjin Kim
  -1 siblings, 0 replies; 47+ messages in thread
From: Kukjin Kim @ 2011-09-05  5:17 UTC (permalink / raw)
  To: 'Vinod Koul', 'Thomas Abraham'
  Cc: devicetree-discuss, boojin.kim, patches, jassisinghbrar,
	grant.likely, linux-samsung-soc, linux-arm-kernel

Vinod Koul wrote:
> 
> On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
> > This patchset adds device tree support for PL330 driver and uses it
> > to add device tree support for Samsung platforms, specifically Exynos4.
> The DMA patches looks good to me. Do you want this to go thru slave-dma
> tree or somewhere else.
> I will need acks on 3, 5 and 6th patch to carry them.
> 

Looks good to me on 3 and 5th patch, I think, 6th patch is needed to update, please refer to my comments on there.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>

As you know, Boojin Kim submitted 8th patch last Friday. So would be nice to me if you could rebase Thomas' patch based on her updated patch set and apply all series into your slave-dma.git samsung_dma branch I think it’s easy because v8 changes are small then I will merge it into my -next to prevent useless conflicts.

If any problems, please let me know.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/6] Add device tree support for PL330 dma controller driver
@ 2011-09-05  5:17     ` Kukjin Kim
  0 siblings, 0 replies; 47+ messages in thread
From: Kukjin Kim @ 2011-09-05  5:17 UTC (permalink / raw)
  To: linux-arm-kernel

Vinod Koul wrote:
> 
> On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
> > This patchset adds device tree support for PL330 driver and uses it
> > to add device tree support for Samsung platforms, specifically Exynos4.
> The DMA patches looks good to me. Do you want this to go thru slave-dma
> tree or somewhere else.
> I will need acks on 3, 5 and 6th patch to carry them.
> 

Looks good to me on 3 and 5th patch, I think, 6th patch is needed to update, please refer to my comments on there.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>

As you know, Boojin Kim submitted 8th patch last Friday. So would be nice to me if you could rebase Thomas' patch based on her updated patch set and apply all series into your slave-dma.git samsung_dma branch I think it?s easy because v8 changes are small then I will merge it into my -next to prevent useless conflicts.

If any problems, please let me know.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/6] Add device tree support for PL330 dma controller driver
  2011-09-05  5:17     ` Kukjin Kim
@ 2011-09-05 10:16       ` Thomas Abraham
  -1 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-09-05 10:16 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: Vinod Koul, devicetree-discuss, boojin.kim, patches,
	jassisinghbrar, grant.likely, linux-samsung-soc,
	linux-arm-kernel

Dear Mr. Kim,

On 5 September 2011 10:47, Kukjin Kim <kgene.kim@samsung.com> wrote:
> Vinod Koul wrote:
>>
>> On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
>> > This patchset adds device tree support for PL330 driver and uses it
>> > to add device tree support for Samsung platforms, specifically Exynos4.
>> The DMA patches looks good to me. Do you want this to go thru slave-dma
>> tree or somewhere else.
>> I will need acks on 3, 5 and 6th patch to carry them.
>>
>
> Looks good to me on 3 and 5th patch, I think, 6th patch is needed to update, please refer to my comments on there.
>
> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
>
> As you know, Boojin Kim submitted 8th patch last Friday. So would be nice to me if you could rebase Thomas' patch based on her updated patch set and apply all series into your slave-dma.git samsung_dma branch I think it’s easy because v8 changes are small then I will merge it into my -next to prevent useless conflicts.
>

I will test the pl330 device tree patches with Boonjin's pl330 driver
update patches and resubmit if there are any changes. Thank you for
your ack.

Thanks,
Thomas.

> If any problems, please let me know.
>
> Thanks.
>
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/6] Add device tree support for PL330 dma controller driver
@ 2011-09-05 10:16       ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-09-05 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Mr. Kim,

On 5 September 2011 10:47, Kukjin Kim <kgene.kim@samsung.com> wrote:
> Vinod Koul wrote:
>>
>> On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
>> > This patchset adds device tree support for PL330 driver and uses it
>> > to add device tree support for Samsung platforms, specifically Exynos4.
>> The DMA patches looks good to me. Do you want this to go thru slave-dma
>> tree or somewhere else.
>> I will need acks on 3, 5 and 6th patch to carry them.
>>
>
> Looks good to me on 3 and 5th patch, I think, 6th patch is needed to update, please refer to my comments on there.
>
> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
>
> As you know, Boojin Kim submitted 8th patch last Friday. So would be nice to me if you could rebase Thomas' patch based on her updated patch set and apply all series into your slave-dma.git samsung_dma branch I think it?s easy because v8 changes are small then I will merge it into my -next to prevent useless conflicts.
>

I will test the pl330 device tree patches with Boonjin's pl330 driver
update patches and resubmit if there are any changes. Thank you for
your ack.

Thanks,
Thomas.

> If any problems, please let me know.
>
> Thanks.
>
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/6] Add device tree support for PL330 dma controller driver
  2011-08-30 12:28     ` Thomas Abraham
@ 2011-09-05 13:14       ` Vinod Koul
  -1 siblings, 0 replies; 47+ messages in thread
From: Vinod Koul @ 2011-09-05 13:14 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: devicetree-discuss, boojin.kim, kgene.kim, patches,
	jassisinghbrar, grant.likely, linux-samsung-soc,
	linux-arm-kernel

On Tue, 2011-08-30 at 17:58 +0530, Thomas Abraham wrote:
> Hi Vinod,
> 
> On 29 August 2011 22:59, Vinod Koul <vinod.koul@linux.intel.com> wrote:
> > On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
> >> This patchset adds device tree support for PL330 driver and uses it
> >> to add device tree support for Samsung platforms, specifically Exynos4.
> > The DMA patches looks good to me. Do you want this to go thru slave-dma
> > tree or somewhere else.
> > I will need acks on 3, 5 and 6th patch to carry them.
> 
> There are couple of changes required in patch 4/6 of this series. I
> will do that and resubmit.
> 
> Since these patches are based on Boojin's pl330 driver update patches,
> it would be easier to take the same route which Boojin's patches will
> take. I will try to get acks' for the patches that you have listed.
> 
And I think these might need to be rebased based on Boojin's latest
version

-- 
~Vinod

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/6] Add device tree support for PL330 dma controller driver
@ 2011-09-05 13:14       ` Vinod Koul
  0 siblings, 0 replies; 47+ messages in thread
From: Vinod Koul @ 2011-09-05 13:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2011-08-30 at 17:58 +0530, Thomas Abraham wrote:
> Hi Vinod,
> 
> On 29 August 2011 22:59, Vinod Koul <vinod.koul@linux.intel.com> wrote:
> > On Fri, 2011-08-26 at 14:10 +0530, Thomas Abraham wrote:
> >> This patchset adds device tree support for PL330 driver and uses it
> >> to add device tree support for Samsung platforms, specifically Exynos4.
> > The DMA patches looks good to me. Do you want this to go thru slave-dma
> > tree or somewhere else.
> > I will need acks on 3, 5 and 6th patch to carry them.
> 
> There are couple of changes required in patch 4/6 of this series. I
> will do that and resubmit.
> 
> Since these patches are based on Boojin's pl330 driver update patches,
> it would be easier to take the same route which Boojin's patches will
> take. I will try to get acks' for the patches that you have listed.
> 
And I think these might need to be rebased based on Boojin's latest
version

-- 
~Vinod

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
  2011-09-19  6:28     ` [PATCH 3/6] ARM: EXYNOS4: Modify platform data for pl330 driver Thomas Abraham
@ 2011-09-19  6:29         ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-09-19  6:29 UTC (permalink / raw)
  To: devicetree-discuss, vinod.koul
  Cc: grant.likely, linux-arm-kernel, linux-samsung-soc, kgene.kim,
	robherring2, patches, jassisinghbrar, boojin.kim

For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.

Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 .../devicetree/bindings/dma/arm-pl330.txt          |   30 ++++++++++++++++++
 drivers/dma/pl330.c                                |   33 +++++++++++++++++--
 2 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..a4cd273
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,30 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+  - compatible: should include both "arm,pl330" and "arm,primecell".
+  - reg: physical base address of the controller and length of memory mapped
+    region.
+  - interrupts: interrupt number to the cpu.
+
+Example:
+
+	pdma0: pdma@12680000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0x12680000 0x1000>;
+		interrupts = <99>;
+	};
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+  [property name]  = <[phandle of the dma controller] [dma request id]>;
+
+      where 'dma request id' is the dma request number which is connected
+      to the client controller. The 'property name' is recommended to be
+      of the form <name>-dma-channel.
+
+  Example:  tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 992bf82..7a4ebf1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
 #include <linux/amba/pl330.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
+#include <linux/of.h>
 
 #define NR_DEFAULT_DESC	16
 
@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
+#ifdef CONFIG_OF
+	if (chan->device->dev->of_node) {
+		const __be32 *prop_value;
+		phandle phandle;
+		struct device_node *node;
+
+		prop_value = ((struct property *)param)->value;
+		phandle = be32_to_cpup(prop_value++);
+		node = of_find_node_by_phandle(phandle);
+		return ((chan->private == node) &&
+				(chan->chan_id == be32_to_cpup(prop_value)));
+	}
+#endif
+
 	peri_id = chan->private;
 	return *peri_id == (unsigned)param;
 }
@@ -855,12 +870,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	INIT_LIST_HEAD(&pd->channels);
 
 	/* Initialize channel parameters */
-	num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
+	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
+			(u8)pi->pcfg.num_chan);
 	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		if (!adev->dev.of_node)
+			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		else
+			pch->chan.private = adev->dev.of_node;
+
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -874,10 +894,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 
 	pd->dev = &adev->dev;
-	if (pdat)
+	if (pdat) {
 		pd->cap_mask = pdat->cap_mask;
-	else
+	} else {
 		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
+		if (pi->pcfg.num_peri) {
+			dma_cap_set(DMA_SLAVE, pd->cap_mask);
+			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+		}
+	}
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 4/6] DMA: PL330: Add device tree support
@ 2011-09-19  6:29         ` Thomas Abraham
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Abraham @ 2011-09-19  6:29 UTC (permalink / raw)
  To: linux-arm-kernel

For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.

Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 .../devicetree/bindings/dma/arm-pl330.txt          |   30 ++++++++++++++++++
 drivers/dma/pl330.c                                |   33 +++++++++++++++++--
 2 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..a4cd273
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,30 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+  - compatible: should include both "arm,pl330" and "arm,primecell".
+  - reg: physical base address of the controller and length of memory mapped
+    region.
+  - interrupts: interrupt number to the cpu.
+
+Example:
+
+	pdma0: pdma at 12680000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0x12680000 0x1000>;
+		interrupts = <99>;
+	};
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+  [property name]  = <[phandle of the dma controller] [dma request id]>;
+
+      where 'dma request id' is the dma request number which is connected
+      to the client controller. The 'property name' is recommended to be
+      of the form <name>-dma-channel.
+
+  Example:  tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 992bf82..7a4ebf1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
 #include <linux/amba/pl330.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
+#include <linux/of.h>
 
 #define NR_DEFAULT_DESC	16
 
@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
+#ifdef CONFIG_OF
+	if (chan->device->dev->of_node) {
+		const __be32 *prop_value;
+		phandle phandle;
+		struct device_node *node;
+
+		prop_value = ((struct property *)param)->value;
+		phandle = be32_to_cpup(prop_value++);
+		node = of_find_node_by_phandle(phandle);
+		return ((chan->private == node) &&
+				(chan->chan_id == be32_to_cpup(prop_value)));
+	}
+#endif
+
 	peri_id = chan->private;
 	return *peri_id == (unsigned)param;
 }
@@ -855,12 +870,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	INIT_LIST_HEAD(&pd->channels);
 
 	/* Initialize channel parameters */
-	num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
+	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
+			(u8)pi->pcfg.num_chan);
 	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		if (!adev->dev.of_node)
+			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		else
+			pch->chan.private = adev->dev.of_node;
+
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -874,10 +894,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 
 	pd->dev = &adev->dev;
-	if (pdat)
+	if (pdat) {
 		pd->cap_mask = pdat->cap_mask;
-	else
+	} else {
 		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
+		if (pi->pcfg.num_peri) {
+			dma_cap_set(DMA_SLAVE, pd->cap_mask);
+			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+		}
+	}
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
-- 
1.6.6.rc2

^ permalink raw reply related	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2011-09-19  6:29 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-26  8:40 [PATCH 0/6] Add device tree support for PL330 dma controller driver Thomas Abraham
2011-08-26  8:40 ` Thomas Abraham
2011-08-26  8:40 ` [PATCH 1/6] DMA: PL330: move filter function into driver Thomas Abraham
2011-08-26  8:40   ` Thomas Abraham
2011-08-26  8:40   ` [PATCH 2/6] DMA: PL330: Infer transfer direction from transfer request instead of platform data Thomas Abraham
2011-08-26  8:40     ` Thomas Abraham
2011-08-26  8:40     ` [PATCH 3/6] ARM: EXYNOS4: Modify platform data for pl330 driver Thomas Abraham
2011-08-26  8:40       ` Thomas Abraham
2011-08-26  8:40       ` [PATCH 4/6] DMA: PL330: Add device tree support Thomas Abraham
2011-08-26  8:40         ` Thomas Abraham
2011-08-26  8:40         ` [PATCH 5/6] ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers Thomas Abraham
2011-08-26  8:40           ` Thomas Abraham
2011-08-26  8:40           ` [PATCH 6/6] ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build Thomas Abraham
2011-08-26  8:40             ` Thomas Abraham
2011-08-26 13:16         ` [PATCH 4/6] DMA: PL330: Add device tree support Rob Herring
2011-08-26 13:16           ` Rob Herring
2011-08-26 14:23           ` Russell King - ARM Linux
2011-08-26 14:23             ` Russell King - ARM Linux
2011-08-30 12:21             ` Thomas Abraham
2011-08-30 12:21               ` Thomas Abraham
     [not found]           ` <4E579C9B.7030807-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2011-08-30 12:18             ` Thomas Abraham
2011-08-30 13:19               ` Rob Herring
2011-08-30 13:19                 ` Rob Herring
2011-08-31  6:46                 ` Thomas Abraham
2011-08-31  6:46                   ` Thomas Abraham
2011-08-31 12:51                   ` Rob Herring
2011-08-31 12:51                     ` Rob Herring
2011-08-31 15:46                     ` Thomas Abraham
2011-08-31 15:46                       ` Thomas Abraham
2011-08-31 16:04                       ` Rob Herring
2011-08-31 16:04                         ` Rob Herring
2011-09-01  9:03                         ` Thomas Abraham
2011-09-01  9:03                           ` Thomas Abraham
2011-08-30 13:09           ` Thomas Abraham
2011-08-30 13:09             ` Thomas Abraham
2011-08-29 17:29 ` [PATCH 0/6] Add device tree support for PL330 dma controller driver Vinod Koul
2011-08-29 17:29   ` Vinod Koul
2011-08-30 12:28   ` Thomas Abraham
2011-08-30 12:28     ` Thomas Abraham
2011-09-05 13:14     ` Vinod Koul
2011-09-05 13:14       ` Vinod Koul
2011-09-05  5:17   ` Kukjin Kim
2011-09-05  5:17     ` Kukjin Kim
2011-09-05 10:16     ` Thomas Abraham
2011-09-05 10:16       ` Thomas Abraham
2011-09-19  6:28 [PATCH v4 " Thomas Abraham
2011-09-19  6:28 ` [PATCH 1/6] DMA: PL330: move filter function into driver Thomas Abraham
2011-09-19  6:28   ` [PATCH 2/6] DMA: PL330: Infer transfer direction from transfer request instead of platform data Thomas Abraham
2011-09-19  6:28     ` [PATCH 3/6] ARM: EXYNOS4: Modify platform data for pl330 driver Thomas Abraham
2011-09-19  6:29       ` [PATCH 4/6] DMA: PL330: Add device tree support Thomas Abraham
2011-09-19  6:29         ` Thomas Abraham

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.