All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] dmaengine: fsl-edma: add dma memcpy and suspend/resume support
@ 2014-12-30  8:41 ` Jingchang Lu
  0 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2014-12-30  8:41 UTC (permalink / raw)
  To: vinod.koul; +Cc: dan.j.williams, dmaengine, linux-kernel, linux-arm-kernel

  This two patches add the dma memory copy and PM suspend/resume support
for the Freescale eDMA engine.

----------------------------------------------------------------
Jingchang Lu (2):
	dmaengine: fsl-edma: add dma memcpy support
	dmaengine: fsl-edma: add PM suspend/resume support

 drivers/dma/fsl-edma.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 99 insertions(+), 2 deletions(-)


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

* [PATCH 0/2] dmaengine: fsl-edma: add dma memcpy and suspend/resume support
@ 2014-12-30  8:41 ` Jingchang Lu
  0 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2014-12-30  8:41 UTC (permalink / raw)
  To: linux-arm-kernel

  This two patches add the dma memory copy and PM suspend/resume support
for the Freescale eDMA engine.

----------------------------------------------------------------
Jingchang Lu (2):
	dmaengine: fsl-edma: add dma memcpy support
	dmaengine: fsl-edma: add PM suspend/resume support

 drivers/dma/fsl-edma.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 99 insertions(+), 2 deletions(-)

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

* [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
  2014-12-30  8:41 ` Jingchang Lu
@ 2014-12-30  8:41   ` Jingchang Lu
  -1 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2014-12-30  8:41 UTC (permalink / raw)
  To: vinod.koul
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-arm-kernel, Jingchang Lu

This adds the memory copy capability support, the memcpy
functionality needs to configure the DMAMUX of the channel
with the always on slave id.

Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
---
 drivers/dma/fsl-edma.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index 09e2842..e0bd517 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -110,6 +110,8 @@
 #define EDMAMUX_CHCFG_ENBL		0x80
 #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
 
+#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
+
 #define DMAMUX_NR	2
 
 #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
@@ -147,6 +149,7 @@ struct fsl_edma_slave_config {
 struct fsl_edma_chan {
 	struct virt_dma_chan		vchan;
 	enum dma_status			status;
+	u32				slave_id;
 	struct fsl_edma_engine		*edma;
 	struct fsl_edma_desc		*edesc;
 	struct fsl_edma_slave_config	fsc;
@@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
 	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
 }
 
+static struct dma_async_tx_descriptor *
+fsl_edma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst,
+			dma_addr_t src, size_t len, unsigned long tx_flags)
+{
+	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+	struct fsl_edma_desc *fsl_desc;
+	u16 soff, doff, attr;
+
+	/*
+	 * use 4-bytes data transfer size if all is 4-bytes aligned,
+	 * else 2-bytes data transfer size of all is 2-bytes aligned,
+	 * otherwise 1-byte tranfer size.
+	 */
+	if (src & 0x1 || dst & 0x1 || len & 0x1) {
+		attr = EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
+		soff = 0x1;
+		doff = 0x1;
+	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
+		attr = EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
+		soff = 0x2;
+		doff = 0x2;
+	} else {
+		attr = EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
+		soff = 0x4;
+		doff = 0x4;
+	}
+
+	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
+	if (!fsl_desc)
+		return NULL;
+	fsl_desc->iscyclic = false;
+
+	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
+			  0, 1, 1, doff, 0, true, true, false);
+
+	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
+
+}
+
 static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
 {
 	struct virt_dma_desc *vdesc;
@@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
 {
 	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
 	struct dma_chan *chan, *_chan;
+	struct fsl_edma_chan *fsl_chan;
 	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
 
 	if (dma_spec->args_count != 2)
@@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
 			chan = dma_get_slave_channel(chan);
 			if (chan) {
 				chan->device->privatecnt++;
-				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
-					dma_spec->args[1], true);
+				fsl_chan = to_fsl_edma_chan(chan);
+				fsl_chan->slave_id = dma_spec->args[1];
+				fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id,
+						  true);
 				mutex_unlock(&fsl_edma->fsl_edma_mutex);
 				return chan;
 			}
@@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
 
+	/*
+	 * If the slave id of the channel DMAMUX is not set yet,
+	 * this could happy when the channel is requested by the
+	 * dma_request_channel() for memory copy purpose instead
+	 * of by dts binding, then configure the DMAMUX with the
+	 * always on slave id.
+	 */
+	if (fsl_chan->slave_id == 0) {
+		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
+		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
+	}
 	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
 				sizeof(struct fsl_edma_hw_tcd),
 				32, 0);
@@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct dma_chan *chan)
 	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
 	fsl_edma_disable_request(fsl_chan);
 	fsl_edma_chan_mux(fsl_chan, 0, false);
+	fsl_chan->slave_id = 0;
 	fsl_chan->edesc = NULL;
 	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
 	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
@@ -903,6 +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
 	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
 	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
+	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
 
 	fsl_edma->dma_dev.dev = &pdev->dev;
 	fsl_edma->dma_dev.device_alloc_chan_resources
@@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
 	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
 	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
+	fsl_edma->dma_dev.device_prep_dma_memcpy = fsl_edma_prep_memcpy;
 	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
 	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
 	fsl_edma->dma_dev.device_resume = fsl_edma_resume;
-- 
1.8.0


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

* [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
@ 2014-12-30  8:41   ` Jingchang Lu
  0 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2014-12-30  8:41 UTC (permalink / raw)
  To: linux-arm-kernel

This adds the memory copy capability support, the memcpy
functionality needs to configure the DMAMUX of the channel
with the always on slave id.

Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
---
 drivers/dma/fsl-edma.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index 09e2842..e0bd517 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -110,6 +110,8 @@
 #define EDMAMUX_CHCFG_ENBL		0x80
 #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
 
+#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
+
 #define DMAMUX_NR	2
 
 #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
@@ -147,6 +149,7 @@ struct fsl_edma_slave_config {
 struct fsl_edma_chan {
 	struct virt_dma_chan		vchan;
 	enum dma_status			status;
+	u32				slave_id;
 	struct fsl_edma_engine		*edma;
 	struct fsl_edma_desc		*edesc;
 	struct fsl_edma_slave_config	fsc;
@@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
 	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
 }
 
+static struct dma_async_tx_descriptor *
+fsl_edma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst,
+			dma_addr_t src, size_t len, unsigned long tx_flags)
+{
+	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+	struct fsl_edma_desc *fsl_desc;
+	u16 soff, doff, attr;
+
+	/*
+	 * use 4-bytes data transfer size if all is 4-bytes aligned,
+	 * else 2-bytes data transfer size of all is 2-bytes aligned,
+	 * otherwise 1-byte tranfer size.
+	 */
+	if (src & 0x1 || dst & 0x1 || len & 0x1) {
+		attr = EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
+		soff = 0x1;
+		doff = 0x1;
+	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
+		attr = EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
+		soff = 0x2;
+		doff = 0x2;
+	} else {
+		attr = EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
+		soff = 0x4;
+		doff = 0x4;
+	}
+
+	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
+	if (!fsl_desc)
+		return NULL;
+	fsl_desc->iscyclic = false;
+
+	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
+			  0, 1, 1, doff, 0, true, true, false);
+
+	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
+
+}
+
 static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
 {
 	struct virt_dma_desc *vdesc;
@@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
 {
 	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
 	struct dma_chan *chan, *_chan;
+	struct fsl_edma_chan *fsl_chan;
 	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
 
 	if (dma_spec->args_count != 2)
@@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
 			chan = dma_get_slave_channel(chan);
 			if (chan) {
 				chan->device->privatecnt++;
-				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
-					dma_spec->args[1], true);
+				fsl_chan = to_fsl_edma_chan(chan);
+				fsl_chan->slave_id = dma_spec->args[1];
+				fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id,
+						  true);
 				mutex_unlock(&fsl_edma->fsl_edma_mutex);
 				return chan;
 			}
@@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
 
+	/*
+	 * If the slave id of the channel DMAMUX is not set yet,
+	 * this could happy when the channel is requested by the
+	 * dma_request_channel() for memory copy purpose instead
+	 * of by dts binding, then configure the DMAMUX with the
+	 * always on slave id.
+	 */
+	if (fsl_chan->slave_id == 0) {
+		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
+		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
+	}
 	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
 				sizeof(struct fsl_edma_hw_tcd),
 				32, 0);
@@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct dma_chan *chan)
 	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
 	fsl_edma_disable_request(fsl_chan);
 	fsl_edma_chan_mux(fsl_chan, 0, false);
+	fsl_chan->slave_id = 0;
 	fsl_chan->edesc = NULL;
 	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
 	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
@@ -903,6 +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
 	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
 	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
+	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
 
 	fsl_edma->dma_dev.dev = &pdev->dev;
 	fsl_edma->dma_dev.device_alloc_chan_resources
@@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
 	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
 	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
+	fsl_edma->dma_dev.device_prep_dma_memcpy = fsl_edma_prep_memcpy;
 	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
 	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
 	fsl_edma->dma_dev.device_resume = fsl_edma_resume;
-- 
1.8.0

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

* [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
  2014-12-30  8:41 ` Jingchang Lu
@ 2014-12-30  8:41   ` Jingchang Lu
  -1 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2014-12-30  8:41 UTC (permalink / raw)
  To: vinod.koul
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-arm-kernel, Jingchang Lu

This adds power management suspend/resume support for
the fsl-edma driver.

Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
---
 drivers/dma/fsl-edma.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index e0bd517..6a81699 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int fsl_edma_pm_suspend(struct device *dev)
+{
+	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
+	struct fsl_edma_chan *fsl_chan;
+	int i;
+
+	for (i = 0; i < fsl_edma->n_chans; i++) {
+		fsl_chan = &fsl_edma->chans[i];
+		fsl_edma_chan_mux(fsl_chan, 0, false);
+	}
+
+	return 0;
+}
+
+static int fsl_edma_pm_resume(struct device *dev)
+{
+	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
+	struct fsl_edma_chan *fsl_chan;
+	int i;
+
+	for (i = 0; i < fsl_edma->n_chans; i++) {
+		fsl_chan = &fsl_edma->chans[i];
+		edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i));
+		/* restore the channel slave id configuration */
+		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
+	}
+
+	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
+		    fsl_edma->membase + EDMA_CR);
+
+	return 0;
+}
+#endif
+static
+SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend, fsl_edma_pm_resume);
+
 static const struct of_device_id fsl_edma_dt_ids[] = {
 	{ .compatible = "fsl,vf610-edma", },
 	{ /* sentinel */ }
@@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
 	.driver		= {
 		.name	= "fsl-edma",
 		.of_match_table = fsl_edma_dt_ids,
+		.pm	= &fsl_edma_pm_ops,
 	},
 	.probe          = fsl_edma_probe,
 	.remove		= fsl_edma_remove,
-- 
1.8.0


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

* [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
@ 2014-12-30  8:41   ` Jingchang Lu
  0 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2014-12-30  8:41 UTC (permalink / raw)
  To: linux-arm-kernel

This adds power management suspend/resume support for
the fsl-edma driver.

Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
---
 drivers/dma/fsl-edma.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index e0bd517..6a81699 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int fsl_edma_pm_suspend(struct device *dev)
+{
+	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
+	struct fsl_edma_chan *fsl_chan;
+	int i;
+
+	for (i = 0; i < fsl_edma->n_chans; i++) {
+		fsl_chan = &fsl_edma->chans[i];
+		fsl_edma_chan_mux(fsl_chan, 0, false);
+	}
+
+	return 0;
+}
+
+static int fsl_edma_pm_resume(struct device *dev)
+{
+	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
+	struct fsl_edma_chan *fsl_chan;
+	int i;
+
+	for (i = 0; i < fsl_edma->n_chans; i++) {
+		fsl_chan = &fsl_edma->chans[i];
+		edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i));
+		/* restore the channel slave id configuration */
+		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
+	}
+
+	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
+		    fsl_edma->membase + EDMA_CR);
+
+	return 0;
+}
+#endif
+static
+SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend, fsl_edma_pm_resume);
+
 static const struct of_device_id fsl_edma_dt_ids[] = {
 	{ .compatible = "fsl,vf610-edma", },
 	{ /* sentinel */ }
@@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
 	.driver		= {
 		.name	= "fsl-edma",
 		.of_match_table = fsl_edma_dt_ids,
+		.pm	= &fsl_edma_pm_ops,
 	},
 	.probe          = fsl_edma_probe,
 	.remove		= fsl_edma_remove,
-- 
1.8.0

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

* RE: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
  2014-12-30  8:41   ` Jingchang Lu
@ 2015-01-14  9:36     ` Jingchang Lu
  -1 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2015-01-14  9:36 UTC (permalink / raw)
  To: Jingchang Lu, vinod.koul
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 999 bytes --]

Hi, Vinod,

   Could you please help review the two patches, and merge them if possible? Thanks!


Best Regards,
Jingchang

>-----Original Message-----
>From: Jingchang Lu [mailto:jingchang.lu@freescale.com]
>Sent: Tuesday, December 30, 2014 4:42 PM
>To: vinod.koul@intel.com
>Cc: dan.j.williams@intel.com; dmaengine@vger.kernel.org; linux-
>kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Lu
>Jingchang-B35083
>Subject: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
>
>This adds the memory copy capability support, the memcpy functionality
>needs to configure the DMAMUX of the channel with the always on slave id.
>
>Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
>---
> drivers/dma/fsl-edma.c | 63
>++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 61 insertions(+), 2 deletions(-)

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
@ 2015-01-14  9:36     ` Jingchang Lu
  0 siblings, 0 replies; 22+ messages in thread
From: Jingchang Lu @ 2015-01-14  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, Vinod,

   Could you please help review the two patches, and merge them if possible? Thanks!


Best Regards,
Jingchang

>-----Original Message-----
>From: Jingchang Lu [mailto:jingchang.lu at freescale.com]
>Sent: Tuesday, December 30, 2014 4:42 PM
>To: vinod.koul at intel.com
>Cc: dan.j.williams at intel.com; dmaengine at vger.kernel.org; linux-
>kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Lu
>Jingchang-B35083
>Subject: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
>
>This adds the memory copy capability support, the memcpy functionality
>needs to configure the DMAMUX of the channel with the always on slave id.
>
>Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
>---
> drivers/dma/fsl-edma.c | 63
>++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 61 insertions(+), 2 deletions(-)

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

* RE: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
  2015-01-14  9:36     ` Jingchang Lu
@ 2015-01-30  9:00       ` Yao Yuan
  -1 siblings, 0 replies; 22+ messages in thread
From: Yao Yuan @ 2015-01-30  9:00 UTC (permalink / raw)
  To: vinod.koul; +Cc: dmaengine, dan.j.williams, linux-kernel, linux-arm-kernel

Hi Vinod,

Could you please take some times help to review the two patches?

Thanks.

Best Regards,
Yuan Yao

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces@lists.infradead.org]
> On Behalf Of Jingchang Lu
> Sent: Wednesday, January 14, 2015 5:37 PM
> To: Lu Jingchang-B35083; vinod.koul@intel.com
> Cc: dmaengine@vger.kernel.org; dan.j.williams@intel.com; linux-
> kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org
> Subject: RE: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
> 
> Hi, Vinod,
> 
>    Could you please help review the two patches, and merge them if possible?
> Thanks!
> 
> 
> Best Regards,
> Jingchang
> 
> >-----Original Message-----
> >From: Jingchang Lu [mailto:jingchang.lu@freescale.com]
> >Sent: Tuesday, December 30, 2014 4:42 PM
> >To: vinod.koul@intel.com
> >Cc: dan.j.williams@intel.com; dmaengine@vger.kernel.org; linux-
> >kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Lu
> >Jingchang-B35083
> >Subject: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
> >
> >This adds the memory copy capability support, the memcpy functionality
> >needs to configure the DMAMUX of the channel with the always on slave id.
> >
> >Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> >---
> > drivers/dma/fsl-edma.c | 63
> >++++++++++++++++++++++++++++++++++++++++++++++++--
> > 1 file changed, 61 insertions(+), 2 deletions(-)
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
@ 2015-01-30  9:00       ` Yao Yuan
  0 siblings, 0 replies; 22+ messages in thread
From: Yao Yuan @ 2015-01-30  9:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod,

Could you please take some times help to review the two patches?

Thanks.

Best Regards,
Yuan Yao

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org]
> On Behalf Of Jingchang Lu
> Sent: Wednesday, January 14, 2015 5:37 PM
> To: Lu Jingchang-B35083; vinod.koul at intel.com
> Cc: dmaengine at vger.kernel.org; dan.j.williams at intel.com; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: RE: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
> 
> Hi, Vinod,
> 
>    Could you please help review the two patches, and merge them if possible?
> Thanks!
> 
> 
> Best Regards,
> Jingchang
> 
> >-----Original Message-----
> >From: Jingchang Lu [mailto:jingchang.lu at freescale.com]
> >Sent: Tuesday, December 30, 2014 4:42 PM
> >To: vinod.koul at intel.com
> >Cc: dan.j.williams at intel.com; dmaengine at vger.kernel.org; linux-
> >kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Lu
> >Jingchang-B35083
> >Subject: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
> >
> >This adds the memory copy capability support, the memcpy functionality
> >needs to configure the DMAMUX of the channel with the always on slave id.
> >
> >Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> >---
> > drivers/dma/fsl-edma.c | 63
> >++++++++++++++++++++++++++++++++++++++++++++++++--
> > 1 file changed, 61 insertions(+), 2 deletions(-)
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
  2014-12-30  8:41   ` Jingchang Lu
@ 2015-01-30 12:39     ` Stefan Agner
  -1 siblings, 0 replies; 22+ messages in thread
From: Stefan Agner @ 2015-01-30 12:39 UTC (permalink / raw)
  To: Jingchang Lu
  Cc: vinod.koul, dmaengine, dan.j.williams, linux-kernel, linux-arm-kernel

On 2014-12-30 09:41, Jingchang Lu wrote:
> This adds the memory copy capability support, the memcpy
> functionality needs to configure the DMAMUX of the channel
> with the always on slave id.

Hi Jingchang,

I run some tests on v3.19-rc6 with this patches applied on Vybrid SoC
VF500 and VF610.

On VF500 clocked at 400MHz I get this numbers:
# insmod dmatest.ko max_channels=1 iterations=100 run=1
[  616.809594] dmatest: Started 1 threads using dma0chan0
[  617.293498] dmatest: dma0chan0-copy0: summary 100 tests, 0 failures
209 iops 1613 KB/s (0)

In contrast, on a VF610 clocked at 500MHz I get this:
# insmod dmatest.ko max_channels=1 iterations=100 run=1
[  154.203290] dmatest: Started 1 threads using dma0chan4
[  154.614225] dmatest: dma0chan4-copy0: summary 100 tests, 0 failures
246 iops 2002 KB/s (0)

Not that huge numbers, but I guess this is what the hardware can
deliver... Did you run some performance tests?

But generally, looks good.

Tested-by: Stefan Agner <stefan@agner.ch>

> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 61 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index 09e2842..e0bd517 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -110,6 +110,8 @@
>  #define EDMAMUX_CHCFG_ENBL		0x80
>  #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
>  
> +#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
> +
>  #define DMAMUX_NR	2
>  
>  #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
> @@ -147,6 +149,7 @@ struct fsl_edma_slave_config {
>  struct fsl_edma_chan {
>  	struct virt_dma_chan		vchan;
>  	enum dma_status			status;
> +	u32				slave_id;
>  	struct fsl_edma_engine		*edma;
>  	struct fsl_edma_desc		*edesc;
>  	struct fsl_edma_slave_config	fsc;
> @@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor
> *fsl_edma_prep_slave_sg(
>  	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
>  }
>  
> +static struct dma_async_tx_descriptor *
> +fsl_edma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst,
> +			dma_addr_t src, size_t len, unsigned long tx_flags)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct fsl_edma_desc *fsl_desc;
> +	u16 soff, doff, attr;
> +
> +	/*
> +	 * use 4-bytes data transfer size if all is 4-bytes aligned,
> +	 * else 2-bytes data transfer size of all is 2-bytes aligned,
> +	 * otherwise 1-byte tranfer size.
> +	 */
> +	if (src & 0x1 || dst & 0x1 || len & 0x1) {
> +		attr = EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
> +		soff = 0x1;
> +		doff = 0x1;
> +	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
> +		attr = EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
> +		soff = 0x2;
> +		doff = 0x2;
> +	} else {
> +		attr = EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
> +		soff = 0x4;
> +		doff = 0x4;
> +	}
> +
> +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
> +	if (!fsl_desc)
> +		return NULL;
> +	fsl_desc->iscyclic = false;
> +
> +	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
> +			  0, 1, 1, doff, 0, true, true, false);
> +
> +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
> +
> +}
> +
>  static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
>  {
>  	struct virt_dma_desc *vdesc;
> @@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct
> of_phandle_args *dma_spec,
>  {
>  	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
>  	struct dma_chan *chan, *_chan;
> +	struct fsl_edma_chan *fsl_chan;
>  	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
>  
>  	if (dma_spec->args_count != 2)
> @@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct
> of_phandle_args *dma_spec,
>  			chan = dma_get_slave_channel(chan);
>  			if (chan) {
>  				chan->device->privatecnt++;
> -				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> -					dma_spec->args[1], true);
> +				fsl_chan = to_fsl_edma_chan(chan);
> +				fsl_chan->slave_id = dma_spec->args[1];
> +				fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id,
> +						  true);
>  				mutex_unlock(&fsl_edma->fsl_edma_mutex);
>  				return chan;
>  			}
> @@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct
> dma_chan *chan)
>  {
>  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
>  
> +	/*
> +	 * If the slave id of the channel DMAMUX is not set yet,
> +	 * this could happy when the channel is requested by the
> +	 * dma_request_channel() for memory copy purpose instead
> +	 * of by dts binding, then configure the DMAMUX with the
> +	 * always on slave id.
> +	 */
> +	if (fsl_chan->slave_id == 0) {
> +		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> +	}
>  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
>  				sizeof(struct fsl_edma_hw_tcd),
>  				32, 0);
> @@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct
> dma_chan *chan)
>  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
>  	fsl_edma_disable_request(fsl_chan);
>  	fsl_edma_chan_mux(fsl_chan, 0, false);
> +	fsl_chan->slave_id = 0;
>  	fsl_chan->edesc = NULL;
>  	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
>  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> @@ -903,6 +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
> +	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
>  
>  	fsl_edma->dma_dev.dev = &pdev->dev;
>  	fsl_edma->dma_dev.device_alloc_chan_resources
> @@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
>  	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
>  	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
> +	fsl_edma->dma_dev.device_prep_dma_memcpy = fsl_edma_prep_memcpy;
>  	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
>  	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
>  	fsl_edma->dma_dev.device_resume = fsl_edma_resume;

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

* [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
@ 2015-01-30 12:39     ` Stefan Agner
  0 siblings, 0 replies; 22+ messages in thread
From: Stefan Agner @ 2015-01-30 12:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-12-30 09:41, Jingchang Lu wrote:
> This adds the memory copy capability support, the memcpy
> functionality needs to configure the DMAMUX of the channel
> with the always on slave id.

Hi Jingchang,

I run some tests on v3.19-rc6 with this patches applied on Vybrid SoC
VF500 and VF610.

On VF500 clocked at 400MHz I get this numbers:
# insmod dmatest.ko max_channels=1 iterations=100 run=1
[  616.809594] dmatest: Started 1 threads using dma0chan0
[  617.293498] dmatest: dma0chan0-copy0: summary 100 tests, 0 failures
209 iops 1613 KB/s (0)

In contrast, on a VF610 clocked at 500MHz I get this:
# insmod dmatest.ko max_channels=1 iterations=100 run=1
[  154.203290] dmatest: Started 1 threads using dma0chan4
[  154.614225] dmatest: dma0chan4-copy0: summary 100 tests, 0 failures
246 iops 2002 KB/s (0)

Not that huge numbers, but I guess this is what the hardware can
deliver... Did you run some performance tests?

But generally, looks good.

Tested-by: Stefan Agner <stefan@agner.ch>

> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 61 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index 09e2842..e0bd517 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -110,6 +110,8 @@
>  #define EDMAMUX_CHCFG_ENBL		0x80
>  #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
>  
> +#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
> +
>  #define DMAMUX_NR	2
>  
>  #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
> @@ -147,6 +149,7 @@ struct fsl_edma_slave_config {
>  struct fsl_edma_chan {
>  	struct virt_dma_chan		vchan;
>  	enum dma_status			status;
> +	u32				slave_id;
>  	struct fsl_edma_engine		*edma;
>  	struct fsl_edma_desc		*edesc;
>  	struct fsl_edma_slave_config	fsc;
> @@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor
> *fsl_edma_prep_slave_sg(
>  	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
>  }
>  
> +static struct dma_async_tx_descriptor *
> +fsl_edma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst,
> +			dma_addr_t src, size_t len, unsigned long tx_flags)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct fsl_edma_desc *fsl_desc;
> +	u16 soff, doff, attr;
> +
> +	/*
> +	 * use 4-bytes data transfer size if all is 4-bytes aligned,
> +	 * else 2-bytes data transfer size of all is 2-bytes aligned,
> +	 * otherwise 1-byte tranfer size.
> +	 */
> +	if (src & 0x1 || dst & 0x1 || len & 0x1) {
> +		attr = EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
> +		soff = 0x1;
> +		doff = 0x1;
> +	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
> +		attr = EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
> +		soff = 0x2;
> +		doff = 0x2;
> +	} else {
> +		attr = EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
> +		soff = 0x4;
> +		doff = 0x4;
> +	}
> +
> +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
> +	if (!fsl_desc)
> +		return NULL;
> +	fsl_desc->iscyclic = false;
> +
> +	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
> +			  0, 1, 1, doff, 0, true, true, false);
> +
> +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
> +
> +}
> +
>  static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
>  {
>  	struct virt_dma_desc *vdesc;
> @@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct
> of_phandle_args *dma_spec,
>  {
>  	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
>  	struct dma_chan *chan, *_chan;
> +	struct fsl_edma_chan *fsl_chan;
>  	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
>  
>  	if (dma_spec->args_count != 2)
> @@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct
> of_phandle_args *dma_spec,
>  			chan = dma_get_slave_channel(chan);
>  			if (chan) {
>  				chan->device->privatecnt++;
> -				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> -					dma_spec->args[1], true);
> +				fsl_chan = to_fsl_edma_chan(chan);
> +				fsl_chan->slave_id = dma_spec->args[1];
> +				fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id,
> +						  true);
>  				mutex_unlock(&fsl_edma->fsl_edma_mutex);
>  				return chan;
>  			}
> @@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct
> dma_chan *chan)
>  {
>  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
>  
> +	/*
> +	 * If the slave id of the channel DMAMUX is not set yet,
> +	 * this could happy when the channel is requested by the
> +	 * dma_request_channel() for memory copy purpose instead
> +	 * of by dts binding, then configure the DMAMUX with the
> +	 * always on slave id.
> +	 */
> +	if (fsl_chan->slave_id == 0) {
> +		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> +	}
>  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
>  				sizeof(struct fsl_edma_hw_tcd),
>  				32, 0);
> @@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct
> dma_chan *chan)
>  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
>  	fsl_edma_disable_request(fsl_chan);
>  	fsl_edma_chan_mux(fsl_chan, 0, false);
> +	fsl_chan->slave_id = 0;
>  	fsl_chan->edesc = NULL;
>  	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
>  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> @@ -903,6 +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
> +	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
>  
>  	fsl_edma->dma_dev.dev = &pdev->dev;
>  	fsl_edma->dma_dev.device_alloc_chan_resources
> @@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
>  	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
>  	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
> +	fsl_edma->dma_dev.device_prep_dma_memcpy = fsl_edma_prep_memcpy;
>  	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
>  	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
>  	fsl_edma->dma_dev.device_resume = fsl_edma_resume;

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

* Re: [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
  2014-12-30  8:41   ` Jingchang Lu
@ 2015-01-30 13:05     ` Stefan Agner
  -1 siblings, 0 replies; 22+ messages in thread
From: Stefan Agner @ 2015-01-30 13:05 UTC (permalink / raw)
  To: Jingchang Lu
  Cc: vinod.koul, dmaengine, dan.j.williams, linux-kernel, linux-arm-kernel

On 2014-12-30 09:41, Jingchang Lu wrote:
> This adds power management suspend/resume support for
> the fsl-edma driver.
> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index e0bd517..6a81699 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int fsl_edma_pm_suspend(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		fsl_edma_chan_mux(fsl_chan, 0, false);
> +	}
> +
> +	return 0;
> +}
> +
> +static int fsl_edma_pm_resume(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i));

What is the expectation of the suspend mode, are the registers and
descriptors cleared during suspend? So this makes sure we have all
descriptors disabled on wake-up, right?

> +		/* restore the channel slave id configuration */
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);

And here the channel gets muxed again.

But the user is expected to reconfigure a channel, e.g. using
dmaengine_slave_config and the dmaengine_prep*? Also and cyclic DMA
which has been paused before would be interrupted, is this correct?

I don't know what the common exception of the API is, I'm just asking so
I now what I can expect when using the DMA driver in other device
drivers...

--
Stefan

> +	}
> +
> +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
> +		    fsl_edma->membase + EDMA_CR);
> +
> +	return 0;
> +}
> +#endif
> +static
> +SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend, fsl_edma_pm_resume);
> +
>  static const struct of_device_id fsl_edma_dt_ids[] = {
>  	{ .compatible = "fsl,vf610-edma", },
>  	{ /* sentinel */ }
> @@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
>  	.driver		= {
>  		.name	= "fsl-edma",
>  		.of_match_table = fsl_edma_dt_ids,
> +		.pm	= &fsl_edma_pm_ops,
>  	},
>  	.probe          = fsl_edma_probe,
>  	.remove		= fsl_edma_remove,

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

* [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
@ 2015-01-30 13:05     ` Stefan Agner
  0 siblings, 0 replies; 22+ messages in thread
From: Stefan Agner @ 2015-01-30 13:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-12-30 09:41, Jingchang Lu wrote:
> This adds power management suspend/resume support for
> the fsl-edma driver.
> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index e0bd517..6a81699 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int fsl_edma_pm_suspend(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		fsl_edma_chan_mux(fsl_chan, 0, false);
> +	}
> +
> +	return 0;
> +}
> +
> +static int fsl_edma_pm_resume(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i));

What is the expectation of the suspend mode, are the registers and
descriptors cleared during suspend? So this makes sure we have all
descriptors disabled on wake-up, right?

> +		/* restore the channel slave id configuration */
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);

And here the channel gets muxed again.

But the user is expected to reconfigure a channel, e.g. using
dmaengine_slave_config and the dmaengine_prep*? Also and cyclic DMA
which has been paused before would be interrupted, is this correct?

I don't know what the common exception of the API is, I'm just asking so
I now what I can expect when using the DMA driver in other device
drivers...

--
Stefan

> +	}
> +
> +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
> +		    fsl_edma->membase + EDMA_CR);
> +
> +	return 0;
> +}
> +#endif
> +static
> +SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend, fsl_edma_pm_resume);
> +
>  static const struct of_device_id fsl_edma_dt_ids[] = {
>  	{ .compatible = "fsl,vf610-edma", },
>  	{ /* sentinel */ }
> @@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
>  	.driver		= {
>  		.name	= "fsl-edma",
>  		.of_match_table = fsl_edma_dt_ids,
> +		.pm	= &fsl_edma_pm_ops,
>  	},
>  	.probe          = fsl_edma_probe,
>  	.remove		= fsl_edma_remove,

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

* RE: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
  2015-01-30 12:39     ` Stefan Agner
@ 2015-02-11  8:06       ` Yao Yuan
  -1 siblings, 0 replies; 22+ messages in thread
From: Yao Yuan @ 2015-02-11  8:06 UTC (permalink / raw)
  To: Stefan Agner
  Cc: vinod.koul, dmaengine, dan.j.williams, linux-kernel, linux-arm-kernel

Hi Stefan,

Thanks for your test.

Yes, it's not a huge number.

The number is always very small especially when the "test_buf_size" is small.

For dmatest tool, the measure transmission time is far greater than the actual transmission time.
So the number is small. In fact, the DMA with memory copy mode is very fast.

Best Regards,
Yuan Yao

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces@lists.infradead.org]
> On Behalf Of Stefan Agner
> Sent: Friday, January 30, 2015 8:39 PM
> To: Lu Jingchang-B35083
> Cc: vinod.koul@intel.com; dmaengine@vger.kernel.org;
> dan.j.williams@intel.com; linux-kernel@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org
> Subject: Re: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
> 
> On 2014-12-30 09:41, Jingchang Lu wrote:
> > This adds the memory copy capability support, the memcpy functionality
> > needs to configure the DMAMUX of the channel with the always on slave
> > id.
> 
> Hi Jingchang,
> 
> I run some tests on v3.19-rc6 with this patches applied on Vybrid SoC
> VF500 and VF610.
> 
> On VF500 clocked at 400MHz I get this numbers:
> # insmod dmatest.ko max_channels=1 iterations=100 run=1 [  616.809594]
> dmatest: Started 1 threads using dma0chan0 [  617.293498] dmatest:
> dma0chan0-copy0: summary 100 tests, 0 failures
> 209 iops 1613 KB/s (0)
> 
> In contrast, on a VF610 clocked at 500MHz I get this:
> # insmod dmatest.ko max_channels=1 iterations=100 run=1 [  154.203290]
> dmatest: Started 1 threads using dma0chan4 [  154.614225] dmatest:
> dma0chan4-copy0: summary 100 tests, 0 failures
> 246 iops 2002 KB/s (0)
> 
> Not that huge numbers, but I guess this is what the hardware can deliver... Did
> you run some performance tests?
> 
> But generally, looks good.
> 
> Tested-by: Stefan Agner <stefan@agner.ch>
> 
> >
> > Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> > ---
> >  drivers/dma/fsl-edma.c | 63
> > ++++++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 61 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index
> > 09e2842..e0bd517 100644
> > --- a/drivers/dma/fsl-edma.c
> > +++ b/drivers/dma/fsl-edma.c
> > @@ -110,6 +110,8 @@
> >  #define EDMAMUX_CHCFG_ENBL		0x80
> >  #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
> >
> > +#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
> > +
> >  #define DMAMUX_NR	2
> >
> >  #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> \
> > @@ -147,6 +149,7 @@ struct fsl_edma_slave_config {  struct
> > fsl_edma_chan {
> >  	struct virt_dma_chan		vchan;
> >  	enum dma_status			status;
> > +	u32				slave_id;
> >  	struct fsl_edma_engine		*edma;
> >  	struct fsl_edma_desc		*edesc;
> >  	struct fsl_edma_slave_config	fsc;
> > @@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor
> > *fsl_edma_prep_slave_sg(
> >  	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);  }
> >
> > +static struct dma_async_tx_descriptor * fsl_edma_prep_memcpy(struct
> > +dma_chan *chan, dma_addr_t dst,
> > +			dma_addr_t src, size_t len, unsigned long tx_flags) {
> > +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> > +	struct fsl_edma_desc *fsl_desc;
> > +	u16 soff, doff, attr;
> > +
> > +	/*
> > +	 * use 4-bytes data transfer size if all is 4-bytes aligned,
> > +	 * else 2-bytes data transfer size of all is 2-bytes aligned,
> > +	 * otherwise 1-byte tranfer size.
> > +	 */
> > +	if (src & 0x1 || dst & 0x1 || len & 0x1) {
> > +		attr = EDMA_TCD_ATTR_SSIZE_8BIT |
> EDMA_TCD_ATTR_DSIZE_8BIT;
> > +		soff = 0x1;
> > +		doff = 0x1;
> > +	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
> > +		attr = EDMA_TCD_ATTR_SSIZE_16BIT |
> EDMA_TCD_ATTR_DSIZE_16BIT;
> > +		soff = 0x2;
> > +		doff = 0x2;
> > +	} else {
> > +		attr = EDMA_TCD_ATTR_SSIZE_32BIT |
> EDMA_TCD_ATTR_DSIZE_32BIT;
> > +		soff = 0x4;
> > +		doff = 0x4;
> > +	}
> > +
> > +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
> > +	if (!fsl_desc)
> > +		return NULL;
> > +	fsl_desc->iscyclic = false;
> > +
> > +	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
> > +			  0, 1, 1, doff, 0, true, true, false);
> > +
> > +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
> > +
> > +}
> > +
> >  static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)  {
> >  	struct virt_dma_desc *vdesc;
> > @@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct
> > of_phandle_args *dma_spec,  {
> >  	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
> >  	struct dma_chan *chan, *_chan;
> > +	struct fsl_edma_chan *fsl_chan;
> >  	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
> >
> >  	if (dma_spec->args_count != 2)
> > @@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct
> > of_phandle_args *dma_spec,
> >  			chan = dma_get_slave_channel(chan);
> >  			if (chan) {
> >  				chan->device->privatecnt++;
> > -				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> > -					dma_spec->args[1], true);
> > +				fsl_chan = to_fsl_edma_chan(chan);
> > +				fsl_chan->slave_id = dma_spec->args[1];
> > +				fsl_edma_chan_mux(fsl_chan, fsl_chan-
> >slave_id,
> > +						  true);
> >  				mutex_unlock(&fsl_edma->fsl_edma_mutex);
> >  				return chan;
> >  			}
> > @@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct
> > dma_chan *chan)
> >  {
> >  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> >
> > +	/*
> > +	 * If the slave id of the channel DMAMUX is not set yet,
> > +	 * this could happy when the channel is requested by the
> > +	 * dma_request_channel() for memory copy purpose instead
> > +	 * of by dts binding, then configure the DMAMUX with the
> > +	 * always on slave id.
> > +	 */
> > +	if (fsl_chan->slave_id == 0) {
> > +		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
> > +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> > +	}
> >  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device-
> >dev,
> >  				sizeof(struct fsl_edma_hw_tcd),
> >  				32, 0);
> > @@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct
> > dma_chan *chan)
> >  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> >  	fsl_edma_disable_request(fsl_chan);
> >  	fsl_edma_chan_mux(fsl_chan, 0, false);
> > +	fsl_chan->slave_id = 0;
> >  	fsl_chan->edesc = NULL;
> >  	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> >  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); @@ -903,6
> > +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
> >  	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
> >  	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
> >  	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
> > +	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
> >
> >  	fsl_edma->dma_dev.dev = &pdev->dev;
> >  	fsl_edma->dma_dev.device_alloc_chan_resources
> > @@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device
> *pdev)
> >  	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
> >  	fsl_edma->dma_dev.device_prep_slave_sg =
> fsl_edma_prep_slave_sg;
> >  	fsl_edma->dma_dev.device_prep_dma_cyclic =
> fsl_edma_prep_dma_cyclic;
> > +	fsl_edma->dma_dev.device_prep_dma_memcpy =
> fsl_edma_prep_memcpy;
> >  	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
> >  	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
> >  	fsl_edma->dma_dev.device_resume = fsl_edma_resume;
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
@ 2015-02-11  8:06       ` Yao Yuan
  0 siblings, 0 replies; 22+ messages in thread
From: Yao Yuan @ 2015-02-11  8:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stefan,

Thanks for your test.

Yes, it's not a huge number.

The number is always very small especially when the "test_buf_size" is small.

For dmatest tool, the measure transmission time is far greater than the actual transmission time.
So the number is small. In fact, the DMA with memory copy mode is very fast.

Best Regards,
Yuan Yao

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org]
> On Behalf Of Stefan Agner
> Sent: Friday, January 30, 2015 8:39 PM
> To: Lu Jingchang-B35083
> Cc: vinod.koul at intel.com; dmaengine at vger.kernel.org;
> dan.j.williams at intel.com; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
> 
> On 2014-12-30 09:41, Jingchang Lu wrote:
> > This adds the memory copy capability support, the memcpy functionality
> > needs to configure the DMAMUX of the channel with the always on slave
> > id.
> 
> Hi Jingchang,
> 
> I run some tests on v3.19-rc6 with this patches applied on Vybrid SoC
> VF500 and VF610.
> 
> On VF500 clocked at 400MHz I get this numbers:
> # insmod dmatest.ko max_channels=1 iterations=100 run=1 [  616.809594]
> dmatest: Started 1 threads using dma0chan0 [  617.293498] dmatest:
> dma0chan0-copy0: summary 100 tests, 0 failures
> 209 iops 1613 KB/s (0)
> 
> In contrast, on a VF610 clocked at 500MHz I get this:
> # insmod dmatest.ko max_channels=1 iterations=100 run=1 [  154.203290]
> dmatest: Started 1 threads using dma0chan4 [  154.614225] dmatest:
> dma0chan4-copy0: summary 100 tests, 0 failures
> 246 iops 2002 KB/s (0)
> 
> Not that huge numbers, but I guess this is what the hardware can deliver... Did
> you run some performance tests?
> 
> But generally, looks good.
> 
> Tested-by: Stefan Agner <stefan@agner.ch>
> 
> >
> > Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> > ---
> >  drivers/dma/fsl-edma.c | 63
> > ++++++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 61 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index
> > 09e2842..e0bd517 100644
> > --- a/drivers/dma/fsl-edma.c
> > +++ b/drivers/dma/fsl-edma.c
> > @@ -110,6 +110,8 @@
> >  #define EDMAMUX_CHCFG_ENBL		0x80
> >  #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
> >
> > +#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
> > +
> >  #define DMAMUX_NR	2
> >
> >  #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> \
> > @@ -147,6 +149,7 @@ struct fsl_edma_slave_config {  struct
> > fsl_edma_chan {
> >  	struct virt_dma_chan		vchan;
> >  	enum dma_status			status;
> > +	u32				slave_id;
> >  	struct fsl_edma_engine		*edma;
> >  	struct fsl_edma_desc		*edesc;
> >  	struct fsl_edma_slave_config	fsc;
> > @@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor
> > *fsl_edma_prep_slave_sg(
> >  	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);  }
> >
> > +static struct dma_async_tx_descriptor * fsl_edma_prep_memcpy(struct
> > +dma_chan *chan, dma_addr_t dst,
> > +			dma_addr_t src, size_t len, unsigned long tx_flags) {
> > +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> > +	struct fsl_edma_desc *fsl_desc;
> > +	u16 soff, doff, attr;
> > +
> > +	/*
> > +	 * use 4-bytes data transfer size if all is 4-bytes aligned,
> > +	 * else 2-bytes data transfer size of all is 2-bytes aligned,
> > +	 * otherwise 1-byte tranfer size.
> > +	 */
> > +	if (src & 0x1 || dst & 0x1 || len & 0x1) {
> > +		attr = EDMA_TCD_ATTR_SSIZE_8BIT |
> EDMA_TCD_ATTR_DSIZE_8BIT;
> > +		soff = 0x1;
> > +		doff = 0x1;
> > +	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
> > +		attr = EDMA_TCD_ATTR_SSIZE_16BIT |
> EDMA_TCD_ATTR_DSIZE_16BIT;
> > +		soff = 0x2;
> > +		doff = 0x2;
> > +	} else {
> > +		attr = EDMA_TCD_ATTR_SSIZE_32BIT |
> EDMA_TCD_ATTR_DSIZE_32BIT;
> > +		soff = 0x4;
> > +		doff = 0x4;
> > +	}
> > +
> > +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
> > +	if (!fsl_desc)
> > +		return NULL;
> > +	fsl_desc->iscyclic = false;
> > +
> > +	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
> > +			  0, 1, 1, doff, 0, true, true, false);
> > +
> > +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
> > +
> > +}
> > +
> >  static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)  {
> >  	struct virt_dma_desc *vdesc;
> > @@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct
> > of_phandle_args *dma_spec,  {
> >  	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
> >  	struct dma_chan *chan, *_chan;
> > +	struct fsl_edma_chan *fsl_chan;
> >  	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
> >
> >  	if (dma_spec->args_count != 2)
> > @@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct
> > of_phandle_args *dma_spec,
> >  			chan = dma_get_slave_channel(chan);
> >  			if (chan) {
> >  				chan->device->privatecnt++;
> > -				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> > -					dma_spec->args[1], true);
> > +				fsl_chan = to_fsl_edma_chan(chan);
> > +				fsl_chan->slave_id = dma_spec->args[1];
> > +				fsl_edma_chan_mux(fsl_chan, fsl_chan-
> >slave_id,
> > +						  true);
> >  				mutex_unlock(&fsl_edma->fsl_edma_mutex);
> >  				return chan;
> >  			}
> > @@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct
> > dma_chan *chan)
> >  {
> >  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> >
> > +	/*
> > +	 * If the slave id of the channel DMAMUX is not set yet,
> > +	 * this could happy when the channel is requested by the
> > +	 * dma_request_channel() for memory copy purpose instead
> > +	 * of by dts binding, then configure the DMAMUX with the
> > +	 * always on slave id.
> > +	 */
> > +	if (fsl_chan->slave_id == 0) {
> > +		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
> > +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> > +	}
> >  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device-
> >dev,
> >  				sizeof(struct fsl_edma_hw_tcd),
> >  				32, 0);
> > @@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct
> > dma_chan *chan)
> >  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> >  	fsl_edma_disable_request(fsl_chan);
> >  	fsl_edma_chan_mux(fsl_chan, 0, false);
> > +	fsl_chan->slave_id = 0;
> >  	fsl_chan->edesc = NULL;
> >  	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> >  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); @@ -903,6
> > +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
> >  	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
> >  	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
> >  	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
> > +	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
> >
> >  	fsl_edma->dma_dev.dev = &pdev->dev;
> >  	fsl_edma->dma_dev.device_alloc_chan_resources
> > @@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device
> *pdev)
> >  	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
> >  	fsl_edma->dma_dev.device_prep_slave_sg =
> fsl_edma_prep_slave_sg;
> >  	fsl_edma->dma_dev.device_prep_dma_cyclic =
> fsl_edma_prep_dma_cyclic;
> > +	fsl_edma->dma_dev.device_prep_dma_memcpy =
> fsl_edma_prep_memcpy;
> >  	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
> >  	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
> >  	fsl_edma->dma_dev.device_resume = fsl_edma_resume;
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
  2014-12-30  8:41   ` Jingchang Lu
@ 2015-03-05 10:39     ` Vinod Koul
  -1 siblings, 0 replies; 22+ messages in thread
From: Vinod Koul @ 2015-03-05 10:39 UTC (permalink / raw)
  To: Jingchang Lu; +Cc: dan.j.williams, dmaengine, linux-kernel, linux-arm-kernel

On Tue, Dec 30, 2014 at 04:41:46PM +0800, Jingchang Lu wrote:
> This adds the memory copy capability support, the memcpy
> functionality needs to configure the DMAMUX of the channel
> with the always on slave id.
sorry looks like this slipped earlier..

> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 61 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index 09e2842..e0bd517 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -110,6 +110,8 @@
>  #define EDMAMUX_CHCFG_ENBL		0x80
>  #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
>  
> +#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
shouldnt this be namespaced aptly

otherwise this looks okay, so can you rebase and resend

-- 
~Vinod
> +
>  #define DMAMUX_NR	2
>  
>  #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
> @@ -147,6 +149,7 @@ struct fsl_edma_slave_config {
>  struct fsl_edma_chan {
>  	struct virt_dma_chan		vchan;
>  	enum dma_status			status;
> +	u32				slave_id;
>  	struct fsl_edma_engine		*edma;
>  	struct fsl_edma_desc		*edesc;
>  	struct fsl_edma_slave_config	fsc;
> @@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
>  	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
>  }
>  
> +static struct dma_async_tx_descriptor *
> +fsl_edma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst,
> +			dma_addr_t src, size_t len, unsigned long tx_flags)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct fsl_edma_desc *fsl_desc;
> +	u16 soff, doff, attr;
> +
> +	/*
> +	 * use 4-bytes data transfer size if all is 4-bytes aligned,
> +	 * else 2-bytes data transfer size of all is 2-bytes aligned,
> +	 * otherwise 1-byte tranfer size.
> +	 */
> +	if (src & 0x1 || dst & 0x1 || len & 0x1) {
> +		attr = EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
> +		soff = 0x1;
> +		doff = 0x1;
> +	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
> +		attr = EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
> +		soff = 0x2;
> +		doff = 0x2;
> +	} else {
> +		attr = EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
> +		soff = 0x4;
> +		doff = 0x4;
> +	}
> +
> +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
> +	if (!fsl_desc)
> +		return NULL;
> +	fsl_desc->iscyclic = false;
> +
> +	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
> +			  0, 1, 1, doff, 0, true, true, false);
> +
> +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
> +
> +}
> +
>  static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
>  {
>  	struct virt_dma_desc *vdesc;
> @@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
>  {
>  	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
>  	struct dma_chan *chan, *_chan;
> +	struct fsl_edma_chan *fsl_chan;
>  	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
>  
>  	if (dma_spec->args_count != 2)
> @@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
>  			chan = dma_get_slave_channel(chan);
>  			if (chan) {
>  				chan->device->privatecnt++;
> -				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> -					dma_spec->args[1], true);
> +				fsl_chan = to_fsl_edma_chan(chan);
> +				fsl_chan->slave_id = dma_spec->args[1];
> +				fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id,
> +						  true);
>  				mutex_unlock(&fsl_edma->fsl_edma_mutex);
>  				return chan;
>  			}
> @@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
>  {
>  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
>  
> +	/*
> +	 * If the slave id of the channel DMAMUX is not set yet,
> +	 * this could happy when the channel is requested by the
> +	 * dma_request_channel() for memory copy purpose instead
> +	 * of by dts binding, then configure the DMAMUX with the
> +	 * always on slave id.
> +	 */
> +	if (fsl_chan->slave_id == 0) {
> +		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> +	}
>  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
>  				sizeof(struct fsl_edma_hw_tcd),
>  				32, 0);
> @@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct dma_chan *chan)
>  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
>  	fsl_edma_disable_request(fsl_chan);
>  	fsl_edma_chan_mux(fsl_chan, 0, false);
> +	fsl_chan->slave_id = 0;
>  	fsl_chan->edesc = NULL;
>  	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
>  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> @@ -903,6 +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
> +	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
>  
>  	fsl_edma->dma_dev.dev = &pdev->dev;
>  	fsl_edma->dma_dev.device_alloc_chan_resources
> @@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
>  	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
>  	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
> +	fsl_edma->dma_dev.device_prep_dma_memcpy = fsl_edma_prep_memcpy;
>  	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
>  	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
>  	fsl_edma->dma_dev.device_resume = fsl_edma_resume;
> -- 
> 1.8.0
> 

-- 

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

* [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support
@ 2015-03-05 10:39     ` Vinod Koul
  0 siblings, 0 replies; 22+ messages in thread
From: Vinod Koul @ 2015-03-05 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 30, 2014 at 04:41:46PM +0800, Jingchang Lu wrote:
> This adds the memory copy capability support, the memcpy
> functionality needs to configure the DMAMUX of the channel
> with the always on slave id.
sorry looks like this slipped earlier..

> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 61 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index 09e2842..e0bd517 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -110,6 +110,8 @@
>  #define EDMAMUX_CHCFG_ENBL		0x80
>  #define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
>  
> +#define SLAVE_ID_ALWAYSON	63 /* the always on slave id */
shouldnt this be namespaced aptly

otherwise this looks okay, so can you rebase and resend

-- 
~Vinod
> +
>  #define DMAMUX_NR	2
>  
>  #define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
> @@ -147,6 +149,7 @@ struct fsl_edma_slave_config {
>  struct fsl_edma_chan {
>  	struct virt_dma_chan		vchan;
>  	enum dma_status			status;
> +	u32				slave_id;
>  	struct fsl_edma_engine		*edma;
>  	struct fsl_edma_desc		*edesc;
>  	struct fsl_edma_slave_config	fsc;
> @@ -637,6 +640,45 @@ static struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
>  	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
>  }
>  
> +static struct dma_async_tx_descriptor *
> +fsl_edma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst,
> +			dma_addr_t src, size_t len, unsigned long tx_flags)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct fsl_edma_desc *fsl_desc;
> +	u16 soff, doff, attr;
> +
> +	/*
> +	 * use 4-bytes data transfer size if all is 4-bytes aligned,
> +	 * else 2-bytes data transfer size of all is 2-bytes aligned,
> +	 * otherwise 1-byte tranfer size.
> +	 */
> +	if (src & 0x1 || dst & 0x1 || len & 0x1) {
> +		attr = EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
> +		soff = 0x1;
> +		doff = 0x1;
> +	} else if (src & 0x2 || dst & 0x2 || len & 0x2) {
> +		attr = EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
> +		soff = 0x2;
> +		doff = 0x2;
> +	} else {
> +		attr = EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
> +		soff = 0x4;
> +		doff = 0x4;
> +	}
> +
> +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
> +	if (!fsl_desc)
> +		return NULL;
> +	fsl_desc->iscyclic = false;
> +
> +	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, src, dst, attr, soff, len,
> +			  0, 1, 1, doff, 0, true, true, false);
> +
> +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, tx_flags);
> +
> +}
> +
>  static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
>  {
>  	struct virt_dma_desc *vdesc;
> @@ -735,6 +777,7 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
>  {
>  	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
>  	struct dma_chan *chan, *_chan;
> +	struct fsl_edma_chan *fsl_chan;
>  	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
>  
>  	if (dma_spec->args_count != 2)
> @@ -748,8 +791,10 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
>  			chan = dma_get_slave_channel(chan);
>  			if (chan) {
>  				chan->device->privatecnt++;
> -				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> -					dma_spec->args[1], true);
> +				fsl_chan = to_fsl_edma_chan(chan);
> +				fsl_chan->slave_id = dma_spec->args[1];
> +				fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id,
> +						  true);
>  				mutex_unlock(&fsl_edma->fsl_edma_mutex);
>  				return chan;
>  			}
> @@ -763,6 +808,17 @@ static int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
>  {
>  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
>  
> +	/*
> +	 * If the slave id of the channel DMAMUX is not set yet,
> +	 * this could happy when the channel is requested by the
> +	 * dma_request_channel() for memory copy purpose instead
> +	 * of by dts binding, then configure the DMAMUX with the
> +	 * always on slave id.
> +	 */
> +	if (fsl_chan->slave_id == 0) {
> +		fsl_chan->slave_id = SLAVE_ID_ALWAYSON;
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> +	}
>  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
>  				sizeof(struct fsl_edma_hw_tcd),
>  				32, 0);
> @@ -778,6 +834,7 @@ static void fsl_edma_free_chan_resources(struct dma_chan *chan)
>  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
>  	fsl_edma_disable_request(fsl_chan);
>  	fsl_edma_chan_mux(fsl_chan, 0, false);
> +	fsl_chan->slave_id = 0;
>  	fsl_chan->edesc = NULL;
>  	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
>  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> @@ -903,6 +960,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
>  	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
> +	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
>  
>  	fsl_edma->dma_dev.dev = &pdev->dev;
>  	fsl_edma->dma_dev.device_alloc_chan_resources
> @@ -912,6 +970,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
>  	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
>  	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
> +	fsl_edma->dma_dev.device_prep_dma_memcpy = fsl_edma_prep_memcpy;
>  	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
>  	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
>  	fsl_edma->dma_dev.device_resume = fsl_edma_resume;
> -- 
> 1.8.0
> 

-- 

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

* Re: [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
  2014-12-30  8:41   ` Jingchang Lu
@ 2015-03-05 10:41     ` Vinod Koul
  -1 siblings, 0 replies; 22+ messages in thread
From: Vinod Koul @ 2015-03-05 10:41 UTC (permalink / raw)
  To: Jingchang Lu, g; +Cc: dan.j.williams, dmaengine, linux-kernel, linux-arm-kernel

On Tue, Dec 30, 2014 at 04:41:47PM +0800, Jingchang Lu wrote:
> This adds power management suspend/resume support for
> the fsl-edma driver.
> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index e0bd517..6a81699 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int fsl_edma_pm_suspend(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		fsl_edma_chan_mux(fsl_chan, 0, false);
> +	}
> +
> +	return 0;
> +}
> +
> +static int fsl_edma_pm_resume(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i));
> +		/* restore the channel slave id configuration */
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
Wouldnt this be reconfigured? Should you do this for all channels or active
ones.
Also I dont see you pausing or suspending active channels or checking for
them?

-- 
~Vinod

> +	}
> +
> +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
> +		    fsl_edma->membase + EDMA_CR);
> +
> +	return 0;
> +}
> +#endif
> +static
> +SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend, fsl_edma_pm_resume);
> +
>  static const struct of_device_id fsl_edma_dt_ids[] = {
>  	{ .compatible = "fsl,vf610-edma", },
>  	{ /* sentinel */ }
> @@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
>  	.driver		= {
>  		.name	= "fsl-edma",
>  		.of_match_table = fsl_edma_dt_ids,
> +		.pm	= &fsl_edma_pm_ops,
>  	},
>  	.probe          = fsl_edma_probe,
>  	.remove		= fsl_edma_remove,
> -- 
> 1.8.0
> 

-- 

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

* [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
@ 2015-03-05 10:41     ` Vinod Koul
  0 siblings, 0 replies; 22+ messages in thread
From: Vinod Koul @ 2015-03-05 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 30, 2014 at 04:41:47PM +0800, Jingchang Lu wrote:
> This adds power management suspend/resume support for
> the fsl-edma driver.
> 
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> index e0bd517..6a81699 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int fsl_edma_pm_suspend(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		fsl_edma_chan_mux(fsl_chan, 0, false);
> +	}
> +
> +	return 0;
> +}
> +
> +static int fsl_edma_pm_resume(struct device *dev)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		edma_writew(fsl_edma, 0x0, fsl_edma->membase + EDMA_TCD_CSR(i));
> +		/* restore the channel slave id configuration */
> +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
Wouldnt this be reconfigured? Should you do this for all channels or active
ones.
Also I dont see you pausing or suspending active channels or checking for
them?

-- 
~Vinod

> +	}
> +
> +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
> +		    fsl_edma->membase + EDMA_CR);
> +
> +	return 0;
> +}
> +#endif
> +static
> +SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend, fsl_edma_pm_resume);
> +
>  static const struct of_device_id fsl_edma_dt_ids[] = {
>  	{ .compatible = "fsl,vf610-edma", },
>  	{ /* sentinel */ }
> @@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
>  	.driver		= {
>  		.name	= "fsl-edma",
>  		.of_match_table = fsl_edma_dt_ids,
> +		.pm	= &fsl_edma_pm_ops,
>  	},
>  	.probe          = fsl_edma_probe,
>  	.remove		= fsl_edma_remove,
> -- 
> 1.8.0
> 

-- 

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

* [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
       [not found] <BL2PR03MB33868673832B44DD03ED841839B0@BL2PR03MB338.namprd03.prod.outlook.com>
@ 2015-07-15  9:29 ` Yao Yuan
  0 siblings, 0 replies; 22+ messages in thread
From: Yao Yuan @ 2015-07-15  9:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod,

Thanks for your review, now I will take over the eDMA.
I have some different in understanding with PM suspend/resume support. And I will send a patch for RFC later.
Also please check my comment in line for this patch.
I hope you can help to review it for me.

Thanks.

Best Regards,
Yuan Yao

On 2015-5-5 18:35, Vinod Koul wrote:
> On 2014-12-30 09:41, Jingchang Lu wrote:
> > This adds power management suspend/resume support for the fsl-edma
> > driver.
> >
> > Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> > ---
> >  drivers/dma/fsl-edma.c | 38
> ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index
> > e0bd517..6a81699 100644
> > --- a/drivers/dma/fsl-edma.c
> > +++ b/drivers/dma/fsl-edma.c
> > @@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct
> platform_device *pdev)
> >  	return 0;
> >  }
> >
> > +#ifdef CONFIG_PM_SLEEP
> > +static int fsl_edma_pm_suspend(struct device *dev) {
> > +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> > +	struct fsl_edma_chan *fsl_chan;
> > +	int i;
> > +
> > +	for (i = 0; i < fsl_edma->n_chans; i++) {
> > +		fsl_chan = &fsl_edma->chans[i];
> > +		fsl_edma_chan_mux(fsl_chan, 0, false);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int fsl_edma_pm_resume(struct device *dev) {
> > +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> > +	struct fsl_edma_chan *fsl_chan;
> > +	int i;
> > +
> > +	for (i = 0; i < fsl_edma->n_chans; i++) {
> > +		fsl_chan = &fsl_edma->chans[i];
> > +		edma_writew(fsl_edma, 0x0, fsl_edma->membase +
> EDMA_TCD_CSR(i));
> 
> What is the expectation of the suspend mode, are the registers and descriptors
> cleared during suspend? So this makes sure we have all descriptors disabled on
> wake-up, right?
Yes, suspend mode will power down the eDMA controller.

> 
> > +		/* restore the channel slave id configuration */
> > +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> 
> And here the channel gets muxed again.
> 
> But the user is expected to reconfigure a channel, e.g. using
> dmaengine_slave_config and the dmaengine_prep*? Also and cyclic DMA
> which has been paused before would be interrupted, is this correct?

No, In fact the channel in eDMA is a little different form the other channel. Every IP just have only one channel. The IP should get his corresponding channel when boot up and release it until power down or IP removed.

> I don't know what the common exception of the API is, I'm just asking so I now
> what I can expect when using the DMA driver in other device drivers...
> 
> --
> Stefan
> 
> > +	}
> > +
> > +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
> > +		    fsl_edma->membase + EDMA_CR);
> > +
> > +	return 0;
> > +}
> > +#endif
> > +static
> > +SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend,
> > +fsl_edma_pm_resume);
> > +
> >  static const struct of_device_id fsl_edma_dt_ids[] = {
> >  	{ .compatible = "fsl,vf610-edma", },
> >  	{ /* sentinel */ }
> > @@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
> >  	.driver		= {
> >  		.name	= "fsl-edma",
> >  		.of_match_table = fsl_edma_dt_ids,
> > +		.pm	= &fsl_edma_pm_ops,
> >  	},
> >  	.probe          = fsl_edma_probe,
> >  	.remove		= fsl_edma_remove,
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support
       [not found] <BL2PR03MB3383F18A5096A989DF7DE8F839B0@BL2PR03MB338.namprd03.prod.outlook.com>
@ 2015-07-15  9:23 ` Yao Yuan
  0 siblings, 0 replies; 22+ messages in thread
From: Yao Yuan @ 2015-07-15  9:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stefan,

Thanks for your review, now I will take over the eDMA.
I have some different in understanding with PM suspend/resume support. And I will send a patch for RFC later.
Also please check my comment in line for this patch.
I hope you can help to review it for me.

Thanks.

Best Regards,
Yuan Yao

On 2015-1-30 21:01,  Stefan Agner wrote:
> On Tue, Dec 30, 2014 at 04:41:47PM +0800, Jingchang Lu wrote:
> > This adds power management suspend/resume support for the fsl-edma
> > driver.
> >
> > Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
> > ---
> >  drivers/dma/fsl-edma.c | 38
> ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index
> > e0bd517..6a81699 100644
> > --- a/drivers/dma/fsl-edma.c
> > +++ b/drivers/dma/fsl-edma.c
> > @@ -1017,6 +1017,43 @@ static int fsl_edma_remove(struct
> platform_device *pdev)
> >  	return 0;
> >  }
> >
> > +#ifdef CONFIG_PM_SLEEP
> > +static int fsl_edma_pm_suspend(struct device *dev) {
> > +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> > +	struct fsl_edma_chan *fsl_chan;
> > +	int i;
> > +
> > +	for (i = 0; i < fsl_edma->n_chans; i++) {
> > +		fsl_chan = &fsl_edma->chans[i];
> > +		fsl_edma_chan_mux(fsl_chan, 0, false);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int fsl_edma_pm_resume(struct device *dev) {
> > +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> > +	struct fsl_edma_chan *fsl_chan;
> > +	int i;
> > +
> > +	for (i = 0; i < fsl_edma->n_chans; i++) {
> > +		fsl_chan = &fsl_edma->chans[i];
> > +		edma_writew(fsl_edma, 0x0, fsl_edma->membase +
> EDMA_TCD_CSR(i));
> > +		/* restore the channel slave id configuration */
> > +		fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
> Wouldnt this be reconfigured? Should you do this for all channels or active ones.
> Also I dont see you pausing or suspending active channels or checking for them?
> 
No, here is no need more reconfigured. I will send a new patch for what your consideration.
Thanks.

> --
> ~Vinod
> 
> > +	}
> > +
> > +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
> > +		    fsl_edma->membase + EDMA_CR);
> > +
> > +	return 0;
> > +}
> > +#endif
> > +static
> > +SIMPLE_DEV_PM_OPS(fsl_edma_pm_ops, fsl_edma_pm_suspend,
> > +fsl_edma_pm_resume);
> > +
> >  static const struct of_device_id fsl_edma_dt_ids[] = {
> >  	{ .compatible = "fsl,vf610-edma", },
> >  	{ /* sentinel */ }
> > @@ -1027,6 +1064,7 @@ static struct platform_driver fsl_edma_driver = {
> >  	.driver		= {
> >  		.name	= "fsl-edma",
> >  		.of_match_table = fsl_edma_dt_ids,
> > +		.pm	= &fsl_edma_pm_ops,
> >  	},
> >  	.probe          = fsl_edma_probe,
> >  	.remove		= fsl_edma_remove,
> > --
> > 1.8.0
> >
> 
> --
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2015-07-15  9:29 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-30  8:41 [PATCH 0/2] dmaengine: fsl-edma: add dma memcpy and suspend/resume support Jingchang Lu
2014-12-30  8:41 ` Jingchang Lu
2014-12-30  8:41 ` [PATCH 1/2] dmaengine: fsl-edma: add dma memcpy support Jingchang Lu
2014-12-30  8:41   ` Jingchang Lu
2015-01-14  9:36   ` Jingchang Lu
2015-01-14  9:36     ` Jingchang Lu
2015-01-30  9:00     ` Yao Yuan
2015-01-30  9:00       ` Yao Yuan
2015-01-30 12:39   ` Stefan Agner
2015-01-30 12:39     ` Stefan Agner
2015-02-11  8:06     ` Yao Yuan
2015-02-11  8:06       ` Yao Yuan
2015-03-05 10:39   ` Vinod Koul
2015-03-05 10:39     ` Vinod Koul
2014-12-30  8:41 ` [PATCH 2/2] dmaengine: fsl-edma: add PM suspend/resume support Jingchang Lu
2014-12-30  8:41   ` Jingchang Lu
2015-01-30 13:05   ` Stefan Agner
2015-01-30 13:05     ` Stefan Agner
2015-03-05 10:41   ` Vinod Koul
2015-03-05 10:41     ` Vinod Koul
     [not found] <BL2PR03MB3383F18A5096A989DF7DE8F839B0@BL2PR03MB338.namprd03.prod.outlook.com>
2015-07-15  9:23 ` Yao Yuan
     [not found] <BL2PR03MB33868673832B44DD03ED841839B0@BL2PR03MB338.namprd03.prod.outlook.com>
2015-07-15  9:29 ` Yao Yuan

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.