linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support
@ 2014-04-15 15:13 Laurent Pinchart
  2014-04-15 15:13 ` [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure Laurent Pinchart
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Laurent Pinchart @ 2014-04-15 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch set adds support for fly-by transfers and external DMA requests to
the mmp_pdma driver. It's broken out as

- extending the dma_slave_config structure with a fly-by flag (1/6)
- miscellaneous small fixes and cleanups (2/6 to 4/6)
- fly-by transfer support (5/6)
- external DMA requests support (6/6)

I haven't been able to test the DT-related changes as my only PXA platform is
a PXA270 that doesn't boot through DT yet.

Laurent Pinchart (6):
  dmaengine: Add fly-by transfer flag to slave configuration structure
  dma: mmp_pdma: Fix the #dma-channels DT property documentation
  dma: mmp_pdma: Simplify access to channel drcmr value
  dma: mmp_pdma: Fix physical channel memory allocation size
  dma: mmp_pdma: Add support for fly-by transfers
  dma: mmp_pdma: Add support externel DMA requests

 Documentation/devicetree/bindings/dma/mmp-dma.txt |  13 ++-
 drivers/dma/mmp_pdma.c                            | 110 ++++++++++++++++++----
 include/linux/dmaengine.h                         |  13 +++
 include/linux/platform_data/mmp_dma.h             |   2 +
 4 files changed, 116 insertions(+), 22 deletions(-)

-- 
Regards,

Laurent Pinchart

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

* [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure
  2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
@ 2014-04-15 15:13 ` Laurent Pinchart
  2014-05-02 15:46   ` Vinod Koul
  2014-05-05 17:26   ` Lars-Peter Clausen
  2014-04-15 15:13 ` [PATCH 2/6] dma: mmp_pdma: Fix the #dma-channels DT property documentation Laurent Pinchart
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Laurent Pinchart @ 2014-04-15 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

Fly-by transfer mode cuts down the number of bus transactions by letting
the slave drive or latch the memory data bus during memory transactions
instead of performing a dedicated transaction to read data from or write
data to the slave.

Support for fly-by mode by adding a new flag field to struct
dma_slave_config.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/linux/dmaengine.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c5c92d5..ae99153 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -304,6 +304,17 @@ enum dma_slave_buswidth {
 };
 
 /**
+ * enum dma_slave_flags - DMA slave configuration flags
+ * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
+ *   Instead of performing a bus transaction to read (write) data from (to) the
+ *   slave, let the slave drive (latch) the memory bus data signals during the
+ *   memory write (read) transaction.
+ */
+enum dma_slave_flags {
+	DMA_SLAVE_FLAG_FLY_BY = (1 << 0),
+};
+
+/**
  * struct dma_slave_config - dma slave channel runtime config
  * @direction: whether the data shall go in or out on this slave
  * channel, right now. DMA_MEM_TO_DEV and DMA_DEV_TO_MEM are
@@ -333,6 +344,7 @@ enum dma_slave_buswidth {
  * @slave_id: Slave requester id. Only valid for slave channels. The dma
  * slave peripheral will have unique id as dma requester which need to be
  * pass as slave config.
+ * @flags: DMA slave flags, a combination of enum dma_slave_flags flags.
  *
  * This struct is passed in as configuration data to a DMA engine
  * in order to set up a certain channel for DMA transport@runtime.
@@ -361,6 +373,7 @@ struct dma_slave_config {
 	u32 dst_maxburst;
 	bool device_fc;
 	unsigned int slave_id;
+	u32 flags;
 };
 
 /**
-- 
1.8.3.2

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

* [PATCH 2/6] dma: mmp_pdma: Fix the #dma-channels DT property documentation
  2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
  2014-04-15 15:13 ` [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure Laurent Pinchart
@ 2014-04-15 15:13 ` Laurent Pinchart
  2014-05-02 15:50   ` Vinod Koul
  2014-04-15 15:13 ` [PATCH 3/6] dma: mmp_pdma: Simplify access to channel drcmr value Laurent Pinchart
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Laurent Pinchart @ 2014-04-15 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

The property is optional and defaults to 32. Document it as such.

Cc: devicetree at vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 Documentation/devicetree/bindings/dma/mmp-dma.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/mmp-dma.txt b/Documentation/devicetree/bindings/dma/mmp-dma.txt
index a4fa4ef..7a802f6 100644
--- a/Documentation/devicetree/bindings/dma/mmp-dma.txt
+++ b/Documentation/devicetree/bindings/dma/mmp-dma.txt
@@ -1,17 +1,20 @@
 * MARVELL MMP DMA controller
 
 Marvell Peripheral DMA Controller
-Used platfroms: pxa688, pxa910, pxa3xx, etc
+Used platforms: pxa688, pxa910, pxa3xx, etc
 
 Required properties:
 - compatible: Should be "marvell,pdma-1.0"
 - reg: Should contain DMA registers location and length.
 - interrupts: Either contain all of the per-channel DMA interrupts
 		or one irq for pdma device
-- #dma-channels: Number of DMA channels supported by the controller.
+
+Optional properties:
+- #dma-channels: Number of DMA channels supported by the controller (defaults
+  to 32 when not specified)
 
 "marvell,pdma-1.0"
-Used platfroms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
+Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
 
 Examples:
 
@@ -45,7 +48,7 @@ pdma: dma-controller at d4000000 {
 
 
 Marvell Two Channel DMA Controller used specifically for audio
-Used platfroms: pxa688, pxa910
+Used platforms: pxa688, pxa910
 
 Required properties:
 - compatible: Should be "marvell,adma-1.0" or "marvell,pxa910-squ"
-- 
1.8.3.2

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

* [PATCH 3/6] dma: mmp_pdma: Simplify access to channel drcmr value
  2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
  2014-04-15 15:13 ` [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure Laurent Pinchart
  2014-04-15 15:13 ` [PATCH 2/6] dma: mmp_pdma: Fix the #dma-channels DT property documentation Laurent Pinchart
@ 2014-04-15 15:13 ` Laurent Pinchart
  2014-05-02 15:51   ` Vinod Koul
  2014-04-15 15:13 ` [PATCH 4/6] dma: mmp_pdma: Fix physical channel memory allocation size Laurent Pinchart
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Laurent Pinchart @ 2014-04-15 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

As the physical channel and virtual channel point to each other,
pchan->phy->vchan is always equal to pchan. Simplify the code
accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/dma/mmp_pdma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index b439679..643f225 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -277,7 +277,7 @@ static void mmp_pdma_free_phy(struct mmp_pdma_chan *pchan)
 		return;
 
 	/* clear the channel mapping in DRCMR */
-	reg = DRCMR(pchan->phy->vchan->drcmr);
+	reg = DRCMR(pchan->drcmr);
 	writel(0, pchan->phy->base + reg);
 
 	spin_lock_irqsave(&pdev->phy_lock, flags);
-- 
1.8.3.2

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

* [PATCH 4/6] dma: mmp_pdma: Fix physical channel memory allocation size
  2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
                   ` (2 preceding siblings ...)
  2014-04-15 15:13 ` [PATCH 3/6] dma: mmp_pdma: Simplify access to channel drcmr value Laurent Pinchart
@ 2014-04-15 15:13 ` Laurent Pinchart
  2014-05-02 15:52   ` Vinod Koul
  2014-04-15 15:13 ` [PATCH 5/6] dma: mmp_pdma: Add support for fly-by transfers Laurent Pinchart
  2014-04-15 15:13 ` [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests Laurent Pinchart
  5 siblings, 1 reply; 14+ messages in thread
From: Laurent Pinchart @ 2014-04-15 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

Use sizeof(*var) instead of sizeof(type) when calling devm_k*alloc().
This avoids using the wrong type as was done to allocate the physical
channels array.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/dma/mmp_pdma.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 643f225..7ed7850 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -858,8 +858,7 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
 	struct mmp_pdma_chan *chan;
 	int ret;
 
-	chan = devm_kzalloc(pdev->dev, sizeof(struct mmp_pdma_chan),
-			    GFP_KERNEL);
+	chan = devm_kzalloc(pdev->dev, sizeof(*chan), GFP_KERNEL);
 	if (chan == NULL)
 		return -ENOMEM;
 
@@ -946,8 +945,7 @@ static int mmp_pdma_probe(struct platform_device *op)
 			irq_num++;
 	}
 
-	pdev->phy = devm_kcalloc(pdev->dev,
-				 dma_channels, sizeof(struct mmp_pdma_chan),
+	pdev->phy = devm_kcalloc(pdev->dev, dma_channels, sizeof(*pdev->phy),
 				 GFP_KERNEL);
 	if (pdev->phy == NULL)
 		return -ENOMEM;
-- 
1.8.3.2

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

* [PATCH 5/6] dma: mmp_pdma: Add support for fly-by transfers
  2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
                   ` (3 preceding siblings ...)
  2014-04-15 15:13 ` [PATCH 4/6] dma: mmp_pdma: Fix physical channel memory allocation size Laurent Pinchart
@ 2014-04-15 15:13 ` Laurent Pinchart
  2014-04-15 15:13 ` [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests Laurent Pinchart
  5 siblings, 0 replies; 14+ messages in thread
From: Laurent Pinchart @ 2014-04-15 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

Enable fly-by mode when the DMA_SLAVE_FLAG_FLY_BY flag is set in the
slave configuration.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/dma/mmp_pdma.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 7ed7850..849bf75 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -63,6 +63,8 @@
 #define DCMD_FLOWTRG	BIT(28)	/* Flow Control by the target. */
 #define DCMD_STARTIRQEN	BIT(22)	/* Start Interrupt Enable */
 #define DCMD_ENDIRQEN	BIT(21)	/* End Interrupt Enable */
+#define DCMD_FLYBYS	BIT(20)	/* Fly-By Source */
+#define DCMD_FLYBYT	BIT(19)	/* Fly-By Target */
 #define DCMD_ENDIAN	BIT(18)	/* Device Endian-ness. */
 #define DCMD_BURST8	(1 << 16)	/* 8 byte burst */
 #define DCMD_BURST16	(2 << 16)	/* 16 byte burst */
@@ -708,11 +710,15 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 	case DMA_SLAVE_CONFIG:
 		if (cfg->direction == DMA_DEV_TO_MEM) {
 			chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC;
+			if (cfg->flags & DMA_SLAVE_FLAG_FLY_BY)
+				chan->dcmd |= DCMD_FLYBYT;
 			maxburst = cfg->src_maxburst;
 			width = cfg->src_addr_width;
 			addr = cfg->src_addr;
 		} else if (cfg->direction == DMA_MEM_TO_DEV) {
 			chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
+			if (cfg->flags & DMA_SLAVE_FLAG_FLY_BY)
+				chan->dcmd |= DCMD_FLYBYS;
 			maxburst = cfg->dst_maxburst;
 			width = cfg->dst_addr_width;
 			addr = cfg->dst_addr;
-- 
1.8.3.2

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

* [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests
  2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
                   ` (4 preceding siblings ...)
  2014-04-15 15:13 ` [PATCH 5/6] dma: mmp_pdma: Add support for fly-by transfers Laurent Pinchart
@ 2014-04-15 15:13 ` Laurent Pinchart
  2014-05-02 16:09   ` Vinod Koul
  5 siblings, 1 reply; 14+ messages in thread
From: Laurent Pinchart @ 2014-04-15 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

The MMP/PXA DMA engine supports transfer initiation by external chips
through DMA request (DREQ) signals. Support them by clearing pending DMA
requests for the associated source when starting a channel.

The request ID to DREQ index mapping depends on the hardware and is
passed through platform data or DT.

Cc: devicetree at vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 Documentation/devicetree/bindings/dma/mmp-dma.txt |  2 +
 drivers/dma/mmp_pdma.c                            | 96 ++++++++++++++++++++---
 include/linux/platform_data/mmp_dma.h             |  2 +
 3 files changed, 87 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/mmp-dma.txt b/Documentation/devicetree/bindings/dma/mmp-dma.txt
index 7a802f6..edb9ff3 100644
--- a/Documentation/devicetree/bindings/dma/mmp-dma.txt
+++ b/Documentation/devicetree/bindings/dma/mmp-dma.txt
@@ -12,6 +12,8 @@ Required properties:
 Optional properties:
 - #dma-channels: Number of DMA channels supported by the controller (defaults
   to 32 when not specified)
+- marvell,dreq: Array of the DMA request IDs corresponding to each of the
+  external device request (DREQ) lines
 
 "marvell,pdma-1.0"
 Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 849bf75..4546a1c 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -27,6 +27,7 @@
 
 #define DCSR		0x0000
 #define DALGN		0x00a0
+#define DRQSR(n)	(0x00e0 + ((n) << 2))
 #define DINT		0x00f0
 #define DDADR		0x0200
 #define DSADR		0x0204
@@ -50,6 +51,9 @@
 #define DCSR_CMPST	BIT(10)	/* The Descriptor Compare Status */
 #define DCSR_EORINTR	BIT(9)	/* The end of Receive */
 
+#define DRQSR_CLR	BIT(8)	/* Clear Pending Requests */
+#define DRQSR_REQPEND	0x1f	/* Requests Pending */
+
 #define DRCMR(n)	((((n) < 64) ? 0x0100 : 0x1100) + (((n) & 0x3f) << 2))
 #define DRCMR_MAPVLD	BIT(7)	/* Map Valid (read / write) */
 #define DRCMR_CHLNUM	0x1f	/* mask for Channel Number (read / write) */
@@ -108,6 +112,7 @@ struct mmp_pdma_chan {
 	u32 dcmd;
 	u32 drcmr;
 	u32 dev_addr;
+	int drq;
 
 	/* list for desc */
 	spinlock_t desc_lock;		/* Descriptor list lock */
@@ -127,6 +132,8 @@ struct mmp_pdma_phy {
 
 struct mmp_pdma_device {
 	int				dma_channels;
+	unsigned int			num_dreq;
+	const u32			*dreq;
 	void __iomem			*base;
 	struct device			*dev;
 	struct dma_device		device;
@@ -167,6 +174,9 @@ static void enable_chan(struct mmp_pdma_phy *phy)
 		dalgn &= ~(1 << phy->idx);
 	writel(dalgn, phy->base + DALGN);
 
+	if (phy->vchan->drq != -1)
+		writel(DRQSR_CLR, phy->base + DRQSR(phy->vchan->drq));
+
 	reg = (phy->idx << 2) + DCSR;
 	writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
 }
@@ -685,6 +695,22 @@ fail:
 	return NULL;
 }
 
+static void mmp_pdma_set_drcmr(struct mmp_pdma_chan *chan, unsigned int drmcr)
+{
+	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(cchan->chan.device);
+	unsigned int i;
+
+	chan->drcmr = drmcr;
+	chan->drq = -1;
+
+	for (i = 0; i < pdev->num_dreq; ++i) {
+		if (pdev->dreq[i] == drmcr) {
+			chan->drq = i;
+			break;
+		}
+	}
+}
+
 static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 			    unsigned long arg)
 {
@@ -745,7 +771,7 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 		 * be removed.
 		 */
 		if (cfg->slave_id)
-			chan->drcmr = cfg->slave_id;
+			mmp_pdma_set_drcmr(chan, cfg->slave_id);
 		break;
 	default:
 		return -ENOSYS;
@@ -909,16 +935,64 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec,
 	if (!chan)
 		return NULL;
 
-	to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
+	mmp_pdma_set_drcmr(to_mmp_pdma_chan(chan), dma_spec->args[0]);
 
 	return chan;
 }
 
+static int mmap_pdma_parse_platform_data(struct mmp_pdma_device *pdev)
+{
+	struct device_node *np = pdev->dev->of_node;
+	struct property *prop;
+
+	/* Default values: 32 channels, no external DREQ. */
+	pdev->dma_channels = 32;
+	pdev->num_dreq = 0;
+
+	if (!IS_ENABLED(CONFIG_OF) || !np) {
+		struct mmp_dma_platdata *pdata = dev_get_platdata(pdev->dev);
+
+		if (!pdata)
+			return 0;
+
+		if (pdata->dma_channels)
+			pdev->dma_channels = pdata->dma_channels;
+		if (pdata->num_dreq) {
+			pdev->num_dreq = pdata->num_dreq;
+			pdev->dreq = pdata->dreq;
+		}
+
+		return 0;
+	}
+
+	of_property_read_u32(np, "#dma-channels", &pdev->dma_channels);
+
+	prop = of_find_property(np, "marvell,dreq");
+	if (prop) {
+		unsigned int num_dreq = prop->length / sizeof(unsigned long);
+		u32 *dreq;
+
+		dreq = devm_kcalloc(pdev->dev, num_dreq, sizeof(*pdreq),
+				    GFP_KERNEL);
+		if (dreq == NULL)
+			return -ENOMEM;
+
+		ret = of_property_read_u32_array(np, "marvell,dreq", dreq,
+						 num_dreq);
+		if (ret < 0)
+			return ret;
+
+		pdev->num_dreq = num_dreq;
+		pdev->dreq = dreq;
+	}
+
+	return 0;
+}
+
 static int mmp_pdma_probe(struct platform_device *op)
 {
 	struct mmp_pdma_device *pdev;
 	const struct of_device_id *of_id;
-	struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
 	struct resource *iores;
 	int i, ret, irq = 0;
 	int dma_channels = 0, irq_num = 0;
@@ -936,15 +1010,11 @@ static int mmp_pdma_probe(struct platform_device *op)
 	if (IS_ERR(pdev->base))
 		return PTR_ERR(pdev->base);
 
-	of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
-	if (of_id)
-		of_property_read_u32(pdev->dev->of_node, "#dma-channels",
-				     &dma_channels);
-	else if (pdata && pdata->dma_channels)
-		dma_channels = pdata->dma_channels;
-	else
-		dma_channels = 32;	/* default 32 channel */
-	pdev->dma_channels = dma_channels;
+	ret = mmp_pdma_parse_platform_data(pdev);
+	if (ret < 0)
+		return ret;
+
+	dma_channels = pdev->dma_channels;
 
 	for (i = 0; i < dma_channels; i++) {
 		if (platform_get_irq(op, i) > 0)
@@ -1038,7 +1108,7 @@ bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &mmp_pdma_driver.driver)
 		return false;
 
-	c->drcmr = *(unsigned int *)param;
+	mmp_pdma_set_drcmr(c, *(unsigned int *)param);
 
 	return true;
 }
diff --git a/include/linux/platform_data/mmp_dma.h b/include/linux/platform_data/mmp_dma.h
index 2a330ec..32595b8 100644
--- a/include/linux/platform_data/mmp_dma.h
+++ b/include/linux/platform_data/mmp_dma.h
@@ -14,6 +14,8 @@
 
 struct mmp_dma_platdata {
 	int dma_channels;
+	unsigned int num_dreq;
+	const u32 *dreq;
 };
 
 #endif /* MMP_DMA_H */
-- 
1.8.3.2

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

* [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure
  2014-04-15 15:13 ` [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure Laurent Pinchart
@ 2014-05-02 15:46   ` Vinod Koul
  2014-05-02 15:47     ` Vinod Koul
  2014-05-05 17:26   ` Lars-Peter Clausen
  1 sibling, 1 reply; 14+ messages in thread
From: Vinod Koul @ 2014-05-02 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 15, 2014 at 05:13:32PM +0200, Laurent Pinchart wrote:
> Fly-by transfer mode cuts down the number of bus transactions by letting
> the slave drive or latch the memory data bus during memory transactions
??            ^^^^^^^^^^^
> instead of performing a dedicated transaction to read data from or write
/								^^^^
> data to the slave.
> 
> Support for fly-by mode by adding a new flag field to struct
> dma_slave_config.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  include/linux/dmaengine.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index c5c92d5..ae99153 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -304,6 +304,17 @@ enum dma_slave_buswidth {
>  };
>  
>  /**
> + * enum dma_slave_flags - DMA slave configuration flags
> + * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
> + *   Instead of performing a bus transaction to read (write) data from (to) the
> + *   slave, let the slave drive (latch) the memory bus data signals during the
> + *   memory write (read) transaction.
> + */
> +enum dma_slave_flags {
> +	DMA_SLAVE_FLAG_FLY_BY = (1 << 0),
> +};
> +
> +/**
>   * struct dma_slave_config - dma slave channel runtime config
>   * @direction: whether the data shall go in or out on this slave
>   * channel, right now. DMA_MEM_TO_DEV and DMA_DEV_TO_MEM are
> @@ -333,6 +344,7 @@ enum dma_slave_buswidth {
>   * @slave_id: Slave requester id. Only valid for slave channels. The dma
>   * slave peripheral will have unique id as dma requester which need to be
>   * pass as slave config.
> + * @flags: DMA slave flags, a combination of enum dma_slave_flags flags.
>   *
>   * This struct is passed in as configuration data to a DMA engine
>   * in order to set up a certain channel for DMA transport at runtime.
> @@ -361,6 +373,7 @@ struct dma_slave_config {
>  	u32 dst_maxburst;
>  	bool device_fc;
>  	unsigned int slave_id;
> +	u32 flags;
>  };
I am not sure about this. Should we have a generic flag for this or just add a
bool for fly_by mode?

Suggestions?

-- 
~Vinod

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

* [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure
  2014-05-02 15:46   ` Vinod Koul
@ 2014-05-02 15:47     ` Vinod Koul
  0 siblings, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2014-05-02 15:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 02, 2014 at 09:16:34PM +0530, Vinod Koul wrote:
+ Dan

Pls cc Dan as well

~Vinod

> On Tue, Apr 15, 2014 at 05:13:32PM +0200, Laurent Pinchart wrote:
> > Fly-by transfer mode cuts down the number of bus transactions by letting
> > the slave drive or latch the memory data bus during memory transactions
> ??            ^^^^^^^^^^^
> > instead of performing a dedicated transaction to read data from or write
> /								^^^^
> > data to the slave.
> > 
> > Support for fly-by mode by adding a new flag field to struct
> > dma_slave_config.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> >  include/linux/dmaengine.h | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> > index c5c92d5..ae99153 100644
> > --- a/include/linux/dmaengine.h
> > +++ b/include/linux/dmaengine.h
> > @@ -304,6 +304,17 @@ enum dma_slave_buswidth {
> >  };
> >  
> >  /**
> > + * enum dma_slave_flags - DMA slave configuration flags
> > + * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
> > + *   Instead of performing a bus transaction to read (write) data from (to) the
> > + *   slave, let the slave drive (latch) the memory bus data signals during the
> > + *   memory write (read) transaction.
> > + */
> > +enum dma_slave_flags {
> > +	DMA_SLAVE_FLAG_FLY_BY = (1 << 0),
> > +};
> > +
> > +/**
> >   * struct dma_slave_config - dma slave channel runtime config
> >   * @direction: whether the data shall go in or out on this slave
> >   * channel, right now. DMA_MEM_TO_DEV and DMA_DEV_TO_MEM are
> > @@ -333,6 +344,7 @@ enum dma_slave_buswidth {
> >   * @slave_id: Slave requester id. Only valid for slave channels. The dma
> >   * slave peripheral will have unique id as dma requester which need to be
> >   * pass as slave config.
> > + * @flags: DMA slave flags, a combination of enum dma_slave_flags flags.
> >   *
> >   * This struct is passed in as configuration data to a DMA engine
> >   * in order to set up a certain channel for DMA transport at runtime.
> > @@ -361,6 +373,7 @@ struct dma_slave_config {
> >  	u32 dst_maxburst;
> >  	bool device_fc;
> >  	unsigned int slave_id;
> > +	u32 flags;
> >  };
> I am not sure about this. Should we have a generic flag for this or just add a
> bool for fly_by mode?
> 
> Suggestions?
> 
> -- 
> ~Vinod
> 

-- 

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

* [PATCH 2/6] dma: mmp_pdma: Fix the #dma-channels DT property documentation
  2014-04-15 15:13 ` [PATCH 2/6] dma: mmp_pdma: Fix the #dma-channels DT property documentation Laurent Pinchart
@ 2014-05-02 15:50   ` Vinod Koul
  0 siblings, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2014-05-02 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 15, 2014 at 05:13:33PM +0200, Laurent Pinchart wrote:
> The property is optional and defaults to 32. Document it as such.

Applied, thanks

-- 
~Vinod

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

* [PATCH 3/6] dma: mmp_pdma: Simplify access to channel drcmr value
  2014-04-15 15:13 ` [PATCH 3/6] dma: mmp_pdma: Simplify access to channel drcmr value Laurent Pinchart
@ 2014-05-02 15:51   ` Vinod Koul
  0 siblings, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2014-05-02 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 15, 2014 at 05:13:34PM +0200, Laurent Pinchart wrote:
> As the physical channel and virtual channel point to each other,
> pchan->phy->vchan is always equal to pchan. Simplify the code
> accordingly.
> 
Applied, thanks

-- 
~Vinod

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

* [PATCH 4/6] dma: mmp_pdma: Fix physical channel memory allocation size
  2014-04-15 15:13 ` [PATCH 4/6] dma: mmp_pdma: Fix physical channel memory allocation size Laurent Pinchart
@ 2014-05-02 15:52   ` Vinod Koul
  0 siblings, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2014-05-02 15:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 15, 2014 at 05:13:35PM +0200, Laurent Pinchart wrote:
> Use sizeof(*var) instead of sizeof(type) when calling devm_k*alloc().
> This avoids using the wrong type as was done to allocate the physical
> channels array.
>

Applied, thanks

-- 
~Vinod

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

* [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests
  2014-04-15 15:13 ` [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests Laurent Pinchart
@ 2014-05-02 16:09   ` Vinod Koul
  0 siblings, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2014-05-02 16:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 15, 2014 at 05:13:37PM +0200, Laurent Pinchart wrote:
> The MMP/PXA DMA engine supports transfer initiation by external chips
> through DMA request (DREQ) signals. Support them by clearing pending DMA
> requests for the associated source when starting a channel.
> 
> The request ID to DREQ index mapping depends on the hardware and is
> passed through platform data or DT.
> 
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  Documentation/devicetree/bindings/dma/mmp-dma.txt |  2 +
>  drivers/dma/mmp_pdma.c                            | 96 ++++++++++++++++++++---
>  include/linux/platform_data/mmp_dma.h             |  2 +
>  3 files changed, 87 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/dma/mmp-dma.txt b/Documentation/devicetree/bindings/dma/mmp-dma.txt
> index 7a802f6..edb9ff3 100644
> --- a/Documentation/devicetree/bindings/dma/mmp-dma.txt
> +++ b/Documentation/devicetree/bindings/dma/mmp-dma.txt
> @@ -12,6 +12,8 @@ Required properties:
>  Optional properties:
>  - #dma-channels: Number of DMA channels supported by the controller (defaults
>    to 32 when not specified)
> +- marvell,dreq: Array of the DMA request IDs corresponding to each of the
> +  external device request (DREQ) lines
>  
>  "marvell,pdma-1.0"
>  Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
Can you please split the binding to separate patch and we need to get an ACK on
it from DT folks.

The below looks fine to me

-- 
~Vinod

> diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
> index 849bf75..4546a1c 100644
> --- a/drivers/dma/mmp_pdma.c
> +++ b/drivers/dma/mmp_pdma.c
> @@ -27,6 +27,7 @@
>  
>  #define DCSR		0x0000
>  #define DALGN		0x00a0
> +#define DRQSR(n)	(0x00e0 + ((n) << 2))
>  #define DINT		0x00f0
>  #define DDADR		0x0200
>  #define DSADR		0x0204
> @@ -50,6 +51,9 @@
>  #define DCSR_CMPST	BIT(10)	/* The Descriptor Compare Status */
>  #define DCSR_EORINTR	BIT(9)	/* The end of Receive */
>  
> +#define DRQSR_CLR	BIT(8)	/* Clear Pending Requests */
> +#define DRQSR_REQPEND	0x1f	/* Requests Pending */
> +
>  #define DRCMR(n)	((((n) < 64) ? 0x0100 : 0x1100) + (((n) & 0x3f) << 2))
>  #define DRCMR_MAPVLD	BIT(7)	/* Map Valid (read / write) */
>  #define DRCMR_CHLNUM	0x1f	/* mask for Channel Number (read / write) */
> @@ -108,6 +112,7 @@ struct mmp_pdma_chan {
>  	u32 dcmd;
>  	u32 drcmr;
>  	u32 dev_addr;
> +	int drq;
>  
>  	/* list for desc */
>  	spinlock_t desc_lock;		/* Descriptor list lock */
> @@ -127,6 +132,8 @@ struct mmp_pdma_phy {
>  
>  struct mmp_pdma_device {
>  	int				dma_channels;
> +	unsigned int			num_dreq;
> +	const u32			*dreq;
>  	void __iomem			*base;
>  	struct device			*dev;
>  	struct dma_device		device;
> @@ -167,6 +174,9 @@ static void enable_chan(struct mmp_pdma_phy *phy)
>  		dalgn &= ~(1 << phy->idx);
>  	writel(dalgn, phy->base + DALGN);
>  
> +	if (phy->vchan->drq != -1)
> +		writel(DRQSR_CLR, phy->base + DRQSR(phy->vchan->drq));
> +
>  	reg = (phy->idx << 2) + DCSR;
>  	writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
>  }
> @@ -685,6 +695,22 @@ fail:
>  	return NULL;
>  }
>  
> +static void mmp_pdma_set_drcmr(struct mmp_pdma_chan *chan, unsigned int drmcr)
> +{
> +	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(cchan->chan.device);
> +	unsigned int i;
> +
> +	chan->drcmr = drmcr;
> +	chan->drq = -1;
> +
> +	for (i = 0; i < pdev->num_dreq; ++i) {
> +		if (pdev->dreq[i] == drmcr) {
> +			chan->drq = i;
> +			break;
> +		}
> +	}
> +}
> +
>  static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
>  			    unsigned long arg)
>  {
> @@ -745,7 +771,7 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
>  		 * be removed.
>  		 */
>  		if (cfg->slave_id)
> -			chan->drcmr = cfg->slave_id;
> +			mmp_pdma_set_drcmr(chan, cfg->slave_id);
>  		break;
>  	default:
>  		return -ENOSYS;
> @@ -909,16 +935,64 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec,
>  	if (!chan)
>  		return NULL;
>  
> -	to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
> +	mmp_pdma_set_drcmr(to_mmp_pdma_chan(chan), dma_spec->args[0]);
>  
>  	return chan;
>  }
>  
> +static int mmap_pdma_parse_platform_data(struct mmp_pdma_device *pdev)
> +{
> +	struct device_node *np = pdev->dev->of_node;
> +	struct property *prop;
> +
> +	/* Default values: 32 channels, no external DREQ. */
> +	pdev->dma_channels = 32;
> +	pdev->num_dreq = 0;
> +
> +	if (!IS_ENABLED(CONFIG_OF) || !np) {
> +		struct mmp_dma_platdata *pdata = dev_get_platdata(pdev->dev);
> +
> +		if (!pdata)
> +			return 0;
> +
> +		if (pdata->dma_channels)
> +			pdev->dma_channels = pdata->dma_channels;
> +		if (pdata->num_dreq) {
> +			pdev->num_dreq = pdata->num_dreq;
> +			pdev->dreq = pdata->dreq;
> +		}
> +
> +		return 0;
> +	}
> +
> +	of_property_read_u32(np, "#dma-channels", &pdev->dma_channels);
> +
> +	prop = of_find_property(np, "marvell,dreq");
> +	if (prop) {
> +		unsigned int num_dreq = prop->length / sizeof(unsigned long);
> +		u32 *dreq;
> +
> +		dreq = devm_kcalloc(pdev->dev, num_dreq, sizeof(*pdreq),
> +				    GFP_KERNEL);
> +		if (dreq == NULL)
> +			return -ENOMEM;
> +
> +		ret = of_property_read_u32_array(np, "marvell,dreq", dreq,
> +						 num_dreq);
> +		if (ret < 0)
> +			return ret;
> +
> +		pdev->num_dreq = num_dreq;
> +		pdev->dreq = dreq;
> +	}
> +
> +	return 0;
> +}
> +
>  static int mmp_pdma_probe(struct platform_device *op)
>  {
>  	struct mmp_pdma_device *pdev;
>  	const struct of_device_id *of_id;
> -	struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
>  	struct resource *iores;
>  	int i, ret, irq = 0;
>  	int dma_channels = 0, irq_num = 0;
> @@ -936,15 +1010,11 @@ static int mmp_pdma_probe(struct platform_device *op)
>  	if (IS_ERR(pdev->base))
>  		return PTR_ERR(pdev->base);
>  
> -	of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
> -	if (of_id)
> -		of_property_read_u32(pdev->dev->of_node, "#dma-channels",
> -				     &dma_channels);
> -	else if (pdata && pdata->dma_channels)
> -		dma_channels = pdata->dma_channels;
> -	else
> -		dma_channels = 32;	/* default 32 channel */
> -	pdev->dma_channels = dma_channels;
> +	ret = mmp_pdma_parse_platform_data(pdev);
> +	if (ret < 0)
> +		return ret;
> +
> +	dma_channels = pdev->dma_channels;
>  
>  	for (i = 0; i < dma_channels; i++) {
>  		if (platform_get_irq(op, i) > 0)
> @@ -1038,7 +1108,7 @@ bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param)
>  	if (chan->device->dev->driver != &mmp_pdma_driver.driver)
>  		return false;
>  
> -	c->drcmr = *(unsigned int *)param;
> +	mmp_pdma_set_drcmr(c, *(unsigned int *)param);
>  
>  	return true;
>  }
> diff --git a/include/linux/platform_data/mmp_dma.h b/include/linux/platform_data/mmp_dma.h
> index 2a330ec..32595b8 100644
> --- a/include/linux/platform_data/mmp_dma.h
> +++ b/include/linux/platform_data/mmp_dma.h
> @@ -14,6 +14,8 @@
>  
>  struct mmp_dma_platdata {
>  	int dma_channels;
> +	unsigned int num_dreq;
> +	const u32 *dreq;
>  };
>  
>  #endif /* MMP_DMA_H */
> -- 
> 1.8.3.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

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

* [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure
  2014-04-15 15:13 ` [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure Laurent Pinchart
  2014-05-02 15:46   ` Vinod Koul
@ 2014-05-05 17:26   ` Lars-Peter Clausen
  1 sibling, 0 replies; 14+ messages in thread
From: Lars-Peter Clausen @ 2014-05-05 17:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/15/2014 05:13 PM, Laurent Pinchart wrote:
> Fly-by transfer mode cuts down the number of bus transactions by letting
> the slave drive or latch the memory data bus during memory transactions
> instead of performing a dedicated transaction to read data from or write
> data to the slave.
>
> Support for fly-by mode by adding a new flag field to struct
> dma_slave_config.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>   include/linux/dmaengine.h | 13 +++++++++++++
>   1 file changed, 13 insertions(+)
>
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index c5c92d5..ae99153 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -304,6 +304,17 @@ enum dma_slave_buswidth {
>   };
>
>   /**
> + * enum dma_slave_flags - DMA slave configuration flags
> + * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
> + *   Instead of performing a bus transaction to read (write) data from (to) the
> + *   slave, let the slave drive (latch) the memory bus data signals during the
> + *   memory write (read) transaction.
> + */

Is there any reason not to use fly-by mode for memory to peripheral or 
peripheral to memory transfers, if fly-by mode is available? And if not how 
should generic drivers using the DMAengine API decide when to use fly-by mode 
and when not?

- Lars

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

end of thread, other threads:[~2014-05-05 17:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
2014-04-15 15:13 ` [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure Laurent Pinchart
2014-05-02 15:46   ` Vinod Koul
2014-05-02 15:47     ` Vinod Koul
2014-05-05 17:26   ` Lars-Peter Clausen
2014-04-15 15:13 ` [PATCH 2/6] dma: mmp_pdma: Fix the #dma-channels DT property documentation Laurent Pinchart
2014-05-02 15:50   ` Vinod Koul
2014-04-15 15:13 ` [PATCH 3/6] dma: mmp_pdma: Simplify access to channel drcmr value Laurent Pinchart
2014-05-02 15:51   ` Vinod Koul
2014-04-15 15:13 ` [PATCH 4/6] dma: mmp_pdma: Fix physical channel memory allocation size Laurent Pinchart
2014-05-02 15:52   ` Vinod Koul
2014-04-15 15:13 ` [PATCH 5/6] dma: mmp_pdma: Add support for fly-by transfers Laurent Pinchart
2014-04-15 15:13 ` [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests Laurent Pinchart
2014-05-02 16:09   ` Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).