All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] ARM: S5P: Use generic DMA APIs
@ 2011-07-04 12:18 ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown

This patch makes EXYNOS4210 SoC use generic DMA APIs instead of
Samsung specific DMA APIs. The DMA client drivers such as spi and
sound are requried to change the usage for it.

NOTE: We will also apply this on other S5P SoCs soon so we can
remove s3c-pl330 specific driver at the same time.

[PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
[PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
[PATCH 3/7] DMA: PL330: Add DMA capabilities
[PATCH 4/7] ARM: SAMSUNG: Update to use PL330-DMA driver
[PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
[PATCH 6/7] spi/s3c64xx: Add support DMA engine API
[PATCH 7/7] ASoC: Samsung: Update DMA interface

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

* [PATCH 0/7] ARM: S5P: Use generic DMA APIs
@ 2011-07-04 12:18 ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

This patch makes EXYNOS4210 SoC use generic DMA APIs instead of
Samsung specific DMA APIs. The DMA client drivers such as spi and
sound are requried to change the usage for it.

NOTE: We will also apply this on other S5P SoCs soon so we can
remove s3c-pl330 specific driver at the same time.

[PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
[PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
[PATCH 3/7] DMA: PL330: Add DMA capabilities
[PATCH 4/7] ARM: SAMSUNG: Update to use PL330-DMA driver
[PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
[PATCH 6/7] spi/s3c64xx: Add support DMA engine API
[PATCH 7/7] ASoC: Samsung: Update DMA interface

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

* [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
  2011-07-04 12:18 ` Kukjin Kim
@ 2011-07-04 12:18   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown, Boojin Kim, Kukjin Kim

From: Boojin Kim <boojin.kim@samsung.com>

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/dma/pl330.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 6abe1ec..7bd72e9 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl330.h>
+#include <linux/pm_runtime.h>
 
 #define NR_DEFAULT_DESC	16
 
@@ -666,6 +667,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	struct dma_device *pd;
 	struct resource *res;
 	int i, ret, irq;
+	struct clk* clk;
 
 	pdat = adev->dev.platform_data;
 
@@ -696,6 +698,28 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		goto probe_err1;
 	}
 
+#ifdef CONFIG_PM_RUNTIME
+	/* to use the runtime PM helper functions */
+	pm_runtime_enable(&adev->dev);
+
+	/* enable the power domain */
+	if (pm_runtime_get_sync(&adev->dev)) {
+		dev_err(&adev->dev, "failed to get runtime pm\n");
+		ret = -ENODEV;
+		goto probe_err1;
+	}
+#else
+	/* enable dma clk */
+	clk = clk_get(&adev->dev, "dma");
+
+	if (IS_ERR(clk)) {
+		dev_err(&adev->dev, "Cannot get operation clock.\n");
+		ret = -EINVAL;
+		goto probe_err1;
+	}
+	clk_enable(clk);
+#endif
+
 	irq = adev->irq[0];
 	ret = request_irq(irq, pl330_irq_handler, 0,
 			dev_name(&adev->dev), pi);
@@ -838,10 +862,47 @@ static struct amba_id pl330_ids[] = {
 	{ 0, 0 },
 };
 
+#ifdef CONFIG_PM_RUNTIME
+static int pl330_runtime_suspend(struct device *dev)
+{
+	struct clk *dmaclk = clk_get(dev, "dma");
+
+	if (dmaclk == NULL) {
+		dev_err(dev, "failed to find dma clock source\n");
+		return -ENODEV;
+	}
+
+	clk_disable(dmaclk);
+	return 0;
+}
+
+static int pl330_runtime_resume(struct device *dev)
+{
+	struct clk *dmaclk = clk_get(dev, "dma");
+
+	if (dmaclk == NULL) {
+		dev_err(dev, "failed to find dma clock source\n");
+		return -ENODEV;
+	}
+
+	clk_enable(dmaclk);
+	return 0;
+}
+#else
+#define pl330_runtime_suspend	NULL
+#define pl330_runtime_resume	NULL
+#endif /* CONFIG_PM_RUNTIME */
+
+static const struct dev_pm_ops pl330_pm_ops = {
+	.runtime_suspend = pl330_runtime_suspend,
+	.runtime_resume = pl330_runtime_resume,
+};
+
 static struct amba_driver pl330_driver = {
 	.drv = {
 		.owner = THIS_MODULE,
 		.name = "dma-pl330",
+		.pm = &pl330_pm_ops,
 	},
 	.id_table = pl330_ids,
 	.probe = pl330_probe,
-- 
1.7.1

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

* [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
@ 2011-07-04 12:18   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Boojin Kim <boojin.kim@samsung.com>

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/dma/pl330.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 6abe1ec..7bd72e9 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl330.h>
+#include <linux/pm_runtime.h>
 
 #define NR_DEFAULT_DESC	16
 
@@ -666,6 +667,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	struct dma_device *pd;
 	struct resource *res;
 	int i, ret, irq;
+	struct clk* clk;
 
 	pdat = adev->dev.platform_data;
 
@@ -696,6 +698,28 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		goto probe_err1;
 	}
 
+#ifdef CONFIG_PM_RUNTIME
+	/* to use the runtime PM helper functions */
+	pm_runtime_enable(&adev->dev);
+
+	/* enable the power domain */
+	if (pm_runtime_get_sync(&adev->dev)) {
+		dev_err(&adev->dev, "failed to get runtime pm\n");
+		ret = -ENODEV;
+		goto probe_err1;
+	}
+#else
+	/* enable dma clk */
+	clk = clk_get(&adev->dev, "dma");
+
+	if (IS_ERR(clk)) {
+		dev_err(&adev->dev, "Cannot get operation clock.\n");
+		ret = -EINVAL;
+		goto probe_err1;
+	}
+	clk_enable(clk);
+#endif
+
 	irq = adev->irq[0];
 	ret = request_irq(irq, pl330_irq_handler, 0,
 			dev_name(&adev->dev), pi);
@@ -838,10 +862,47 @@ static struct amba_id pl330_ids[] = {
 	{ 0, 0 },
 };
 
+#ifdef CONFIG_PM_RUNTIME
+static int pl330_runtime_suspend(struct device *dev)
+{
+	struct clk *dmaclk = clk_get(dev, "dma");
+
+	if (dmaclk == NULL) {
+		dev_err(dev, "failed to find dma clock source\n");
+		return -ENODEV;
+	}
+
+	clk_disable(dmaclk);
+	return 0;
+}
+
+static int pl330_runtime_resume(struct device *dev)
+{
+	struct clk *dmaclk = clk_get(dev, "dma");
+
+	if (dmaclk == NULL) {
+		dev_err(dev, "failed to find dma clock source\n");
+		return -ENODEV;
+	}
+
+	clk_enable(dmaclk);
+	return 0;
+}
+#else
+#define pl330_runtime_suspend	NULL
+#define pl330_runtime_resume	NULL
+#endif /* CONFIG_PM_RUNTIME */
+
+static const struct dev_pm_ops pl330_pm_ops = {
+	.runtime_suspend = pl330_runtime_suspend,
+	.runtime_resume = pl330_runtime_resume,
+};
+
 static struct amba_driver pl330_driver = {
 	.drv = {
 		.owner = THIS_MODULE,
 		.name = "dma-pl330",
+		.pm = &pl330_pm_ops,
 	},
 	.id_table = pl330_ids,
 	.probe = pl330_probe,
-- 
1.7.1

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

* [PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
  2011-07-04 12:18 ` Kukjin Kim
@ 2011-07-04 12:18   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown, Boojin Kim, Kukjin Kim

From: Boojin Kim <boojin.kim@samsung.com>

This patch updates following 3 items.
1. Removes unneccessary code.
2. Add AMBA, PL330 configuration
3. Change the meaning of 'peri_id' variable
   from PL330 event number to specific dma id by user.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/dma/Kconfig        |    3 ++-
 drivers/dma/pl330.c        |   31 ++++++++++++++++---------------
 include/linux/amba/pl330.h |    2 +-
 3 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 25cf327..9b7f15a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
 config PL330_DMA
 	tristate "DMA API Driver for PL330"
 	select DMA_ENGINE
-	depends on PL330
+	select ARM_AMBA
+	select PL330
 	help
 	  Select if your platform has one or more PL330 DMACs.
 	  You need to provide platform specific settings via
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 7bd72e9..0f80af8 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -453,7 +453,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 	async_tx_ack(&desc->txd);
 
 	desc->req.rqtype = peri->rqtype;
-	desc->req.peri = peri->peri_id;
+	desc->req.peri = pch->chan.chan_id;
 
 	dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
 
@@ -575,7 +575,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	struct dma_pl330_peri *peri = chan->private;
 	struct scatterlist *sg;
 	unsigned long flags;
-	int i, burst_size;
+	int i;
 	dma_addr_t addr;
 
 	if (unlikely(!pch || !sgl || !sg_len))
@@ -592,7 +592,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	}
 
 	addr = peri->fifo_addr;
-	burst_size = peri->burst_sz;
 
 	first = NULL;
 
@@ -640,7 +639,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 				sg_dma_address(sg), addr, sg_dma_len(sg));
 		}
 
-		desc->rqcfg.brst_size = burst_size;
+		desc->rqcfg.brst_size = peri->burst_sz;
 		desc->rqcfg.brst_len = 1;
 	}
 
@@ -745,17 +744,19 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		struct dma_pl330_peri *peri = &pdat->peri[i];
 		pch = &pdmac->peripherals[i];
 
-		switch (peri->rqtype) {
-		case MEMTOMEM:
-			dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-			break;
-		case MEMTODEV:
-		case DEVTOMEM:
-			dma_cap_set(DMA_SLAVE, pd->cap_mask);
-			break;
-		default:
-			dev_err(&adev->dev, "DEVTODEV Not Supported\n");
-			continue;
+		if (peri) {
+			switch (peri->rqtype) {
+			case MEMTOMEM:
+				dma_cap_set(DMA_MEMCPY, pd->cap_mask);
+				break;
+			case MEMTODEV:
+			case DEVTOMEM:
+				dma_cap_set(DMA_SLAVE, pd->cap_mask);
+				break;
+			default:
+				dev_err(&adev->dev, "DEVTODEV Not Supported\n");
+				continue;
+			}
 		}
 
 		INIT_LIST_HEAD(&pch->work_list);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index cbee7de..17b0ada 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -19,7 +19,7 @@ struct dma_pl330_peri {
 	 * Peri_Req i/f of the DMAC that is
 	 * peripheral could be reached from.
 	 */
-	u8 peri_id; /* {0, 31} */
+	u8 peri_id; /* specific dma id */
 	enum pl330_reqtype rqtype;
 
 	/* For M->D and D->M Channels */
-- 
1.7.1

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

* [PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
@ 2011-07-04 12:18   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Boojin Kim <boojin.kim@samsung.com>

This patch updates following 3 items.
1. Removes unneccessary code.
2. Add AMBA, PL330 configuration
3. Change the meaning of 'peri_id' variable
   from PL330 event number to specific dma id by user.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/dma/Kconfig        |    3 ++-
 drivers/dma/pl330.c        |   31 ++++++++++++++++---------------
 include/linux/amba/pl330.h |    2 +-
 3 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 25cf327..9b7f15a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
 config PL330_DMA
 	tristate "DMA API Driver for PL330"
 	select DMA_ENGINE
-	depends on PL330
+	select ARM_AMBA
+	select PL330
 	help
 	  Select if your platform has one or more PL330 DMACs.
 	  You need to provide platform specific settings via
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 7bd72e9..0f80af8 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -453,7 +453,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 	async_tx_ack(&desc->txd);
 
 	desc->req.rqtype = peri->rqtype;
-	desc->req.peri = peri->peri_id;
+	desc->req.peri = pch->chan.chan_id;
 
 	dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
 
@@ -575,7 +575,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	struct dma_pl330_peri *peri = chan->private;
 	struct scatterlist *sg;
 	unsigned long flags;
-	int i, burst_size;
+	int i;
 	dma_addr_t addr;
 
 	if (unlikely(!pch || !sgl || !sg_len))
@@ -592,7 +592,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	}
 
 	addr = peri->fifo_addr;
-	burst_size = peri->burst_sz;
 
 	first = NULL;
 
@@ -640,7 +639,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 				sg_dma_address(sg), addr, sg_dma_len(sg));
 		}
 
-		desc->rqcfg.brst_size = burst_size;
+		desc->rqcfg.brst_size = peri->burst_sz;
 		desc->rqcfg.brst_len = 1;
 	}
 
@@ -745,17 +744,19 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		struct dma_pl330_peri *peri = &pdat->peri[i];
 		pch = &pdmac->peripherals[i];
 
-		switch (peri->rqtype) {
-		case MEMTOMEM:
-			dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-			break;
-		case MEMTODEV:
-		case DEVTOMEM:
-			dma_cap_set(DMA_SLAVE, pd->cap_mask);
-			break;
-		default:
-			dev_err(&adev->dev, "DEVTODEV Not Supported\n");
-			continue;
+		if (peri) {
+			switch (peri->rqtype) {
+			case MEMTOMEM:
+				dma_cap_set(DMA_MEMCPY, pd->cap_mask);
+				break;
+			case MEMTODEV:
+			case DEVTOMEM:
+				dma_cap_set(DMA_SLAVE, pd->cap_mask);
+				break;
+			default:
+				dev_err(&adev->dev, "DEVTODEV Not Supported\n");
+				continue;
+			}
 		}
 
 		INIT_LIST_HEAD(&pch->work_list);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index cbee7de..17b0ada 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -19,7 +19,7 @@ struct dma_pl330_peri {
 	 * Peri_Req i/f of the DMAC that is
 	 * peripheral could be reached from.
 	 */
-	u8 peri_id; /* {0, 31} */
+	u8 peri_id; /* specific dma id */
 	enum pl330_reqtype rqtype;
 
 	/* For M->D and D->M Channels */
-- 
1.7.1

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-04 12:18 ` Kukjin Kim
@ 2011-07-04 12:18   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown, Boojin Kim, Kukjin Kim

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds DMA_CYCLIC capability that is used for audio driver
and SLAVE_CONFIG capability for transmit between device and memory.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/dma/pl330.c |  114 ++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 100 insertions(+), 14 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 0f80af8..e2a59c2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -254,25 +254,58 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
 static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_desc *desc;
+	struct dma_pl330_desc *desc, *_dt;
 	unsigned long flags;
+	struct dma_pl330_dmac *pdmac = pch->dmac;
+	struct dma_slave_config *slave_config;
+	struct dma_pl330_peri *peri;
+	int i;
+	LIST_HEAD(list);
 
-	/* Only supports DMA_TERMINATE_ALL */
-	if (cmd != DMA_TERMINATE_ALL)
-		return -ENXIO;
-
-	spin_lock_irqsave(&pch->lock, flags);
-
-	/* FLUSH the PL330 Channel thread */
-	pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
+	switch (cmd) {
+	case DMA_TERMINATE_ALL:
+		spin_lock_irqsave(&pch->lock, flags);
 
-	/* Mark all desc done */
-	list_for_each_entry(desc, &pch->work_list, node)
-		desc->status = DONE;
+		/* FLUSH the PL330 Channel thread */
+		pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
 
-	spin_unlock_irqrestore(&pch->lock, flags);
+		/* Mark all desc done */
+		list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
+			desc->status = DONE;
+			pch->completed = desc->txd.cookie;
+			list_move_tail(&desc->node, &list);
+		}
 
-	pl330_tasklet((unsigned long) pch);
+		list_splice_tail_init(&list, &pdmac->desc_pool);
+		spin_unlock_irqrestore(&pch->lock, flags);
+		break;
+	case DMA_SLAVE_CONFIG:
+		slave_config = (struct dma_slave_config *)arg;
+		peri = pch->chan.private;
+
+		if (slave_config->direction == DMA_TO_DEVICE) {
+			if (slave_config->dst_addr)
+				peri->fifo_addr = slave_config->dst_addr;
+			if (slave_config->dst_addr_width) {
+				i = 0;
+				while (slave_config->dst_addr_width != (1 << i))
+					i++;
+				peri->burst_sz = i;
+			}
+		} else if (slave_config->direction == DMA_FROM_DEVICE) {
+			if (slave_config->src_addr)
+				peri->fifo_addr = slave_config->src_addr;
+			if (slave_config->src_addr_width) {
+				i = 0;
+				while (slave_config->src_addr_width != (1 << i))
+					i++;
+				peri->burst_sz = i;
+			}
+		}
+		break;
+	default:
+		return -ENXIO;
+	}
 
 	return 0;
 }
@@ -520,6 +553,57 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len)
 	return burst_len;
 }
 
+static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
+		struct dma_chan *chan, dma_addr_t dma_addr, size_t len,
+		size_t period_len, enum dma_data_direction direction)
+{
+	struct dma_pl330_desc *desc;
+	struct dma_pl330_chan *pch = to_pchan(chan);
+	struct dma_pl330_peri *peri = chan->private;
+	dma_addr_t dst;
+	dma_addr_t src;
+
+	pch = to_pchan(chan);
+	if (!pch) {
+		dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
+			__func__, __LINE__);
+		return NULL;
+	}
+
+	desc = pl330_get_desc(pch);
+	if (!desc) {
+		dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
+			__func__, __LINE__);
+		return NULL;
+	}
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		desc->rqcfg.src_inc = 1;
+		desc->rqcfg.dst_inc = 0;
+		src = dma_addr;
+		dst = peri->fifo_addr;
+		break;
+	case DMA_FROM_DEVICE:
+		desc->rqcfg.src_inc = 0;
+		desc->rqcfg.dst_inc = 1;
+		src = peri->fifo_addr;
+		dst = dma_addr;
+		break;
+	default:
+		dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
+		__func__, __LINE__);
+		return NULL;
+	}
+
+	desc->rqcfg.brst_size = peri->burst_sz;
+	desc->rqcfg.brst_len = 1;
+
+	fill_px(&desc->px, dst, src, period_len);
+
+	return &desc->txd;
+}
+
 static struct dma_async_tx_descriptor *
 pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 		dma_addr_t src, size_t len, unsigned long flags)
@@ -752,6 +836,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 			case MEMTODEV:
 			case DEVTOMEM:
 				dma_cap_set(DMA_SLAVE, pd->cap_mask);
+				dma_cap_set(DMA_CYCLIC, pd->cap_mask);
 				break;
 			default:
 				dev_err(&adev->dev, "DEVTODEV Not Supported\n");
@@ -777,6 +862,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
 	pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;
+	pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic;
 	pd->device_tx_status = pl330_tx_status;
 	pd->device_prep_slave_sg = pl330_prep_slave_sg;
 	pd->device_control = pl330_control;
-- 
1.7.1

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-04 12:18   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds DMA_CYCLIC capability that is used for audio driver
and SLAVE_CONFIG capability for transmit between device and memory.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/dma/pl330.c |  114 ++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 100 insertions(+), 14 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 0f80af8..e2a59c2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -254,25 +254,58 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
 static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_desc *desc;
+	struct dma_pl330_desc *desc, *_dt;
 	unsigned long flags;
+	struct dma_pl330_dmac *pdmac = pch->dmac;
+	struct dma_slave_config *slave_config;
+	struct dma_pl330_peri *peri;
+	int i;
+	LIST_HEAD(list);
 
-	/* Only supports DMA_TERMINATE_ALL */
-	if (cmd != DMA_TERMINATE_ALL)
-		return -ENXIO;
-
-	spin_lock_irqsave(&pch->lock, flags);
-
-	/* FLUSH the PL330 Channel thread */
-	pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
+	switch (cmd) {
+	case DMA_TERMINATE_ALL:
+		spin_lock_irqsave(&pch->lock, flags);
 
-	/* Mark all desc done */
-	list_for_each_entry(desc, &pch->work_list, node)
-		desc->status = DONE;
+		/* FLUSH the PL330 Channel thread */
+		pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
 
-	spin_unlock_irqrestore(&pch->lock, flags);
+		/* Mark all desc done */
+		list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
+			desc->status = DONE;
+			pch->completed = desc->txd.cookie;
+			list_move_tail(&desc->node, &list);
+		}
 
-	pl330_tasklet((unsigned long) pch);
+		list_splice_tail_init(&list, &pdmac->desc_pool);
+		spin_unlock_irqrestore(&pch->lock, flags);
+		break;
+	case DMA_SLAVE_CONFIG:
+		slave_config = (struct dma_slave_config *)arg;
+		peri = pch->chan.private;
+
+		if (slave_config->direction == DMA_TO_DEVICE) {
+			if (slave_config->dst_addr)
+				peri->fifo_addr = slave_config->dst_addr;
+			if (slave_config->dst_addr_width) {
+				i = 0;
+				while (slave_config->dst_addr_width != (1 << i))
+					i++;
+				peri->burst_sz = i;
+			}
+		} else if (slave_config->direction == DMA_FROM_DEVICE) {
+			if (slave_config->src_addr)
+				peri->fifo_addr = slave_config->src_addr;
+			if (slave_config->src_addr_width) {
+				i = 0;
+				while (slave_config->src_addr_width != (1 << i))
+					i++;
+				peri->burst_sz = i;
+			}
+		}
+		break;
+	default:
+		return -ENXIO;
+	}
 
 	return 0;
 }
@@ -520,6 +553,57 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len)
 	return burst_len;
 }
 
+static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
+		struct dma_chan *chan, dma_addr_t dma_addr, size_t len,
+		size_t period_len, enum dma_data_direction direction)
+{
+	struct dma_pl330_desc *desc;
+	struct dma_pl330_chan *pch = to_pchan(chan);
+	struct dma_pl330_peri *peri = chan->private;
+	dma_addr_t dst;
+	dma_addr_t src;
+
+	pch = to_pchan(chan);
+	if (!pch) {
+		dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
+			__func__, __LINE__);
+		return NULL;
+	}
+
+	desc = pl330_get_desc(pch);
+	if (!desc) {
+		dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
+			__func__, __LINE__);
+		return NULL;
+	}
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		desc->rqcfg.src_inc = 1;
+		desc->rqcfg.dst_inc = 0;
+		src = dma_addr;
+		dst = peri->fifo_addr;
+		break;
+	case DMA_FROM_DEVICE:
+		desc->rqcfg.src_inc = 0;
+		desc->rqcfg.dst_inc = 1;
+		src = peri->fifo_addr;
+		dst = dma_addr;
+		break;
+	default:
+		dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
+		__func__, __LINE__);
+		return NULL;
+	}
+
+	desc->rqcfg.brst_size = peri->burst_sz;
+	desc->rqcfg.brst_len = 1;
+
+	fill_px(&desc->px, dst, src, period_len);
+
+	return &desc->txd;
+}
+
 static struct dma_async_tx_descriptor *
 pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 		dma_addr_t src, size_t len, unsigned long flags)
@@ -752,6 +836,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 			case MEMTODEV:
 			case DEVTOMEM:
 				dma_cap_set(DMA_SLAVE, pd->cap_mask);
+				dma_cap_set(DMA_CYCLIC, pd->cap_mask);
 				break;
 			default:
 				dev_err(&adev->dev, "DEVTODEV Not Supported\n");
@@ -777,6 +862,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
 	pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;
+	pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic;
 	pd->device_tx_status = pl330_tx_status;
 	pd->device_prep_slave_sg = pl330_prep_slave_sg;
 	pd->device_control = pl330_control;
-- 
1.7.1

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

* [PATCH 4/7] ARM: SAMSUNG: Update to use PL330-DMA driver
  2011-07-04 12:18 ` Kukjin Kim
@ 2011-07-04 12:18   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown, Boojin Kim, Kukjin Kim

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds to support PL330-DMA driver on DMADEVICE. Currently
S3C-DMA(PL080) is used for S3C24XX and S3C64XX and S3C-PL330-DMA has
been used for S5P SoCs. So this patch changes S3C-PL330-DMA to just
PL330-DMA for use generic DMA driver for S5P SoCs.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-exynos4/include/mach/dma.h           |    4 ++--
 arch/arm/mach-s5p64x0/include/mach/dma.h           |    2 +-
 arch/arm/mach-s5pc100/include/mach/dma.h           |    2 +-
 arch/arm/mach-s5pv210/include/mach/dma.h           |    2 +-
 arch/arm/plat-samsung/Kconfig                      |    7 +++++++
 .../include/plat/{s3c-dma-pl330.h => dma-pl330.h}  |   18 +++++++++++++++---
 .../plat-samsung/include/plat/s3c-pl330-pdata.h    |    2 +-
 7 files changed, 28 insertions(+), 9 deletions(-)
 rename arch/arm/plat-samsung/include/plat/{s3c-dma-pl330.h => dma-pl330.h} (87%)

diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos4/include/mach/dma.h
index 81209eb..201842a 100644
--- a/arch/arm/mach-exynos4/include/mach/dma.h
+++ b/arch/arm/mach-exynos4/include/mach/dma.h
@@ -20,7 +20,7 @@
 #ifndef __MACH_DMA_H
 #define __MACH_DMA_H
 
-/* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+/* This platform uses the common DMA API driver for PL330 */
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h
index 81209eb..1beae2c 100644
--- a/arch/arm/mach-s5p64x0/include/mach/dma.h
+++ b/arch/arm/mach-s5p64x0/include/mach/dma.h
@@ -21,6 +21,6 @@
 #define __MACH_DMA_H
 
 /* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/dma.h b/arch/arm/mach-s5pc100/include/mach/dma.h
index 81209eb..1beae2c 100644
--- a/arch/arm/mach-s5pc100/include/mach/dma.h
+++ b/arch/arm/mach-s5pc100/include/mach/dma.h
@@ -21,6 +21,6 @@
 #define __MACH_DMA_H
 
 /* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h
index 81209eb..1beae2c 100644
--- a/arch/arm/mach-s5pv210/include/mach/dma.h
+++ b/arch/arm/mach-s5pv210/include/mach/dma.h
@@ -21,6 +21,6 @@
 #define __MACH_DMA_H
 
 /* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 4d79519..4dc914e 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -300,6 +300,13 @@ config S3C_PL330_DMA
 	help
 	  S3C DMA API Driver for PL330 DMAC.
 
+config DMADEV_PL330
+	bool
+	select DMADEVICES
+	select PL330_DMA
+	help
+	  Use DMA device engine for PL330 DMAC.
+
 comment "Power management"
 
 config SAMSUNG_PM_DEBUG
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
similarity index 87%
rename from arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
rename to arch/arm/plat-samsung/include/plat/dma-pl330.h
index 8107442..1122c8b 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -8,11 +8,13 @@
  * (at your option) any later version.
  */
 
-#ifndef	__S3C_DMA_PL330_H_
-#define	__S3C_DMA_PL330_H_
+#ifndef __DMA_PL330_H_
+#define __DMA_PL330_H_ __FILE__
 
+#if !defined(CONFIG_DMADEV_PL330)
 #define S3C2410_DMAF_AUTOSTART		(1 << 0)
 #define S3C2410_DMAF_CIRCULAR		(1 << 1)
+#endif
 
 /*
  * PL330 can assign any channel to communicate with
@@ -84,6 +86,14 @@ enum dma_ch {
 	DMACH_SLIMBUS4_TX,
 	DMACH_SLIMBUS5_RX,
 	DMACH_SLIMBUS5_TX,
+	DMACH_MTOM_0,
+	DMACH_MTOM_1,
+	DMACH_MTOM_2,
+	DMACH_MTOM_3,
+	DMACH_MTOM_4,
+	DMACH_MTOM_5,
+	DMACH_MTOM_6,
+	DMACH_MTOM_7,
 	/* END Marker, also used to denote a reserved channel */
 	DMACH_MAX,
 };
@@ -93,6 +103,8 @@ static inline bool s3c_dma_has_circular(void)
 	return true;
 }
 
+#if !defined(CONFIG_DMADEV_PL330)
 #include <plat/dma.h>
+#endif
 
-#endif	/* __S3C_DMA_PL330_H_ */
+#endif	/* __DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
index bf5e2a9..64fdf66 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
+++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
@@ -12,7 +12,7 @@
 #ifndef __S3C_PL330_PDATA_H
 #define __S3C_PL330_PDATA_H
 
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 /*
  * Every PL330 DMAC has max 32 peripheral interfaces,
-- 
1.7.1

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

* [PATCH 4/7] ARM: SAMSUNG: Update to use PL330-DMA driver
@ 2011-07-04 12:18   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds to support PL330-DMA driver on DMADEVICE. Currently
S3C-DMA(PL080) is used for S3C24XX and S3C64XX and S3C-PL330-DMA has
been used for S5P SoCs. So this patch changes S3C-PL330-DMA to just
PL330-DMA for use generic DMA driver for S5P SoCs.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-exynos4/include/mach/dma.h           |    4 ++--
 arch/arm/mach-s5p64x0/include/mach/dma.h           |    2 +-
 arch/arm/mach-s5pc100/include/mach/dma.h           |    2 +-
 arch/arm/mach-s5pv210/include/mach/dma.h           |    2 +-
 arch/arm/plat-samsung/Kconfig                      |    7 +++++++
 .../include/plat/{s3c-dma-pl330.h => dma-pl330.h}  |   18 +++++++++++++++---
 .../plat-samsung/include/plat/s3c-pl330-pdata.h    |    2 +-
 7 files changed, 28 insertions(+), 9 deletions(-)
 rename arch/arm/plat-samsung/include/plat/{s3c-dma-pl330.h => dma-pl330.h} (87%)

diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos4/include/mach/dma.h
index 81209eb..201842a 100644
--- a/arch/arm/mach-exynos4/include/mach/dma.h
+++ b/arch/arm/mach-exynos4/include/mach/dma.h
@@ -20,7 +20,7 @@
 #ifndef __MACH_DMA_H
 #define __MACH_DMA_H
 
-/* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+/* This platform uses the common DMA API driver for PL330 */
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h
index 81209eb..1beae2c 100644
--- a/arch/arm/mach-s5p64x0/include/mach/dma.h
+++ b/arch/arm/mach-s5p64x0/include/mach/dma.h
@@ -21,6 +21,6 @@
 #define __MACH_DMA_H
 
 /* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/dma.h b/arch/arm/mach-s5pc100/include/mach/dma.h
index 81209eb..1beae2c 100644
--- a/arch/arm/mach-s5pc100/include/mach/dma.h
+++ b/arch/arm/mach-s5pc100/include/mach/dma.h
@@ -21,6 +21,6 @@
 #define __MACH_DMA_H
 
 /* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h
index 81209eb..1beae2c 100644
--- a/arch/arm/mach-s5pv210/include/mach/dma.h
+++ b/arch/arm/mach-s5pv210/include/mach/dma.h
@@ -21,6 +21,6 @@
 #define __MACH_DMA_H
 
 /* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 #endif /* __MACH_DMA_H */
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 4d79519..4dc914e 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -300,6 +300,13 @@ config S3C_PL330_DMA
 	help
 	  S3C DMA API Driver for PL330 DMAC.
 
+config DMADEV_PL330
+	bool
+	select DMADEVICES
+	select PL330_DMA
+	help
+	  Use DMA device engine for PL330 DMAC.
+
 comment "Power management"
 
 config SAMSUNG_PM_DEBUG
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
similarity index 87%
rename from arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
rename to arch/arm/plat-samsung/include/plat/dma-pl330.h
index 8107442..1122c8b 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -8,11 +8,13 @@
  * (at your option) any later version.
  */
 
-#ifndef	__S3C_DMA_PL330_H_
-#define	__S3C_DMA_PL330_H_
+#ifndef __DMA_PL330_H_
+#define __DMA_PL330_H_ __FILE__
 
+#if !defined(CONFIG_DMADEV_PL330)
 #define S3C2410_DMAF_AUTOSTART		(1 << 0)
 #define S3C2410_DMAF_CIRCULAR		(1 << 1)
+#endif
 
 /*
  * PL330 can assign any channel to communicate with
@@ -84,6 +86,14 @@ enum dma_ch {
 	DMACH_SLIMBUS4_TX,
 	DMACH_SLIMBUS5_RX,
 	DMACH_SLIMBUS5_TX,
+	DMACH_MTOM_0,
+	DMACH_MTOM_1,
+	DMACH_MTOM_2,
+	DMACH_MTOM_3,
+	DMACH_MTOM_4,
+	DMACH_MTOM_5,
+	DMACH_MTOM_6,
+	DMACH_MTOM_7,
 	/* END Marker, also used to denote a reserved channel */
 	DMACH_MAX,
 };
@@ -93,6 +103,8 @@ static inline bool s3c_dma_has_circular(void)
 	return true;
 }
 
+#if !defined(CONFIG_DMADEV_PL330)
 #include <plat/dma.h>
+#endif
 
-#endif	/* __S3C_DMA_PL330_H_ */
+#endif	/* __DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
index bf5e2a9..64fdf66 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
+++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
@@ -12,7 +12,7 @@
 #ifndef __S3C_PL330_PDATA_H
 #define __S3C_PL330_PDATA_H
 
-#include <plat/s3c-dma-pl330.h>
+#include <plat/dma-pl330.h>
 
 /*
  * Every PL330 DMAC has max 32 peripheral interfaces,
-- 
1.7.1

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

* [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
  2011-07-04 12:18 ` Kukjin Kim
@ 2011-07-04 12:18   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown, Boojin Kim, Kukjin Kim

From: Boojin Kim <boojin.kim@samsung.com>

This patch makes EXYNOS4 use DMA PL330 driver on DMADEVICE.
EXYNOS4 uses DMA generic API instead of SAMSUNG specific S3C-PL330 API.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-exynos4/Kconfig |    2 +-
 arch/arm/mach-exynos4/clock.c |   16 +-
 arch/arm/mach-exynos4/dma.c   |  323 +++++++++++++++++++++++++++--------------
 3 files changed, 221 insertions(+), 120 deletions(-)

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..5cc9b7a 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4
 
 config CPU_EXYNOS4210
 	bool
-	select S3C_PL330_DMA
+	select DMADEV_PL330
 	help
 	  Enable EXYNOS4210 CPU support
 
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 871f9d5..1b2e78c 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -47,6 +47,11 @@ static struct clk clk_sclk_usbphy1 = {
 	.id		= -1,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name		= "apb_pclk",
+	.id		= -1,
+};
+
 static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
 {
 	return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
@@ -485,16 +490,11 @@ static struct clk init_clocks_off[] = {
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 10),
 	}, {
-		.name		= "pdma",
-		.id		= 0,
+		.name		= "dma",
+		.id		= -1,
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
-		.name		= "pdma",
-		.id		= 1,
-		.enable		= exynos4_clk_ip_fsys_ctrl,
-		.ctrlbit	= (1 << 1),
-	}, {
 		.name		= "adc",
 		.id		= -1,
 		.enable		= exynos4_clk_ip_peril_ctrl,
@@ -1212,5 +1212,7 @@ void __init exynos4_register_clocks(void)
 	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
+	s3c24xx_register_clock(&dummy_apb_pclk);
+
 	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index 564bb53..f81c6f1 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -21,151 +21,250 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
+#include <linux/amba/bus.h>
+#include <linux/amba/pl330.h>
+#include <asm/irq.h>
 #include <plat/devs.h>
 #include <plat/irqs.h>
 
 #include <mach/map.h>
 #include <mach/irqs.h>
-
-#include <plat/s3c-pl330-pdata.h>
+#include <mach/dma.h>
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-static struct resource exynos4_pdma0_resource[] = {
-	[0] = {
-		.start	= EXYNOS4_PA_PDMA0,
-		.end	= EXYNOS4_PA_PDMA0 + SZ_4K,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_PDMA0,
-		.end	= IRQ_PDMA0,
-		.flags	= IORESOURCE_IRQ,
+struct dma_pl330_peri pdma0_peri[32] = {
+	{
+		.peri_id = (u8)DMACH_PCM0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_PCM2_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM2_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ0,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ2,
+	}, {
+		.peri_id = (u8)DMACH_SPI0_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI0_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI2_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI2_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_I2S0S_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_UART0_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART0_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART2_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART2_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART4_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART4_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS2_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS2_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS4_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS4_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_AC97_MICIN,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_AC97_PCMIN,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_AC97_PCMOUT,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
 	},
 };
 
-static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
-	.peri = {
-		[0] = DMACH_PCM0_RX,
-		[1] = DMACH_PCM0_TX,
-		[2] = DMACH_PCM2_RX,
-		[3] = DMACH_PCM2_TX,
-		[4] = DMACH_MSM_REQ0,
-		[5] = DMACH_MSM_REQ2,
-		[6] = DMACH_SPI0_RX,
-		[7] = DMACH_SPI0_TX,
-		[8] = DMACH_SPI2_RX,
-		[9] = DMACH_SPI2_TX,
-		[10] = DMACH_I2S0S_TX,
-		[11] = DMACH_I2S0_RX,
-		[12] = DMACH_I2S0_TX,
-		[13] = DMACH_I2S2_RX,
-		[14] = DMACH_I2S2_TX,
-		[15] = DMACH_UART0_RX,
-		[16] = DMACH_UART0_TX,
-		[17] = DMACH_UART2_RX,
-		[18] = DMACH_UART2_TX,
-		[19] = DMACH_UART4_RX,
-		[20] = DMACH_UART4_TX,
-		[21] = DMACH_SLIMBUS0_RX,
-		[22] = DMACH_SLIMBUS0_TX,
-		[23] = DMACH_SLIMBUS2_RX,
-		[24] = DMACH_SLIMBUS2_TX,
-		[25] = DMACH_SLIMBUS4_RX,
-		[26] = DMACH_SLIMBUS4_TX,
-		[27] = DMACH_AC97_MICIN,
-		[28] = DMACH_AC97_PCMIN,
-		[29] = DMACH_AC97_PCMOUT,
-		[30] = DMACH_MAX,
-		[31] = DMACH_MAX,
-	},
+struct dma_pl330_platdata exynos4_pdma0_pdata = {
+	.nr_valid_peri = 32,
+	.peri = pdma0_peri,
 };
 
-static struct platform_device exynos4_device_pdma0 = {
-	.name		= "s3c-pl330",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(exynos4_pdma0_resource),
-	.resource	= exynos4_pdma0_resource,
-	.dev		= {
+struct amba_device exynos4_device_pdma0 = {
+	.dev = {
+		.init_name = "dma-pl330",
 		.dma_mask = &dma_dmamask,
 		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.platform_data = &exynos4_pdma0_pdata,
-	},
+		},
+	.res = {
+		.start = EXYNOS4_PA_PDMA0,
+		.end = EXYNOS4_PA_PDMA0 + SZ_4K,
+		.flags = IORESOURCE_MEM,
+		},
+	.irq = {IRQ_PDMA0, NO_IRQ},
+	.periphid = 0x00041330,
 };
 
-static struct resource exynos4_pdma1_resource[] = {
-	[0] = {
-		.start	= EXYNOS4_PA_PDMA1,
-		.end	= EXYNOS4_PA_PDMA1 + SZ_4K,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_PDMA1,
-		.end	= IRQ_PDMA1,
-		.flags	= IORESOURCE_IRQ,
+struct dma_pl330_peri pdma1_peri[32] = {
+	{
+		.peri_id = (u8)DMACH_PCM0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_PCM1_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM1_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ1,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ3,
+	}, {
+		.peri_id = (u8)DMACH_SPI1_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI1_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_I2S0S_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_I2S1_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_I2S1_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_UART0_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART0_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART1_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART1_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART3_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART3_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS1_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS1_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS3_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS3_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS5_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS5_TX,
+		.rqtype = MEMTODEV,
 	},
 };
 
-static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
-	.peri = {
-		[0] = DMACH_PCM0_RX,
-		[1] = DMACH_PCM0_TX,
-		[2] = DMACH_PCM1_RX,
-		[3] = DMACH_PCM1_TX,
-		[4] = DMACH_MSM_REQ1,
-		[5] = DMACH_MSM_REQ3,
-		[6] = DMACH_SPI1_RX,
-		[7] = DMACH_SPI1_TX,
-		[8] = DMACH_I2S0S_TX,
-		[9] = DMACH_I2S0_RX,
-		[10] = DMACH_I2S0_TX,
-		[11] = DMACH_I2S1_RX,
-		[12] = DMACH_I2S1_TX,
-		[13] = DMACH_UART0_RX,
-		[14] = DMACH_UART0_TX,
-		[15] = DMACH_UART1_RX,
-		[16] = DMACH_UART1_TX,
-		[17] = DMACH_UART3_RX,
-		[18] = DMACH_UART3_TX,
-		[19] = DMACH_SLIMBUS1_RX,
-		[20] = DMACH_SLIMBUS1_TX,
-		[21] = DMACH_SLIMBUS3_RX,
-		[22] = DMACH_SLIMBUS3_TX,
-		[23] = DMACH_SLIMBUS5_RX,
-		[24] = DMACH_SLIMBUS5_TX,
-		[25] = DMACH_SLIMBUS0AUX_RX,
-		[26] = DMACH_SLIMBUS0AUX_TX,
-		[27] = DMACH_SPDIF,
-		[28] = DMACH_MAX,
-		[29] = DMACH_MAX,
-		[30] = DMACH_MAX,
-		[31] = DMACH_MAX,
-	},
+struct dma_pl330_platdata exynos4_pdma1_pdata = {
+	.nr_valid_peri = 32,
+	.peri = pdma1_peri,
 };
 
-static struct platform_device exynos4_device_pdma1 = {
-	.name		= "s3c-pl330",
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(exynos4_pdma1_resource),
-	.resource	= exynos4_pdma1_resource,
-	.dev		= {
+struct amba_device exynos4_device_pdma1 = {
+	.dev = {
+		.init_name = "dma-pl330",
 		.dma_mask = &dma_dmamask,
 		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.platform_data = &exynos4_pdma1_pdata,
 	},
-};
-
-static struct platform_device *exynos4_dmacs[] __initdata = {
-	&exynos4_device_pdma0,
-	&exynos4_device_pdma1,
+	.res = {
+		.start = EXYNOS4_PA_PDMA1,
+		.end = EXYNOS4_PA_PDMA1 + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_PDMA1, NO_IRQ},
+	.periphid = 0x00041330,
 };
 
 static int __init exynos4_dma_init(void)
 {
-	platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
+	amba_device_register(&exynos4_device_pdma0, &iomem_resource);
 
 	return 0;
 }
-- 
1.7.1

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

* [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
@ 2011-07-04 12:18   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Boojin Kim <boojin.kim@samsung.com>

This patch makes EXYNOS4 use DMA PL330 driver on DMADEVICE.
EXYNOS4 uses DMA generic API instead of SAMSUNG specific S3C-PL330 API.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-exynos4/Kconfig |    2 +-
 arch/arm/mach-exynos4/clock.c |   16 +-
 arch/arm/mach-exynos4/dma.c   |  323 +++++++++++++++++++++++++++--------------
 3 files changed, 221 insertions(+), 120 deletions(-)

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..5cc9b7a 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4
 
 config CPU_EXYNOS4210
 	bool
-	select S3C_PL330_DMA
+	select DMADEV_PL330
 	help
 	  Enable EXYNOS4210 CPU support
 
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 871f9d5..1b2e78c 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -47,6 +47,11 @@ static struct clk clk_sclk_usbphy1 = {
 	.id		= -1,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name		= "apb_pclk",
+	.id		= -1,
+};
+
 static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
 {
 	return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
@@ -485,16 +490,11 @@ static struct clk init_clocks_off[] = {
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 10),
 	}, {
-		.name		= "pdma",
-		.id		= 0,
+		.name		= "dma",
+		.id		= -1,
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
-		.name		= "pdma",
-		.id		= 1,
-		.enable		= exynos4_clk_ip_fsys_ctrl,
-		.ctrlbit	= (1 << 1),
-	}, {
 		.name		= "adc",
 		.id		= -1,
 		.enable		= exynos4_clk_ip_peril_ctrl,
@@ -1212,5 +1212,7 @@ void __init exynos4_register_clocks(void)
 	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
+	s3c24xx_register_clock(&dummy_apb_pclk);
+
 	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index 564bb53..f81c6f1 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -21,151 +21,250 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
+#include <linux/amba/bus.h>
+#include <linux/amba/pl330.h>
+#include <asm/irq.h>
 #include <plat/devs.h>
 #include <plat/irqs.h>
 
 #include <mach/map.h>
 #include <mach/irqs.h>
-
-#include <plat/s3c-pl330-pdata.h>
+#include <mach/dma.h>
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-static struct resource exynos4_pdma0_resource[] = {
-	[0] = {
-		.start	= EXYNOS4_PA_PDMA0,
-		.end	= EXYNOS4_PA_PDMA0 + SZ_4K,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_PDMA0,
-		.end	= IRQ_PDMA0,
-		.flags	= IORESOURCE_IRQ,
+struct dma_pl330_peri pdma0_peri[32] = {
+	{
+		.peri_id = (u8)DMACH_PCM0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_PCM2_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM2_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ0,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ2,
+	}, {
+		.peri_id = (u8)DMACH_SPI0_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI0_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI2_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI2_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_I2S0S_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_UART0_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART0_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART2_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART2_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART4_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART4_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS2_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS2_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS4_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS4_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_AC97_MICIN,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_AC97_PCMIN,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_AC97_PCMOUT,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
 	},
 };
 
-static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
-	.peri = {
-		[0] = DMACH_PCM0_RX,
-		[1] = DMACH_PCM0_TX,
-		[2] = DMACH_PCM2_RX,
-		[3] = DMACH_PCM2_TX,
-		[4] = DMACH_MSM_REQ0,
-		[5] = DMACH_MSM_REQ2,
-		[6] = DMACH_SPI0_RX,
-		[7] = DMACH_SPI0_TX,
-		[8] = DMACH_SPI2_RX,
-		[9] = DMACH_SPI2_TX,
-		[10] = DMACH_I2S0S_TX,
-		[11] = DMACH_I2S0_RX,
-		[12] = DMACH_I2S0_TX,
-		[13] = DMACH_I2S2_RX,
-		[14] = DMACH_I2S2_TX,
-		[15] = DMACH_UART0_RX,
-		[16] = DMACH_UART0_TX,
-		[17] = DMACH_UART2_RX,
-		[18] = DMACH_UART2_TX,
-		[19] = DMACH_UART4_RX,
-		[20] = DMACH_UART4_TX,
-		[21] = DMACH_SLIMBUS0_RX,
-		[22] = DMACH_SLIMBUS0_TX,
-		[23] = DMACH_SLIMBUS2_RX,
-		[24] = DMACH_SLIMBUS2_TX,
-		[25] = DMACH_SLIMBUS4_RX,
-		[26] = DMACH_SLIMBUS4_TX,
-		[27] = DMACH_AC97_MICIN,
-		[28] = DMACH_AC97_PCMIN,
-		[29] = DMACH_AC97_PCMOUT,
-		[30] = DMACH_MAX,
-		[31] = DMACH_MAX,
-	},
+struct dma_pl330_platdata exynos4_pdma0_pdata = {
+	.nr_valid_peri = 32,
+	.peri = pdma0_peri,
 };
 
-static struct platform_device exynos4_device_pdma0 = {
-	.name		= "s3c-pl330",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(exynos4_pdma0_resource),
-	.resource	= exynos4_pdma0_resource,
-	.dev		= {
+struct amba_device exynos4_device_pdma0 = {
+	.dev = {
+		.init_name = "dma-pl330",
 		.dma_mask = &dma_dmamask,
 		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.platform_data = &exynos4_pdma0_pdata,
-	},
+		},
+	.res = {
+		.start = EXYNOS4_PA_PDMA0,
+		.end = EXYNOS4_PA_PDMA0 + SZ_4K,
+		.flags = IORESOURCE_MEM,
+		},
+	.irq = {IRQ_PDMA0, NO_IRQ},
+	.periphid = 0x00041330,
 };
 
-static struct resource exynos4_pdma1_resource[] = {
-	[0] = {
-		.start	= EXYNOS4_PA_PDMA1,
-		.end	= EXYNOS4_PA_PDMA1 + SZ_4K,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_PDMA1,
-		.end	= IRQ_PDMA1,
-		.flags	= IORESOURCE_IRQ,
+struct dma_pl330_peri pdma1_peri[32] = {
+	{
+		.peri_id = (u8)DMACH_PCM0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_PCM1_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_PCM1_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ1,
+	}, {
+		.peri_id = (u8)DMACH_MSM_REQ3,
+	}, {
+		.peri_id = (u8)DMACH_SPI1_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_SPI1_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 1,
+	}, {
+		.peri_id = (u8)DMACH_I2S0S_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_I2S0_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_I2S1_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_I2S1_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_UART0_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART0_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART1_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART1_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART3_RX,
+		.rqtype = DEVTOMEM,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_UART3_TX,
+		.rqtype = MEMTODEV,
+		.burst_sz = 4,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS1_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS1_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS3_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS3_TX,
+		.rqtype = MEMTODEV,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS5_RX,
+		.rqtype = DEVTOMEM,
+	}, {
+		.peri_id = (u8)DMACH_SLIMBUS5_TX,
+		.rqtype = MEMTODEV,
 	},
 };
 
-static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
-	.peri = {
-		[0] = DMACH_PCM0_RX,
-		[1] = DMACH_PCM0_TX,
-		[2] = DMACH_PCM1_RX,
-		[3] = DMACH_PCM1_TX,
-		[4] = DMACH_MSM_REQ1,
-		[5] = DMACH_MSM_REQ3,
-		[6] = DMACH_SPI1_RX,
-		[7] = DMACH_SPI1_TX,
-		[8] = DMACH_I2S0S_TX,
-		[9] = DMACH_I2S0_RX,
-		[10] = DMACH_I2S0_TX,
-		[11] = DMACH_I2S1_RX,
-		[12] = DMACH_I2S1_TX,
-		[13] = DMACH_UART0_RX,
-		[14] = DMACH_UART0_TX,
-		[15] = DMACH_UART1_RX,
-		[16] = DMACH_UART1_TX,
-		[17] = DMACH_UART3_RX,
-		[18] = DMACH_UART3_TX,
-		[19] = DMACH_SLIMBUS1_RX,
-		[20] = DMACH_SLIMBUS1_TX,
-		[21] = DMACH_SLIMBUS3_RX,
-		[22] = DMACH_SLIMBUS3_TX,
-		[23] = DMACH_SLIMBUS5_RX,
-		[24] = DMACH_SLIMBUS5_TX,
-		[25] = DMACH_SLIMBUS0AUX_RX,
-		[26] = DMACH_SLIMBUS0AUX_TX,
-		[27] = DMACH_SPDIF,
-		[28] = DMACH_MAX,
-		[29] = DMACH_MAX,
-		[30] = DMACH_MAX,
-		[31] = DMACH_MAX,
-	},
+struct dma_pl330_platdata exynos4_pdma1_pdata = {
+	.nr_valid_peri = 32,
+	.peri = pdma1_peri,
 };
 
-static struct platform_device exynos4_device_pdma1 = {
-	.name		= "s3c-pl330",
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(exynos4_pdma1_resource),
-	.resource	= exynos4_pdma1_resource,
-	.dev		= {
+struct amba_device exynos4_device_pdma1 = {
+	.dev = {
+		.init_name = "dma-pl330",
 		.dma_mask = &dma_dmamask,
 		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.platform_data = &exynos4_pdma1_pdata,
 	},
-};
-
-static struct platform_device *exynos4_dmacs[] __initdata = {
-	&exynos4_device_pdma0,
-	&exynos4_device_pdma1,
+	.res = {
+		.start = EXYNOS4_PA_PDMA1,
+		.end = EXYNOS4_PA_PDMA1 + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_PDMA1, NO_IRQ},
+	.periphid = 0x00041330,
 };
 
 static int __init exynos4_dma_init(void)
 {
-	platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
+	amba_device_register(&exynos4_device_pdma0, &iomem_resource);
 
 	return 0;
 }
-- 
1.7.1

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 12:18 ` Kukjin Kim
@ 2011-07-04 12:18   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown, Boojin Kim, Kukjin Kim

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds to support DMA generic API to transfer raw
SPI data. Basiclly the spi driver uses DMA generic API if
architecture supports it. Otherwise, uses Samsung specific
S3C-PL330 APIs.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/spi/spi_s3c64xx.c |  234 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 194 insertions(+), 40 deletions(-)

diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 795828b..848487b 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -26,6 +26,10 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#if defined(CONFIG_DMADEV_PL330)
+#include <linux/dmaengine.h>
+#include <linux/amba/pl330.h>
+#endif
 
 #include <mach/dma.h>
 #include <plat/s3c64xx-spi.h>
@@ -174,11 +178,19 @@ struct s3c64xx_spi_driver_data {
 	unsigned                        state;
 	unsigned                        cur_mode, cur_bpw;
 	unsigned                        cur_speed;
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_chan *rx_chan;
+	struct dma_chan *tx_chan;
+	struct dma_async_tx_descriptor *rx_desc;
+	struct dma_async_tx_descriptor *tx_desc;
+#endif
 };
 
+#if !defined(CONFIG_DMADEV_PL330)
 static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
 	.name = "samsung-spi-dma",
 };
+#endif
 
 static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
 {
@@ -229,6 +241,80 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
 	writel(val, regs + S3C64XX_SPI_CH_CFG);
 }
 
+#if defined(CONFIG_DMADEV_PL330)
+static void s3c64xx_spi_dma_rxcb(void *data)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	sdd->state &= ~RXBUSY;
+	/* If the other done */
+	if (!(sdd->state & TXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+
+static void s3c64xx_spi_dma_txcb(void *data)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	sdd->state &= ~TXBUSY;
+	/* If the other done */
+	if (!(sdd->state & RXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+#else
+static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
+				 int size, enum s3c2410_dma_buffresult res)
+{
+	struct s3c64xx_spi_driver_data *sdd = buf_id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	if (res == S3C2410_RES_OK)
+		sdd->state &= ~RXBUSY;
+	else
+		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
+
+	/* If the other done */
+	if (!(sdd->state & TXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+
+static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
+				 int size, enum s3c2410_dma_buffresult res)
+{
+	struct s3c64xx_spi_driver_data *sdd = buf_id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	if (res == S3C2410_RES_OK)
+		sdd->state &= ~TXBUSY;
+	else
+		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d\n", size);
+
+	/* If the other done */
+	if (!(sdd->state & RXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+#endif
+
 static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 				struct spi_device *spi,
 				struct spi_transfer *xfer, int dma_mode)
@@ -236,6 +322,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	void __iomem *regs = sdd->regs;
 	u32 modecfg, chcfg;
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_slave_config slave_config;
+	struct scatterlist tx_sg;
+	struct scatterlist rx_sg;
+#endif
 
 	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
 	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
@@ -261,10 +352,34 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
 		if (dma_mode) {
 			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
+#if defined(CONFIG_DMADEV_PL330)
+			memset(&slave_config, 0, sizeof(slave_config));
+			slave_config.direction = DMA_TO_DEVICE;
+			slave_config.src_addr = xfer->tx_dma;
+			slave_config.dst_addr =
+				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+			slave_config.dst_addr_width = sdd->cur_bpw / 8;
+			dmaengine_slave_config(sdd->tx_chan, &slave_config);
+
+			sg_init_table(&tx_sg, 1);
+			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
+				xfer->len, offset_in_page(xfer->tx_dma));
+			sg_dma_len(&tx_sg) =  xfer->len;
+			sg_dma_address(&tx_sg) = xfer->tx_dma;
+			sdd->tx_desc =
+				sdd->tx_chan->device->device_prep_slave_sg(
+				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
+				DMA_PREP_INTERRUPT);
+			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
+			sdd->tx_desc->callback_param = sdd;
+			dmaengine_submit(sdd->tx_desc);
+			dma_async_issue_pending(sdd->tx_chan);
+#else
 			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
 			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
 						xfer->tx_dma, xfer->len);
 			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
+#endif
 		} else {
 			switch (sdd->cur_bpw) {
 			case 32:
@@ -296,10 +411,33 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
 					| S3C64XX_SPI_PACKET_CNT_EN,
 					regs + S3C64XX_SPI_PACKET_CNT);
+#if defined(CONFIG_DMADEV_PL330)
+			slave_config.direction = DMA_FROM_DEVICE;
+			slave_config.dst_addr = xfer->rx_dma;
+			slave_config.src_addr =
+				sdd->sfr_start + S3C64XX_SPI_RX_DATA;
+			slave_config.src_addr_width = sdd->cur_bpw / 8;
+			dmaengine_slave_config(sdd->rx_chan, &slave_config);
+
+			sg_init_table(&rx_sg, 1);
+			sg_set_page(&rx_sg, pfn_to_page(PFN_DOWN(xfer->rx_dma)),
+				xfer->len, offset_in_page(xfer->rx_dma));
+			sg_dma_len(&rx_sg) =  xfer->len;
+			sg_dma_address(&rx_sg) = xfer->rx_dma;
+			sdd->rx_desc =
+				sdd->rx_chan->device->device_prep_slave_sg(
+				sdd->rx_chan, &rx_sg, 1, DMA_FROM_DEVICE,
+				DMA_PREP_INTERRUPT);
+			sdd->rx_desc->callback = s3c64xx_spi_dma_rxcb;
+			sdd->rx_desc->callback_param = sdd;
+			dmaengine_submit(sdd->rx_desc);
+			dma_async_issue_pending(sdd->rx_chan);
+#else
 			s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
 			s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
 						xfer->rx_dma, xfer->len);
 			s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
+#endif
 		}
 	}
 
@@ -485,46 +623,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
 	}
 }
 
-static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
-				 int size, enum s3c2410_dma_buffresult res)
-{
-	struct s3c64xx_spi_driver_data *sdd = buf_id;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdd->lock, flags);
-
-	if (res == S3C2410_RES_OK)
-		sdd->state &= ~RXBUSY;
-	else
-		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
-
-	/* If the other done */
-	if (!(sdd->state & TXBUSY))
-		complete(&sdd->xfer_completion);
-
-	spin_unlock_irqrestore(&sdd->lock, flags);
-}
-
-static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
-				 int size, enum s3c2410_dma_buffresult res)
-{
-	struct s3c64xx_spi_driver_data *sdd = buf_id;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdd->lock, flags);
-
-	if (res == S3C2410_RES_OK)
-		sdd->state &= ~TXBUSY;
-	else
-		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
-
-	/* If the other done */
-	if (!(sdd->state & RXBUSY))
-		complete(&sdd->xfer_completion);
-
-	spin_unlock_irqrestore(&sdd->lock, flags);
-}
-
 #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
 
 static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
@@ -699,12 +797,20 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
 			if (use_dma) {
 				if (xfer->tx_buf != NULL
 						&& (sdd->state & TXBUSY))
+#if defined(CONFIG_DMADEV_PL330)
+					dmaengine_terminate_all(sdd->tx_chan);
+#else
 					s3c2410_dma_ctrl(sdd->tx_dmach,
 							S3C2410_DMAOP_FLUSH);
+#endif
 				if (xfer->rx_buf != NULL
 						&& (sdd->state & RXBUSY))
+#if defined(CONFIG_DMADEV_PL330)
+					dmaengine_terminate_all(sdd->rx_chan);
+#else
 					s3c2410_dma_ctrl(sdd->rx_dmach,
 							S3C2410_DMAOP_FLUSH);
+#endif
 			}
 
 			goto out;
@@ -742,8 +848,50 @@ out:
 		msg->complete(msg->context);
 }
 
+#if defined(CONFIG_DMADEV_PL330)
+static bool rxfilter(struct dma_chan *chan, void *param)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)param;
+	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
+
+	if (peri->peri_id != sdd->rx_dmach)
+		return false;
+
+	return true;
+}
+static bool txfilter(struct dma_chan *chan, void *param)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)param;
+	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
+
+	if (peri->peri_id != sdd->tx_dmach)
+		return false;
+
+	return true;
+}
+#endif
+
 static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
 {
+#if defined(CONFIG_DMADEV_PL330)
+	dma_cap_mask_t mask;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	sdd->rx_chan =
+		dma_request_channel(mask, rxfilter, (void *)sdd);
+	if (!sdd->rx_chan) {
+		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
+		return 0;
+	}
+	sdd->tx_chan =
+		dma_request_channel(mask, txfilter, (void *)sdd);
+	if (!sdd->tx_chan) {
+		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
+		return 0;
+	}
+#else
 	if (s3c2410_dma_request(sdd->rx_dmach,
 					&s3c64xx_spi_dma_client, NULL) < 0) {
 		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
@@ -762,6 +910,7 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
 	s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
 	s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
 					sdd->sfr_start + S3C64XX_SPI_TX_DATA);
+#endif
 
 	return 1;
 }
@@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct *work)
 	spin_unlock_irqrestore(&sdd->lock, flags);
 
 	/* Free DMA channels */
+#if defined(CONFIG_DMADEV_PL330)
+	dma_release_channel(sdd->tx_chan);
+	dma_release_channel(sdd->rx_chan);
+#else
 	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
 	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+#endif
 }
 
 static int s3c64xx_spi_transfer(struct spi_device *spi,
-- 
1.7.1

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-04 12:18   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds to support DMA generic API to transfer raw
SPI data. Basiclly the spi driver uses DMA generic API if
architecture supports it. Otherwise, uses Samsung specific
S3C-PL330 APIs.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 drivers/spi/spi_s3c64xx.c |  234 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 194 insertions(+), 40 deletions(-)

diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 795828b..848487b 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -26,6 +26,10 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#if defined(CONFIG_DMADEV_PL330)
+#include <linux/dmaengine.h>
+#include <linux/amba/pl330.h>
+#endif
 
 #include <mach/dma.h>
 #include <plat/s3c64xx-spi.h>
@@ -174,11 +178,19 @@ struct s3c64xx_spi_driver_data {
 	unsigned                        state;
 	unsigned                        cur_mode, cur_bpw;
 	unsigned                        cur_speed;
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_chan *rx_chan;
+	struct dma_chan *tx_chan;
+	struct dma_async_tx_descriptor *rx_desc;
+	struct dma_async_tx_descriptor *tx_desc;
+#endif
 };
 
+#if !defined(CONFIG_DMADEV_PL330)
 static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
 	.name = "samsung-spi-dma",
 };
+#endif
 
 static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
 {
@@ -229,6 +241,80 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
 	writel(val, regs + S3C64XX_SPI_CH_CFG);
 }
 
+#if defined(CONFIG_DMADEV_PL330)
+static void s3c64xx_spi_dma_rxcb(void *data)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	sdd->state &= ~RXBUSY;
+	/* If the other done */
+	if (!(sdd->state & TXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+
+static void s3c64xx_spi_dma_txcb(void *data)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	sdd->state &= ~TXBUSY;
+	/* If the other done */
+	if (!(sdd->state & RXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+#else
+static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
+				 int size, enum s3c2410_dma_buffresult res)
+{
+	struct s3c64xx_spi_driver_data *sdd = buf_id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	if (res == S3C2410_RES_OK)
+		sdd->state &= ~RXBUSY;
+	else
+		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
+
+	/* If the other done */
+	if (!(sdd->state & TXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+
+static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
+				 int size, enum s3c2410_dma_buffresult res)
+{
+	struct s3c64xx_spi_driver_data *sdd = buf_id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdd->lock, flags);
+
+	if (res == S3C2410_RES_OK)
+		sdd->state &= ~TXBUSY;
+	else
+		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d\n", size);
+
+	/* If the other done */
+	if (!(sdd->state & RXBUSY))
+		complete(&sdd->xfer_completion);
+
+	spin_unlock_irqrestore(&sdd->lock, flags);
+}
+#endif
+
 static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 				struct spi_device *spi,
 				struct spi_transfer *xfer, int dma_mode)
@@ -236,6 +322,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	void __iomem *regs = sdd->regs;
 	u32 modecfg, chcfg;
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_slave_config slave_config;
+	struct scatterlist tx_sg;
+	struct scatterlist rx_sg;
+#endif
 
 	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
 	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
@@ -261,10 +352,34 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
 		if (dma_mode) {
 			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
+#if defined(CONFIG_DMADEV_PL330)
+			memset(&slave_config, 0, sizeof(slave_config));
+			slave_config.direction = DMA_TO_DEVICE;
+			slave_config.src_addr = xfer->tx_dma;
+			slave_config.dst_addr =
+				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+			slave_config.dst_addr_width = sdd->cur_bpw / 8;
+			dmaengine_slave_config(sdd->tx_chan, &slave_config);
+
+			sg_init_table(&tx_sg, 1);
+			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
+				xfer->len, offset_in_page(xfer->tx_dma));
+			sg_dma_len(&tx_sg) =  xfer->len;
+			sg_dma_address(&tx_sg) = xfer->tx_dma;
+			sdd->tx_desc =
+				sdd->tx_chan->device->device_prep_slave_sg(
+				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
+				DMA_PREP_INTERRUPT);
+			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
+			sdd->tx_desc->callback_param = sdd;
+			dmaengine_submit(sdd->tx_desc);
+			dma_async_issue_pending(sdd->tx_chan);
+#else
 			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
 			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
 						xfer->tx_dma, xfer->len);
 			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
+#endif
 		} else {
 			switch (sdd->cur_bpw) {
 			case 32:
@@ -296,10 +411,33 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
 					| S3C64XX_SPI_PACKET_CNT_EN,
 					regs + S3C64XX_SPI_PACKET_CNT);
+#if defined(CONFIG_DMADEV_PL330)
+			slave_config.direction = DMA_FROM_DEVICE;
+			slave_config.dst_addr = xfer->rx_dma;
+			slave_config.src_addr =
+				sdd->sfr_start + S3C64XX_SPI_RX_DATA;
+			slave_config.src_addr_width = sdd->cur_bpw / 8;
+			dmaengine_slave_config(sdd->rx_chan, &slave_config);
+
+			sg_init_table(&rx_sg, 1);
+			sg_set_page(&rx_sg, pfn_to_page(PFN_DOWN(xfer->rx_dma)),
+				xfer->len, offset_in_page(xfer->rx_dma));
+			sg_dma_len(&rx_sg) =  xfer->len;
+			sg_dma_address(&rx_sg) = xfer->rx_dma;
+			sdd->rx_desc =
+				sdd->rx_chan->device->device_prep_slave_sg(
+				sdd->rx_chan, &rx_sg, 1, DMA_FROM_DEVICE,
+				DMA_PREP_INTERRUPT);
+			sdd->rx_desc->callback = s3c64xx_spi_dma_rxcb;
+			sdd->rx_desc->callback_param = sdd;
+			dmaengine_submit(sdd->rx_desc);
+			dma_async_issue_pending(sdd->rx_chan);
+#else
 			s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
 			s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
 						xfer->rx_dma, xfer->len);
 			s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
+#endif
 		}
 	}
 
@@ -485,46 +623,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
 	}
 }
 
-static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
-				 int size, enum s3c2410_dma_buffresult res)
-{
-	struct s3c64xx_spi_driver_data *sdd = buf_id;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdd->lock, flags);
-
-	if (res == S3C2410_RES_OK)
-		sdd->state &= ~RXBUSY;
-	else
-		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
-
-	/* If the other done */
-	if (!(sdd->state & TXBUSY))
-		complete(&sdd->xfer_completion);
-
-	spin_unlock_irqrestore(&sdd->lock, flags);
-}
-
-static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
-				 int size, enum s3c2410_dma_buffresult res)
-{
-	struct s3c64xx_spi_driver_data *sdd = buf_id;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdd->lock, flags);
-
-	if (res == S3C2410_RES_OK)
-		sdd->state &= ~TXBUSY;
-	else
-		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
-
-	/* If the other done */
-	if (!(sdd->state & RXBUSY))
-		complete(&sdd->xfer_completion);
-
-	spin_unlock_irqrestore(&sdd->lock, flags);
-}
-
 #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
 
 static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
@@ -699,12 +797,20 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
 			if (use_dma) {
 				if (xfer->tx_buf != NULL
 						&& (sdd->state & TXBUSY))
+#if defined(CONFIG_DMADEV_PL330)
+					dmaengine_terminate_all(sdd->tx_chan);
+#else
 					s3c2410_dma_ctrl(sdd->tx_dmach,
 							S3C2410_DMAOP_FLUSH);
+#endif
 				if (xfer->rx_buf != NULL
 						&& (sdd->state & RXBUSY))
+#if defined(CONFIG_DMADEV_PL330)
+					dmaengine_terminate_all(sdd->rx_chan);
+#else
 					s3c2410_dma_ctrl(sdd->rx_dmach,
 							S3C2410_DMAOP_FLUSH);
+#endif
 			}
 
 			goto out;
@@ -742,8 +848,50 @@ out:
 		msg->complete(msg->context);
 }
 
+#if defined(CONFIG_DMADEV_PL330)
+static bool rxfilter(struct dma_chan *chan, void *param)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)param;
+	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
+
+	if (peri->peri_id != sdd->rx_dmach)
+		return false;
+
+	return true;
+}
+static bool txfilter(struct dma_chan *chan, void *param)
+{
+	struct s3c64xx_spi_driver_data *sdd
+		= (struct s3c64xx_spi_driver_data *)param;
+	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
+
+	if (peri->peri_id != sdd->tx_dmach)
+		return false;
+
+	return true;
+}
+#endif
+
 static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
 {
+#if defined(CONFIG_DMADEV_PL330)
+	dma_cap_mask_t mask;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	sdd->rx_chan =
+		dma_request_channel(mask, rxfilter, (void *)sdd);
+	if (!sdd->rx_chan) {
+		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
+		return 0;
+	}
+	sdd->tx_chan =
+		dma_request_channel(mask, txfilter, (void *)sdd);
+	if (!sdd->tx_chan) {
+		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
+		return 0;
+	}
+#else
 	if (s3c2410_dma_request(sdd->rx_dmach,
 					&s3c64xx_spi_dma_client, NULL) < 0) {
 		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
@@ -762,6 +910,7 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
 	s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
 	s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
 					sdd->sfr_start + S3C64XX_SPI_TX_DATA);
+#endif
 
 	return 1;
 }
@@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct *work)
 	spin_unlock_irqrestore(&sdd->lock, flags);
 
 	/* Free DMA channels */
+#if defined(CONFIG_DMADEV_PL330)
+	dma_release_channel(sdd->tx_chan);
+	dma_release_channel(sdd->rx_chan);
+#else
 	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
 	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+#endif
 }
 
 static int s3c64xx_spi_transfer(struct spi_device *spi,
-- 
1.7.1

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

* [PATCH 7/7] ASoC: Samsung: Update DMA interface
  2011-07-04 12:18 ` Kukjin Kim
@ 2011-07-04 12:18   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: Vinod Koul, Dan Williams, Grant Likely, Jassi Brar,
	Liam Girdwood, Mark Brown, Boojin Kim, Kukjin Kim

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds to support the DMA PL330 driver that uses
DMA generic API. Samsung sound driver uses DMA generic API
if architecture supports it. Otherwise, use samsung specific
S3C-PL330 API driver to transfer PCM data.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Liam Girdwood <lrg@ti.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-s3c2410/include/mach/dma.h       |    2 +-
 arch/arm/mach-s3c64xx/include/mach/dma.h       |    2 +-
 arch/arm/plat-samsung/include/plat/dma-pl330.h |    2 +-
 sound/soc/samsung/ac97.c                       |    4 +
 sound/soc/samsung/dma.c                        |  204 +++++++++++++++++++++++-
 sound/soc/samsung/dma.h                        |    4 +
 6 files changed, 211 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index b2b2a5b..e2db38b 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -196,7 +196,7 @@ struct s3c2410_dma_chan {
 
 typedef unsigned long dma_device_t;
 
-static inline bool s3c_dma_has_circular(void)
+static inline bool dma_has_circular(void)
 {
 	return false;
 }
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index 0a5d926..d752e27 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -58,7 +58,7 @@ enum dma_ch {
 	DMACH_MAX		/* the end */
 };
 
-static __inline__ bool s3c_dma_has_circular(void)
+static inline bool dma_has_circular(void)
 {
 	return true;
 }
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 1122c8b..4f19eb3 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -98,7 +98,7 @@ enum dma_ch {
 	DMACH_MAX,
 };
 
-static inline bool s3c_dma_has_circular(void)
+static inline bool dma_has_circular(void)
 {
 	return true;
 }
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index f97110e..ec6b3dd 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -271,7 +271,9 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 
 	writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
+#if !defined(CONFIG_DMADEV_PL330)
 	s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
+#endif
 
 	return 0;
 }
@@ -317,7 +319,9 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
 
 	writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
+#if !defined(CONFIG_DMADEV_PL330)
 	s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
+#endif
 
 	return 0;
 }
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 5cb3b88..6ba0632 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -17,6 +17,11 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 
+#if defined(CONFIG_DMADEV_PL330)
+#include <linux/dmaengine.h>
+#include <linux/amba/pl330.h>
+#endif
+
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
 
@@ -62,6 +67,103 @@ struct runtime_data {
 	struct s3c_dma_params *params;
 };
 
+#if defined(CONFIG_DMADEV_PL330)
+static bool filter(struct dma_chan *chan, void *param)
+{
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)param;
+	struct runtime_data *prtd = substream->runtime->private_data;
+
+	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
+
+	if (peri->peri_id != prtd->params->channel)
+		return false;
+
+	/* dma client should fill fifo_addr */
+	peri->fifo_addr = prtd->params->dma_addr;
+
+	return true;
+}
+
+static void audio_buffdone(void *data)
+{
+	struct snd_pcm_substream *substream = data;
+	struct runtime_data *prtd;
+	struct dma_chan *chan;
+
+	prtd = substream->runtime->private_data;
+
+	chan = prtd->params->chan;
+	prtd->params->desc =
+		chan->device->device_prep_dma_cyclic(
+		chan, prtd->dma_pos, prtd->dma_period, prtd->dma_period,
+		substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+		DMA_TO_DEVICE : DMA_FROM_DEVICE);
+	if (!prtd->params->desc)
+		dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
+
+	prtd->params->desc->callback = audio_buffdone;
+	prtd->params->desc->callback_param = substream;
+	dmaengine_submit(prtd->params->desc);
+
+	prtd->dma_pos += prtd->dma_period;
+	if (prtd->dma_pos >= prtd->dma_end)
+		prtd->dma_pos = prtd->dma_start;
+
+	if (substream)
+		snd_pcm_period_elapsed(substream);
+}
+
+/* dma_enqueue
+ *
+ * place a dma buffer onto the queue for the dma system
+ * to handle.
+ */
+static void dma_enqueue(struct snd_pcm_substream *substream)
+{
+	struct runtime_data *prtd = substream->runtime->private_data;
+	dma_addr_t pos = prtd->dma_pos;
+	unsigned int limit;
+	struct dma_chan *chan = prtd->params->chan;
+
+	pr_debug("Entered %s\n", __func__);
+
+	limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
+
+	chan = prtd->params->chan;
+
+	while (prtd->dma_loaded < limit) {
+		unsigned long len = prtd->dma_period;
+
+		pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
+
+		if ((pos + len) > prtd->dma_end) {
+			len  = prtd->dma_end - pos;
+			pr_debug("%s: corrected dma len %ld\n",
+					__func__, len);
+		}
+
+		prtd->params->desc =
+			chan->device->device_prep_dma_cyclic(
+			chan, pos, prtd->dma_period, prtd->dma_period,
+			substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+			DMA_TO_DEVICE : DMA_FROM_DEVICE);
+		if (!prtd->params->desc)
+			dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
+
+		prtd->params->desc->callback = audio_buffdone;
+		prtd->params->desc->callback_param = substream;
+		dmaengine_submit(prtd->params->desc);
+
+		prtd->dma_loaded++;
+		pos += prtd->dma_period;
+		if (pos >= prtd->dma_end)
+			pos = prtd->dma_start;
+	}
+
+	prtd->dma_pos = pos;
+}
+
+#else
 /* dma_enqueue
  *
  * place a dma buffer onto the queue for the dma system
@@ -76,7 +178,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
 
 	pr_debug("Entered %s\n", __func__);
 
-	if (s3c_dma_has_circular())
+	if (dma_has_circular())
 		limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
 	else
 		limit = prtd->dma_limit;
@@ -127,13 +229,14 @@ static void audio_buffdone(struct s3c2410_dma_chan *channel,
 		snd_pcm_period_elapsed(substream);
 
 	spin_lock(&prtd->lock);
-	if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
+	if (prtd->state & ST_RUNNING && !dma_has_circular()) {
 		prtd->dma_loaded--;
 		dma_enqueue(substream);
 	}
 
 	spin_unlock(&prtd->lock);
 }
+#endif /* CONFIG_DMADEV_PL330 */
 
 static int dma_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
@@ -146,6 +249,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
 		snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 	int ret = 0;
 
+#if defined(CONFIG_DMADEV_PL330)
+	dma_cap_mask_t mask;
 
 	pr_debug("Entered %s\n", __func__);
 
@@ -154,6 +259,28 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
 	if (!dma)
 		return 0;
 
+	if (prtd->params == NULL) {
+		/* prepare DMA */
+		prtd->params = dma;
+
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_SLAVE, mask);
+		dma_cap_set(DMA_CYCLIC, mask);
+		prtd->params->chan =
+			dma_request_channel(mask, filter, substream);
+		if (!prtd->params->chan) {
+			printk(KERN_ERR "failed to get dma channel\n");
+			return ret;
+		}
+	}
+#else
+	pr_debug("Entered %s\n", __func__);
+
+	/* return if this is a bufferless transfer e.g.
+	 * codec <--> BT codec or GSM modem -- lg FIXME */
+	if (!dma)
+		return 0;
+
 	/* this may get called several times by oss emulation
 	 * with different params -HW */
 	if (prtd->params == NULL) {
@@ -172,14 +299,14 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
 		}
 
 		/* use the circular buffering if we have it available. */
-		if (s3c_dma_has_circular())
+		if (dma_has_circular())
 			s3c2410_dma_setflags(prtd->params->channel,
 					     S3C2410_DMAF_CIRCULAR);
 	}
 
 	s3c2410_dma_set_buffdone_fn(prtd->params->channel,
 				    audio_buffdone);
-
+#endif /* CONFIG_DMADEV_PL330 */
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
 	runtime->dma_bytes = totbytes;
@@ -206,7 +333,11 @@ static int dma_hw_free(struct snd_pcm_substream *substream)
 	snd_pcm_set_runtime_buffer(substream, NULL);
 
 	if (prtd->params) {
+#if defined(CONFIG_DMADEV_PL330)
+		dma_release_channel(prtd->params->chan);
+#else
 		s3c2410_dma_free(prtd->params->channel, prtd->params->client);
+#endif
 		prtd->params = NULL;
 	}
 
@@ -218,6 +349,33 @@ static int dma_prepare(struct snd_pcm_substream *substream)
 	struct runtime_data *prtd = substream->runtime->private_data;
 	int ret = 0;
 
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_chan *chan = prtd->params->chan;
+	struct dma_slave_config slave_config;
+
+	pr_debug("Entered %s\n", __func__);
+
+	/* return if this is a bufferless transfer e.g.
+	 * codec <--> BT codec or GSM modem -- lg FIXME */
+	if (!prtd->params)
+		return 0;
+
+	ret = dmaengine_terminate_all(chan);
+	if (ret)
+		dev_err(&chan->dev->device, "cannot flush dma channel\n");
+
+	memset(&slave_config, 0, sizeof(struct dma_slave_config));
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		slave_config.direction = DMA_TO_DEVICE;
+		slave_config.dst_addr_width = prtd->params->dma_size;
+	} else {
+		slave_config.direction = DMA_FROM_DEVICE;
+		slave_config.src_addr_width = prtd->params->dma_size;
+	}
+	ret = dmaengine_slave_config(chan, &slave_config);
+	if (ret)
+		dev_err(&chan->dev->device, "cannot config dma channel\n");
+#else
 	pr_debug("Entered %s\n", __func__);
 
 	/* return if this is a bufferless transfer e.g.
@@ -242,6 +400,7 @@ static int dma_prepare(struct snd_pcm_substream *substream)
 
 	/* flush the DMA channel */
 	s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
+#endif	/* CONFIG_DMADEV_PL330 */
 	prtd->dma_loaded = 0;
 	prtd->dma_pos = prtd->dma_start;
 
@@ -256,6 +415,33 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct runtime_data *prtd = substream->runtime->private_data;
 	int ret = 0;
 
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_chan *chan = prtd->params->chan;
+
+	pr_debug("Entered %s\n", __func__);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		prtd->state |= ST_RUNNING;
+		dma_async_issue_pending(prtd->params->chan);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		prtd->state &= ~ST_RUNNING;
+		ret = dmaengine_terminate_all(chan);
+		if (ret)
+			dev_err(&chan->dev->device, "cannot flush dma channel\n");
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+#else
 	pr_debug("Entered %s\n", __func__);
 
 	spin_lock(&prtd->lock);
@@ -281,6 +467,7 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
 	}
 
 	spin_unlock(&prtd->lock);
+#endif /* CONFIG_DMADEV_PL330 */
 
 	return ret;
 }
@@ -291,6 +478,14 @@ dma_pointer(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct runtime_data *prtd = runtime->private_data;
 	unsigned long res;
+
+#if defined(CONFIG_DMADEV_PL330)
+	pr_debug("Entered %s\n", __func__);
+
+	res = prtd->dma_pos - prtd->dma_start;
+
+	pr_debug("Pointer offset: %lu\n", res);
+#else
 	dma_addr_t src, dst;
 
 	pr_debug("Entered %s\n", __func__);
@@ -306,6 +501,7 @@ dma_pointer(struct snd_pcm_substream *substream)
 	spin_unlock(&prtd->lock);
 
 	pr_debug("Pointer %x %x\n", src, dst);
+#endif /* CONFIG_DMADEV_PL330 */
 
 	/* we seem to be getting the odd error from the pcm library due
 	 * to out-of-bounds pointers. this is maybe due to the dma engine
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index c506592..b6fae7e 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -17,6 +17,10 @@ struct s3c_dma_params {
 	int channel;				/* Channel ID */
 	dma_addr_t dma_addr;
 	int dma_size;			/* Size of the DMA transfer */
+#ifdef CONFIG_DMADEV_PL330
+	struct dma_chan *chan;
+	struct dma_async_tx_descriptor *desc;
+#endif
 };
 
 #endif
-- 
1.7.1

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

* [PATCH 7/7] ASoC: Samsung: Update DMA interface
@ 2011-07-04 12:18   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-04 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Boojin Kim <boojin.kim@samsung.com>

This patch adds to support the DMA PL330 driver that uses
DMA generic API. Samsung sound driver uses DMA generic API
if architecture supports it. Otherwise, use samsung specific
S3C-PL330 API driver to transfer PCM data.

Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Liam Girdwood <lrg@ti.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-s3c2410/include/mach/dma.h       |    2 +-
 arch/arm/mach-s3c64xx/include/mach/dma.h       |    2 +-
 arch/arm/plat-samsung/include/plat/dma-pl330.h |    2 +-
 sound/soc/samsung/ac97.c                       |    4 +
 sound/soc/samsung/dma.c                        |  204 +++++++++++++++++++++++-
 sound/soc/samsung/dma.h                        |    4 +
 6 files changed, 211 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index b2b2a5b..e2db38b 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -196,7 +196,7 @@ struct s3c2410_dma_chan {
 
 typedef unsigned long dma_device_t;
 
-static inline bool s3c_dma_has_circular(void)
+static inline bool dma_has_circular(void)
 {
 	return false;
 }
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index 0a5d926..d752e27 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -58,7 +58,7 @@ enum dma_ch {
 	DMACH_MAX		/* the end */
 };
 
-static __inline__ bool s3c_dma_has_circular(void)
+static inline bool dma_has_circular(void)
 {
 	return true;
 }
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 1122c8b..4f19eb3 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -98,7 +98,7 @@ enum dma_ch {
 	DMACH_MAX,
 };
 
-static inline bool s3c_dma_has_circular(void)
+static inline bool dma_has_circular(void)
 {
 	return true;
 }
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index f97110e..ec6b3dd 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -271,7 +271,9 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 
 	writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
+#if !defined(CONFIG_DMADEV_PL330)
 	s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
+#endif
 
 	return 0;
 }
@@ -317,7 +319,9 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
 
 	writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
+#if !defined(CONFIG_DMADEV_PL330)
 	s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
+#endif
 
 	return 0;
 }
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 5cb3b88..6ba0632 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -17,6 +17,11 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 
+#if defined(CONFIG_DMADEV_PL330)
+#include <linux/dmaengine.h>
+#include <linux/amba/pl330.h>
+#endif
+
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
 
@@ -62,6 +67,103 @@ struct runtime_data {
 	struct s3c_dma_params *params;
 };
 
+#if defined(CONFIG_DMADEV_PL330)
+static bool filter(struct dma_chan *chan, void *param)
+{
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)param;
+	struct runtime_data *prtd = substream->runtime->private_data;
+
+	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
+
+	if (peri->peri_id != prtd->params->channel)
+		return false;
+
+	/* dma client should fill fifo_addr */
+	peri->fifo_addr = prtd->params->dma_addr;
+
+	return true;
+}
+
+static void audio_buffdone(void *data)
+{
+	struct snd_pcm_substream *substream = data;
+	struct runtime_data *prtd;
+	struct dma_chan *chan;
+
+	prtd = substream->runtime->private_data;
+
+	chan = prtd->params->chan;
+	prtd->params->desc =
+		chan->device->device_prep_dma_cyclic(
+		chan, prtd->dma_pos, prtd->dma_period, prtd->dma_period,
+		substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+		DMA_TO_DEVICE : DMA_FROM_DEVICE);
+	if (!prtd->params->desc)
+		dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
+
+	prtd->params->desc->callback = audio_buffdone;
+	prtd->params->desc->callback_param = substream;
+	dmaengine_submit(prtd->params->desc);
+
+	prtd->dma_pos += prtd->dma_period;
+	if (prtd->dma_pos >= prtd->dma_end)
+		prtd->dma_pos = prtd->dma_start;
+
+	if (substream)
+		snd_pcm_period_elapsed(substream);
+}
+
+/* dma_enqueue
+ *
+ * place a dma buffer onto the queue for the dma system
+ * to handle.
+ */
+static void dma_enqueue(struct snd_pcm_substream *substream)
+{
+	struct runtime_data *prtd = substream->runtime->private_data;
+	dma_addr_t pos = prtd->dma_pos;
+	unsigned int limit;
+	struct dma_chan *chan = prtd->params->chan;
+
+	pr_debug("Entered %s\n", __func__);
+
+	limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
+
+	chan = prtd->params->chan;
+
+	while (prtd->dma_loaded < limit) {
+		unsigned long len = prtd->dma_period;
+
+		pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
+
+		if ((pos + len) > prtd->dma_end) {
+			len  = prtd->dma_end - pos;
+			pr_debug("%s: corrected dma len %ld\n",
+					__func__, len);
+		}
+
+		prtd->params->desc =
+			chan->device->device_prep_dma_cyclic(
+			chan, pos, prtd->dma_period, prtd->dma_period,
+			substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+			DMA_TO_DEVICE : DMA_FROM_DEVICE);
+		if (!prtd->params->desc)
+			dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
+
+		prtd->params->desc->callback = audio_buffdone;
+		prtd->params->desc->callback_param = substream;
+		dmaengine_submit(prtd->params->desc);
+
+		prtd->dma_loaded++;
+		pos += prtd->dma_period;
+		if (pos >= prtd->dma_end)
+			pos = prtd->dma_start;
+	}
+
+	prtd->dma_pos = pos;
+}
+
+#else
 /* dma_enqueue
  *
  * place a dma buffer onto the queue for the dma system
@@ -76,7 +178,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
 
 	pr_debug("Entered %s\n", __func__);
 
-	if (s3c_dma_has_circular())
+	if (dma_has_circular())
 		limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
 	else
 		limit = prtd->dma_limit;
@@ -127,13 +229,14 @@ static void audio_buffdone(struct s3c2410_dma_chan *channel,
 		snd_pcm_period_elapsed(substream);
 
 	spin_lock(&prtd->lock);
-	if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
+	if (prtd->state & ST_RUNNING && !dma_has_circular()) {
 		prtd->dma_loaded--;
 		dma_enqueue(substream);
 	}
 
 	spin_unlock(&prtd->lock);
 }
+#endif /* CONFIG_DMADEV_PL330 */
 
 static int dma_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
@@ -146,6 +249,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
 		snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 	int ret = 0;
 
+#if defined(CONFIG_DMADEV_PL330)
+	dma_cap_mask_t mask;
 
 	pr_debug("Entered %s\n", __func__);
 
@@ -154,6 +259,28 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
 	if (!dma)
 		return 0;
 
+	if (prtd->params == NULL) {
+		/* prepare DMA */
+		prtd->params = dma;
+
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_SLAVE, mask);
+		dma_cap_set(DMA_CYCLIC, mask);
+		prtd->params->chan =
+			dma_request_channel(mask, filter, substream);
+		if (!prtd->params->chan) {
+			printk(KERN_ERR "failed to get dma channel\n");
+			return ret;
+		}
+	}
+#else
+	pr_debug("Entered %s\n", __func__);
+
+	/* return if this is a bufferless transfer e.g.
+	 * codec <--> BT codec or GSM modem -- lg FIXME */
+	if (!dma)
+		return 0;
+
 	/* this may get called several times by oss emulation
 	 * with different params -HW */
 	if (prtd->params == NULL) {
@@ -172,14 +299,14 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
 		}
 
 		/* use the circular buffering if we have it available. */
-		if (s3c_dma_has_circular())
+		if (dma_has_circular())
 			s3c2410_dma_setflags(prtd->params->channel,
 					     S3C2410_DMAF_CIRCULAR);
 	}
 
 	s3c2410_dma_set_buffdone_fn(prtd->params->channel,
 				    audio_buffdone);
-
+#endif /* CONFIG_DMADEV_PL330 */
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
 	runtime->dma_bytes = totbytes;
@@ -206,7 +333,11 @@ static int dma_hw_free(struct snd_pcm_substream *substream)
 	snd_pcm_set_runtime_buffer(substream, NULL);
 
 	if (prtd->params) {
+#if defined(CONFIG_DMADEV_PL330)
+		dma_release_channel(prtd->params->chan);
+#else
 		s3c2410_dma_free(prtd->params->channel, prtd->params->client);
+#endif
 		prtd->params = NULL;
 	}
 
@@ -218,6 +349,33 @@ static int dma_prepare(struct snd_pcm_substream *substream)
 	struct runtime_data *prtd = substream->runtime->private_data;
 	int ret = 0;
 
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_chan *chan = prtd->params->chan;
+	struct dma_slave_config slave_config;
+
+	pr_debug("Entered %s\n", __func__);
+
+	/* return if this is a bufferless transfer e.g.
+	 * codec <--> BT codec or GSM modem -- lg FIXME */
+	if (!prtd->params)
+		return 0;
+
+	ret = dmaengine_terminate_all(chan);
+	if (ret)
+		dev_err(&chan->dev->device, "cannot flush dma channel\n");
+
+	memset(&slave_config, 0, sizeof(struct dma_slave_config));
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		slave_config.direction = DMA_TO_DEVICE;
+		slave_config.dst_addr_width = prtd->params->dma_size;
+	} else {
+		slave_config.direction = DMA_FROM_DEVICE;
+		slave_config.src_addr_width = prtd->params->dma_size;
+	}
+	ret = dmaengine_slave_config(chan, &slave_config);
+	if (ret)
+		dev_err(&chan->dev->device, "cannot config dma channel\n");
+#else
 	pr_debug("Entered %s\n", __func__);
 
 	/* return if this is a bufferless transfer e.g.
@@ -242,6 +400,7 @@ static int dma_prepare(struct snd_pcm_substream *substream)
 
 	/* flush the DMA channel */
 	s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
+#endif	/* CONFIG_DMADEV_PL330 */
 	prtd->dma_loaded = 0;
 	prtd->dma_pos = prtd->dma_start;
 
@@ -256,6 +415,33 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct runtime_data *prtd = substream->runtime->private_data;
 	int ret = 0;
 
+#if defined(CONFIG_DMADEV_PL330)
+	struct dma_chan *chan = prtd->params->chan;
+
+	pr_debug("Entered %s\n", __func__);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		prtd->state |= ST_RUNNING;
+		dma_async_issue_pending(prtd->params->chan);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		prtd->state &= ~ST_RUNNING;
+		ret = dmaengine_terminate_all(chan);
+		if (ret)
+			dev_err(&chan->dev->device, "cannot flush dma channel\n");
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+#else
 	pr_debug("Entered %s\n", __func__);
 
 	spin_lock(&prtd->lock);
@@ -281,6 +467,7 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
 	}
 
 	spin_unlock(&prtd->lock);
+#endif /* CONFIG_DMADEV_PL330 */
 
 	return ret;
 }
@@ -291,6 +478,14 @@ dma_pointer(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct runtime_data *prtd = runtime->private_data;
 	unsigned long res;
+
+#if defined(CONFIG_DMADEV_PL330)
+	pr_debug("Entered %s\n", __func__);
+
+	res = prtd->dma_pos - prtd->dma_start;
+
+	pr_debug("Pointer offset: %lu\n", res);
+#else
 	dma_addr_t src, dst;
 
 	pr_debug("Entered %s\n", __func__);
@@ -306,6 +501,7 @@ dma_pointer(struct snd_pcm_substream *substream)
 	spin_unlock(&prtd->lock);
 
 	pr_debug("Pointer %x %x\n", src, dst);
+#endif /* CONFIG_DMADEV_PL330 */
 
 	/* we seem to be getting the odd error from the pcm library due
 	 * to out-of-bounds pointers. this is maybe due to the dma engine
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index c506592..b6fae7e 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -17,6 +17,10 @@ struct s3c_dma_params {
 	int channel;				/* Channel ID */
 	dma_addr_t dma_addr;
 	int dma_size;			/* Size of the DMA transfer */
+#ifdef CONFIG_DMADEV_PL330
+	struct dma_chan *chan;
+	struct dma_async_tx_descriptor *desc;
+#endif
 };
 
 #endif
-- 
1.7.1

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-04 16:42     ` Grant Likely
  -1 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-04 16:42 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Vinod Koul, Dan Williams,
	Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> From: Boojin Kim <boojin.kim@samsung.com>
> 
> This patch adds to support DMA generic API to transfer raw
> SPI data. Basiclly the spi driver uses DMA generic API if
> architecture supports it. Otherwise, uses Samsung specific
> S3C-PL330 APIs.
> 
> Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> ---
>  drivers/spi/spi_s3c64xx.c |  234 +++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 194 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
> index 795828b..848487b 100644
> --- a/drivers/spi/spi_s3c64xx.c
> +++ b/drivers/spi/spi_s3c64xx.c
> @@ -26,6 +26,10 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/platform_device.h>
>  #include <linux/spi/spi.h>
> +#if defined(CONFIG_DMADEV_PL330)
> +#include <linux/dmaengine.h>
> +#include <linux/amba/pl330.h>
> +#endif

Is the #if protection really needed here?

>  
>  #include <mach/dma.h>
>  #include <plat/s3c64xx-spi.h>
> @@ -174,11 +178,19 @@ struct s3c64xx_spi_driver_data {
>  	unsigned                        state;
>  	unsigned                        cur_mode, cur_bpw;
>  	unsigned                        cur_speed;
> +#if defined(CONFIG_DMADEV_PL330)
> +	struct dma_chan *rx_chan;
> +	struct dma_chan *tx_chan;
> +	struct dma_async_tx_descriptor *rx_desc;
> +	struct dma_async_tx_descriptor *tx_desc;
> +#endif
>  };
>  
> +#if !defined(CONFIG_DMADEV_PL330)
>  static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
>  	.name = "samsung-spi-dma",
>  };
> +#endif
>  
>  static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
>  {
> @@ -229,6 +241,80 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
>  	writel(val, regs + S3C64XX_SPI_CH_CFG);
>  }
>  
> +#if defined(CONFIG_DMADEV_PL330)
> +static void s3c64xx_spi_dma_rxcb(void *data)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)data;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	sdd->state &= ~RXBUSY;
> +	/* If the other done */
> +	if (!(sdd->state & TXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +
> +static void s3c64xx_spi_dma_txcb(void *data)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)data;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	sdd->state &= ~TXBUSY;
> +	/* If the other done */
> +	if (!(sdd->state & RXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +#else
> +static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
> +				 int size, enum s3c2410_dma_buffresult res)
> +{
> +	struct s3c64xx_spi_driver_data *sdd = buf_id;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	if (res == S3C2410_RES_OK)
> +		sdd->state &= ~RXBUSY;
> +	else
> +		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
> +
> +	/* If the other done */
> +	if (!(sdd->state & TXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +
> +static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
> +				 int size, enum s3c2410_dma_buffresult res)
> +{
> +	struct s3c64xx_spi_driver_data *sdd = buf_id;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	if (res == S3C2410_RES_OK)
> +		sdd->state &= ~TXBUSY;
> +	else
> +		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d\n", size);
> +
> +	/* If the other done */
> +	if (!(sdd->state & RXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +#endif
> +
>  static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  				struct spi_device *spi,
>  				struct spi_transfer *xfer, int dma_mode)
> @@ -236,6 +322,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
>  	void __iomem *regs = sdd->regs;
>  	u32 modecfg, chcfg;
> +#if defined(CONFIG_DMADEV_PL330)
> +	struct dma_slave_config slave_config;
> +	struct scatterlist tx_sg;
> +	struct scatterlist rx_sg;
> +#endif
>  
>  	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
>  	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
> @@ -261,10 +352,34 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
>  		if (dma_mode) {
>  			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
> +#if defined(CONFIG_DMADEV_PL330)
> +			memset(&slave_config, 0, sizeof(slave_config));
> +			slave_config.direction = DMA_TO_DEVICE;
> +			slave_config.src_addr = xfer->tx_dma;
> +			slave_config.dst_addr =
> +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> +
> +			sg_init_table(&tx_sg, 1);
> +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> +				xfer->len, offset_in_page(xfer->tx_dma));
> +			sg_dma_len(&tx_sg) =  xfer->len;
> +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> +			sdd->tx_desc =
> +				sdd->tx_chan->device->device_prep_slave_sg(
> +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> +			sdd->tx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->tx_desc);
> +			dma_async_issue_pending(sdd->tx_chan);
> +#else
>  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
>  						xfer->tx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> +#endif

Hmmm, this is not pretty.  The driver behaviour is entirely different depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to multiplatform kernels, is this going to break on some hardware?

>  		} else {
>  			switch (sdd->cur_bpw) {
>  			case 32:
> @@ -296,10 +411,33 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
>  					| S3C64XX_SPI_PACKET_CNT_EN,
>  					regs + S3C64XX_SPI_PACKET_CNT);
> +#if defined(CONFIG_DMADEV_PL330)
> +			slave_config.direction = DMA_FROM_DEVICE;
> +			slave_config.dst_addr = xfer->rx_dma;
> +			slave_config.src_addr =
> +				sdd->sfr_start + S3C64XX_SPI_RX_DATA;
> +			slave_config.src_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->rx_chan, &slave_config);
> +
> +			sg_init_table(&rx_sg, 1);
> +			sg_set_page(&rx_sg, pfn_to_page(PFN_DOWN(xfer->rx_dma)),
> +				xfer->len, offset_in_page(xfer->rx_dma));
> +			sg_dma_len(&rx_sg) =  xfer->len;
> +			sg_dma_address(&rx_sg) = xfer->rx_dma;
> +			sdd->rx_desc =
> +				sdd->rx_chan->device->device_prep_slave_sg(
> +				sdd->rx_chan, &rx_sg, 1, DMA_FROM_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->rx_desc->callback = s3c64xx_spi_dma_rxcb;
> +			sdd->rx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->rx_desc);
> +			dma_async_issue_pending(sdd->rx_chan);
> +#else
>  			s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
>  						xfer->rx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
> +#endif
>  		}
>  	}
>  
> @@ -485,46 +623,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
>  	}
>  }
>  
> -static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
> -				 int size, enum s3c2410_dma_buffresult res)
> -{
> -	struct s3c64xx_spi_driver_data *sdd = buf_id;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&sdd->lock, flags);
> -
> -	if (res == S3C2410_RES_OK)
> -		sdd->state &= ~RXBUSY;
> -	else
> -		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
> -
> -	/* If the other done */
> -	if (!(sdd->state & TXBUSY))
> -		complete(&sdd->xfer_completion);
> -
> -	spin_unlock_irqrestore(&sdd->lock, flags);
> -}
> -
> -static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
> -				 int size, enum s3c2410_dma_buffresult res)
> -{
> -	struct s3c64xx_spi_driver_data *sdd = buf_id;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&sdd->lock, flags);
> -
> -	if (res == S3C2410_RES_OK)
> -		sdd->state &= ~TXBUSY;
> -	else
> -		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
> -
> -	/* If the other done */
> -	if (!(sdd->state & RXBUSY))
> -		complete(&sdd->xfer_completion);
> -
> -	spin_unlock_irqrestore(&sdd->lock, flags);
> -}
> -
>  #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
>  
>  static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
> @@ -699,12 +797,20 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
>  			if (use_dma) {
>  				if (xfer->tx_buf != NULL
>  						&& (sdd->state & TXBUSY))
> +#if defined(CONFIG_DMADEV_PL330)
> +					dmaengine_terminate_all(sdd->tx_chan);
> +#else
>  					s3c2410_dma_ctrl(sdd->tx_dmach,
>  							S3C2410_DMAOP_FLUSH);
> +#endif
>  				if (xfer->rx_buf != NULL
>  						&& (sdd->state & RXBUSY))
> +#if defined(CONFIG_DMADEV_PL330)
> +					dmaengine_terminate_all(sdd->rx_chan);
> +#else
>  					s3c2410_dma_ctrl(sdd->rx_dmach,
>  							S3C2410_DMAOP_FLUSH);
> +#endif
>  			}
>  
>  			goto out;
> @@ -742,8 +848,50 @@ out:
>  		msg->complete(msg->context);
>  }
>  
> +#if defined(CONFIG_DMADEV_PL330)
> +static bool rxfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->rx_dmach)
> +		return false;
> +
> +	return true;
> +}
> +static bool txfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->tx_dmach)
> +		return false;
> +
> +	return true;
> +}
> +#endif
> +
>  static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
>  {
> +#if defined(CONFIG_DMADEV_PL330)
> +	dma_cap_mask_t mask;
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_SLAVE, mask);
> +	sdd->rx_chan =
> +		dma_request_channel(mask, rxfilter, (void *)sdd);
> +	if (!sdd->rx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> +		return 0;
> +	}
> +	sdd->tx_chan =
> +		dma_request_channel(mask, txfilter, (void *)sdd);
> +	if (!sdd->tx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
> +		return 0;
> +	}
> +#else
>  	if (s3c2410_dma_request(sdd->rx_dmach,
>  					&s3c64xx_spi_dma_client, NULL) < 0) {
>  		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> @@ -762,6 +910,7 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
>  	s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
>  	s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
>  					sdd->sfr_start + S3C64XX_SPI_TX_DATA);
> +#endif
>  
>  	return 1;
>  }
> @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct *work)
>  	spin_unlock_irqrestore(&sdd->lock, flags);
>  
>  	/* Free DMA channels */
> +#if defined(CONFIG_DMADEV_PL330)
> +	dma_release_channel(sdd->tx_chan);
> +	dma_release_channel(sdd->rx_chan);
> +#else
>  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
>  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> +#endif

Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
selected?  If so, can they be removed entirely, or are they required
to support certain hardware?

g.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-04 16:42     ` Grant Likely
  0 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-04 16:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> From: Boojin Kim <boojin.kim@samsung.com>
> 
> This patch adds to support DMA generic API to transfer raw
> SPI data. Basiclly the spi driver uses DMA generic API if
> architecture supports it. Otherwise, uses Samsung specific
> S3C-PL330 APIs.
> 
> Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> ---
>  drivers/spi/spi_s3c64xx.c |  234 +++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 194 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
> index 795828b..848487b 100644
> --- a/drivers/spi/spi_s3c64xx.c
> +++ b/drivers/spi/spi_s3c64xx.c
> @@ -26,6 +26,10 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/platform_device.h>
>  #include <linux/spi/spi.h>
> +#if defined(CONFIG_DMADEV_PL330)
> +#include <linux/dmaengine.h>
> +#include <linux/amba/pl330.h>
> +#endif

Is the #if protection really needed here?

>  
>  #include <mach/dma.h>
>  #include <plat/s3c64xx-spi.h>
> @@ -174,11 +178,19 @@ struct s3c64xx_spi_driver_data {
>  	unsigned                        state;
>  	unsigned                        cur_mode, cur_bpw;
>  	unsigned                        cur_speed;
> +#if defined(CONFIG_DMADEV_PL330)
> +	struct dma_chan *rx_chan;
> +	struct dma_chan *tx_chan;
> +	struct dma_async_tx_descriptor *rx_desc;
> +	struct dma_async_tx_descriptor *tx_desc;
> +#endif
>  };
>  
> +#if !defined(CONFIG_DMADEV_PL330)
>  static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
>  	.name = "samsung-spi-dma",
>  };
> +#endif
>  
>  static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
>  {
> @@ -229,6 +241,80 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
>  	writel(val, regs + S3C64XX_SPI_CH_CFG);
>  }
>  
> +#if defined(CONFIG_DMADEV_PL330)
> +static void s3c64xx_spi_dma_rxcb(void *data)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)data;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	sdd->state &= ~RXBUSY;
> +	/* If the other done */
> +	if (!(sdd->state & TXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +
> +static void s3c64xx_spi_dma_txcb(void *data)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)data;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	sdd->state &= ~TXBUSY;
> +	/* If the other done */
> +	if (!(sdd->state & RXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +#else
> +static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
> +				 int size, enum s3c2410_dma_buffresult res)
> +{
> +	struct s3c64xx_spi_driver_data *sdd = buf_id;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	if (res == S3C2410_RES_OK)
> +		sdd->state &= ~RXBUSY;
> +	else
> +		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
> +
> +	/* If the other done */
> +	if (!(sdd->state & TXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +
> +static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
> +				 int size, enum s3c2410_dma_buffresult res)
> +{
> +	struct s3c64xx_spi_driver_data *sdd = buf_id;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&sdd->lock, flags);
> +
> +	if (res == S3C2410_RES_OK)
> +		sdd->state &= ~TXBUSY;
> +	else
> +		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d\n", size);
> +
> +	/* If the other done */
> +	if (!(sdd->state & RXBUSY))
> +		complete(&sdd->xfer_completion);
> +
> +	spin_unlock_irqrestore(&sdd->lock, flags);
> +}
> +#endif
> +
>  static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  				struct spi_device *spi,
>  				struct spi_transfer *xfer, int dma_mode)
> @@ -236,6 +322,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
>  	void __iomem *regs = sdd->regs;
>  	u32 modecfg, chcfg;
> +#if defined(CONFIG_DMADEV_PL330)
> +	struct dma_slave_config slave_config;
> +	struct scatterlist tx_sg;
> +	struct scatterlist rx_sg;
> +#endif
>  
>  	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
>  	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
> @@ -261,10 +352,34 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
>  		if (dma_mode) {
>  			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
> +#if defined(CONFIG_DMADEV_PL330)
> +			memset(&slave_config, 0, sizeof(slave_config));
> +			slave_config.direction = DMA_TO_DEVICE;
> +			slave_config.src_addr = xfer->tx_dma;
> +			slave_config.dst_addr =
> +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> +
> +			sg_init_table(&tx_sg, 1);
> +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> +				xfer->len, offset_in_page(xfer->tx_dma));
> +			sg_dma_len(&tx_sg) =  xfer->len;
> +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> +			sdd->tx_desc =
> +				sdd->tx_chan->device->device_prep_slave_sg(
> +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> +			sdd->tx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->tx_desc);
> +			dma_async_issue_pending(sdd->tx_chan);
> +#else
>  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
>  						xfer->tx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> +#endif

Hmmm, this is not pretty.  The driver behaviour is entirely different depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to multiplatform kernels, is this going to break on some hardware?

>  		} else {
>  			switch (sdd->cur_bpw) {
>  			case 32:
> @@ -296,10 +411,33 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
>  					| S3C64XX_SPI_PACKET_CNT_EN,
>  					regs + S3C64XX_SPI_PACKET_CNT);
> +#if defined(CONFIG_DMADEV_PL330)
> +			slave_config.direction = DMA_FROM_DEVICE;
> +			slave_config.dst_addr = xfer->rx_dma;
> +			slave_config.src_addr =
> +				sdd->sfr_start + S3C64XX_SPI_RX_DATA;
> +			slave_config.src_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->rx_chan, &slave_config);
> +
> +			sg_init_table(&rx_sg, 1);
> +			sg_set_page(&rx_sg, pfn_to_page(PFN_DOWN(xfer->rx_dma)),
> +				xfer->len, offset_in_page(xfer->rx_dma));
> +			sg_dma_len(&rx_sg) =  xfer->len;
> +			sg_dma_address(&rx_sg) = xfer->rx_dma;
> +			sdd->rx_desc =
> +				sdd->rx_chan->device->device_prep_slave_sg(
> +				sdd->rx_chan, &rx_sg, 1, DMA_FROM_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->rx_desc->callback = s3c64xx_spi_dma_rxcb;
> +			sdd->rx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->rx_desc);
> +			dma_async_issue_pending(sdd->rx_chan);
> +#else
>  			s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
>  						xfer->rx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
> +#endif
>  		}
>  	}
>  
> @@ -485,46 +623,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
>  	}
>  }
>  
> -static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
> -				 int size, enum s3c2410_dma_buffresult res)
> -{
> -	struct s3c64xx_spi_driver_data *sdd = buf_id;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&sdd->lock, flags);
> -
> -	if (res == S3C2410_RES_OK)
> -		sdd->state &= ~RXBUSY;
> -	else
> -		dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
> -
> -	/* If the other done */
> -	if (!(sdd->state & TXBUSY))
> -		complete(&sdd->xfer_completion);
> -
> -	spin_unlock_irqrestore(&sdd->lock, flags);
> -}
> -
> -static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
> -				 int size, enum s3c2410_dma_buffresult res)
> -{
> -	struct s3c64xx_spi_driver_data *sdd = buf_id;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&sdd->lock, flags);
> -
> -	if (res == S3C2410_RES_OK)
> -		sdd->state &= ~TXBUSY;
> -	else
> -		dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
> -
> -	/* If the other done */
> -	if (!(sdd->state & RXBUSY))
> -		complete(&sdd->xfer_completion);
> -
> -	spin_unlock_irqrestore(&sdd->lock, flags);
> -}
> -
>  #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
>  
>  static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
> @@ -699,12 +797,20 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
>  			if (use_dma) {
>  				if (xfer->tx_buf != NULL
>  						&& (sdd->state & TXBUSY))
> +#if defined(CONFIG_DMADEV_PL330)
> +					dmaengine_terminate_all(sdd->tx_chan);
> +#else
>  					s3c2410_dma_ctrl(sdd->tx_dmach,
>  							S3C2410_DMAOP_FLUSH);
> +#endif
>  				if (xfer->rx_buf != NULL
>  						&& (sdd->state & RXBUSY))
> +#if defined(CONFIG_DMADEV_PL330)
> +					dmaengine_terminate_all(sdd->rx_chan);
> +#else
>  					s3c2410_dma_ctrl(sdd->rx_dmach,
>  							S3C2410_DMAOP_FLUSH);
> +#endif
>  			}
>  
>  			goto out;
> @@ -742,8 +848,50 @@ out:
>  		msg->complete(msg->context);
>  }
>  
> +#if defined(CONFIG_DMADEV_PL330)
> +static bool rxfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->rx_dmach)
> +		return false;
> +
> +	return true;
> +}
> +static bool txfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->tx_dmach)
> +		return false;
> +
> +	return true;
> +}
> +#endif
> +
>  static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
>  {
> +#if defined(CONFIG_DMADEV_PL330)
> +	dma_cap_mask_t mask;
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_SLAVE, mask);
> +	sdd->rx_chan =
> +		dma_request_channel(mask, rxfilter, (void *)sdd);
> +	if (!sdd->rx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> +		return 0;
> +	}
> +	sdd->tx_chan =
> +		dma_request_channel(mask, txfilter, (void *)sdd);
> +	if (!sdd->tx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
> +		return 0;
> +	}
> +#else
>  	if (s3c2410_dma_request(sdd->rx_dmach,
>  					&s3c64xx_spi_dma_client, NULL) < 0) {
>  		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> @@ -762,6 +910,7 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
>  	s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
>  	s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
>  					sdd->sfr_start + S3C64XX_SPI_TX_DATA);
> +#endif
>  
>  	return 1;
>  }
> @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct *work)
>  	spin_unlock_irqrestore(&sdd->lock, flags);
>  
>  	/* Free DMA channels */
> +#if defined(CONFIG_DMADEV_PL330)
> +	dma_release_channel(sdd->tx_chan);
> +	dma_release_channel(sdd->rx_chan);
> +#else
>  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
>  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> +#endif

Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
selected?  If so, can they be removed entirely, or are they required
to support certain hardware?

g.

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 16:42     ` Grant Likely
@ 2011-07-04 16:56       ` Mark Brown
  -1 siblings, 0 replies; 86+ messages in thread
From: Mark Brown @ 2011-07-04 16:56 UTC (permalink / raw)
  To: Grant Likely
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Jassi Brar, Liam Girdwood, Boojin Kim

On Mon, Jul 04, 2011 at 10:42:51AM -0600, Grant Likely wrote:

> Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> selected?  If so, can they be removed entirely, or are they required
> to support certain hardware?

My question was going to be if we should split this up into two
different drivers for pretty much these reasons.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-04 16:56       ` Mark Brown
  0 siblings, 0 replies; 86+ messages in thread
From: Mark Brown @ 2011-07-04 16:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 10:42:51AM -0600, Grant Likely wrote:

> Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> selected?  If so, can they be removed entirely, or are they required
> to support certain hardware?

My question was going to be if we should split this up into two
different drivers for pretty much these reasons.

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 16:42     ` Grant Likely
@ 2011-07-04 16:59       ` Heiko Stübner
  -1 siblings, 0 replies; 86+ messages in thread
From: Heiko Stübner @ 2011-07-04 16:59 UTC (permalink / raw)
  To: Grant Likely
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > +#if defined(CONFIG_DMADEV_PL330)
> > +			memset(&slave_config, 0, sizeof(slave_config));
> > +			slave_config.direction = DMA_TO_DEVICE;
> > +			slave_config.src_addr = xfer->tx_dma;
> > +			slave_config.dst_addr =
> > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > +
> > +			sg_init_table(&tx_sg, 1);
> > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> > +				xfer->len, offset_in_page(xfer->tx_dma));
> > +			sg_dma_len(&tx_sg) =  xfer->len;
> > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > +			sdd->tx_desc =
> > +				sdd->tx_chan->device->device_prep_slave_sg(
> > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > +				DMA_PREP_INTERRUPT);
> > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > +			sdd->tx_desc->callback_param = sdd;
> > +			dmaengine_submit(sdd->tx_desc);
> > +			dma_async_issue_pending(sdd->tx_chan);
> > +#else
> > 
> >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> >  			
> >  						xfer->tx_dma, xfer->len);
> >  			
> >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > 
> > +#endif
> 
> Hmmm, this is not pretty.  The driver behaviour is entirely different
> depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> multiplatform kernels, is this going to break on some hardware?

> > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > *work)
> > 
> >  	spin_unlock_irqrestore(&sdd->lock, flags);
> >  	
> >  	/* Free DMA channels */
> > 
> > +#if defined(CONFIG_DMADEV_PL330)
> > +	dma_release_channel(sdd->tx_chan);
> > +	dma_release_channel(sdd->rx_chan);
> > +#else
> > 
> >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > 
> > +#endif
> 
> Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> selected?  If so, can they be removed entirely, or are they required
> to support certain hardware?

The spi_s3c64xx driver can also support the SPI controller of the 
S3C2416/S3C2443 line of SoCs.
As I'm currently working on a S3C2416 based project, my small wish from the 
sidelines would be to not break this support with whatever solution you will 
decide on :-) .


Thanks
Heiko

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-04 16:59       ` Heiko Stübner
  0 siblings, 0 replies; 86+ messages in thread
From: Heiko Stübner @ 2011-07-04 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > +#if defined(CONFIG_DMADEV_PL330)
> > +			memset(&slave_config, 0, sizeof(slave_config));
> > +			slave_config.direction = DMA_TO_DEVICE;
> > +			slave_config.src_addr = xfer->tx_dma;
> > +			slave_config.dst_addr =
> > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > +
> > +			sg_init_table(&tx_sg, 1);
> > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> > +				xfer->len, offset_in_page(xfer->tx_dma));
> > +			sg_dma_len(&tx_sg) =  xfer->len;
> > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > +			sdd->tx_desc =
> > +				sdd->tx_chan->device->device_prep_slave_sg(
> > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > +				DMA_PREP_INTERRUPT);
> > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > +			sdd->tx_desc->callback_param = sdd;
> > +			dmaengine_submit(sdd->tx_desc);
> > +			dma_async_issue_pending(sdd->tx_chan);
> > +#else
> > 
> >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> >  			
> >  						xfer->tx_dma, xfer->len);
> >  			
> >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > 
> > +#endif
> 
> Hmmm, this is not pretty.  The driver behaviour is entirely different
> depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> multiplatform kernels, is this going to break on some hardware?

> > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > *work)
> > 
> >  	spin_unlock_irqrestore(&sdd->lock, flags);
> >  	
> >  	/* Free DMA channels */
> > 
> > +#if defined(CONFIG_DMADEV_PL330)
> > +	dma_release_channel(sdd->tx_chan);
> > +	dma_release_channel(sdd->rx_chan);
> > +#else
> > 
> >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > 
> > +#endif
> 
> Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> selected?  If so, can they be removed entirely, or are they required
> to support certain hardware?

The spi_s3c64xx driver can also support the SPI controller of the 
S3C2416/S3C2443 line of SoCs.
As I'm currently working on a S3C2416 based project, my small wish from the 
sidelines would be to not break this support with whatever solution you will 
decide on :-) .


Thanks
Heiko

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 16:59       ` Heiko Stübner
@ 2011-07-04 17:02         ` Grant Likely
  -1 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-04 17:02 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko Stübner wrote:
> Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > > +#if defined(CONFIG_DMADEV_PL330)
> > > +			memset(&slave_config, 0, sizeof(slave_config));
> > > +			slave_config.direction = DMA_TO_DEVICE;
> > > +			slave_config.src_addr = xfer->tx_dma;
> > > +			slave_config.dst_addr =
> > > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > > +
> > > +			sg_init_table(&tx_sg, 1);
> > > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> > > +				xfer->len, offset_in_page(xfer->tx_dma));
> > > +			sg_dma_len(&tx_sg) =  xfer->len;
> > > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > > +			sdd->tx_desc =
> > > +				sdd->tx_chan->device->device_prep_slave_sg(
> > > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > > +				DMA_PREP_INTERRUPT);
> > > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > > +			sdd->tx_desc->callback_param = sdd;
> > > +			dmaengine_submit(sdd->tx_desc);
> > > +			dma_async_issue_pending(sdd->tx_chan);
> > > +#else
> > > 
> > >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> > >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> > >  			
> > >  						xfer->tx_dma, xfer->len);
> > >  			
> > >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > > 
> > > +#endif
> > 
> > Hmmm, this is not pretty.  The driver behaviour is entirely different
> > depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> > multiplatform kernels, is this going to break on some hardware?
> 
> > > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > > *work)
> > > 
> > >  	spin_unlock_irqrestore(&sdd->lock, flags);
> > >  	
> > >  	/* Free DMA channels */
> > > 
> > > +#if defined(CONFIG_DMADEV_PL330)
> > > +	dma_release_channel(sdd->tx_chan);
> > > +	dma_release_channel(sdd->rx_chan);
> > > +#else
> > > 
> > >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> > >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > > 
> > > +#endif
> > 
> > Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> > selected?  If so, can they be removed entirely, or are they required
> > to support certain hardware?
> 
> The spi_s3c64xx driver can also support the SPI controller of the 
> S3C2416/S3C2443 line of SoCs.
> As I'm currently working on a S3C2416 based project, my small wish from the 
> sidelines would be to not break this support with whatever solution you will 
> decide on :-) .

I will not merge a patch that either breaks a platform, or requires
a compile time either/or choice of device support (enabling support
for one device should not break support for another).

g.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-04 17:02         ` Grant Likely
  0 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-04 17:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko St?bner wrote:
> Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > > +#if defined(CONFIG_DMADEV_PL330)
> > > +			memset(&slave_config, 0, sizeof(slave_config));
> > > +			slave_config.direction = DMA_TO_DEVICE;
> > > +			slave_config.src_addr = xfer->tx_dma;
> > > +			slave_config.dst_addr =
> > > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > > +
> > > +			sg_init_table(&tx_sg, 1);
> > > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> > > +				xfer->len, offset_in_page(xfer->tx_dma));
> > > +			sg_dma_len(&tx_sg) =  xfer->len;
> > > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > > +			sdd->tx_desc =
> > > +				sdd->tx_chan->device->device_prep_slave_sg(
> > > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > > +				DMA_PREP_INTERRUPT);
> > > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > > +			sdd->tx_desc->callback_param = sdd;
> > > +			dmaengine_submit(sdd->tx_desc);
> > > +			dma_async_issue_pending(sdd->tx_chan);
> > > +#else
> > > 
> > >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> > >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> > >  			
> > >  						xfer->tx_dma, xfer->len);
> > >  			
> > >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > > 
> > > +#endif
> > 
> > Hmmm, this is not pretty.  The driver behaviour is entirely different
> > depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> > multiplatform kernels, is this going to break on some hardware?
> 
> > > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > > *work)
> > > 
> > >  	spin_unlock_irqrestore(&sdd->lock, flags);
> > >  	
> > >  	/* Free DMA channels */
> > > 
> > > +#if defined(CONFIG_DMADEV_PL330)
> > > +	dma_release_channel(sdd->tx_chan);
> > > +	dma_release_channel(sdd->rx_chan);
> > > +#else
> > > 
> > >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> > >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > > 
> > > +#endif
> > 
> > Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> > selected?  If so, can they be removed entirely, or are they required
> > to support certain hardware?
> 
> The spi_s3c64xx driver can also support the SPI controller of the 
> S3C2416/S3C2443 line of SoCs.
> As I'm currently working on a S3C2416 based project, my small wish from the 
> sidelines would be to not break this support with whatever solution you will 
> decide on :-) .

I will not merge a patch that either breaks a platform, or requires
a compile time either/or choice of device support (enabling support
for one device should not break support for another).

g.

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

* Re: [PATCH 7/7] ASoC: Samsung: Update DMA interface
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-04 17:03     ` Mark Brown
  -1 siblings, 0 replies; 86+ messages in thread
From: Mark Brown @ 2011-07-04 17:03 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Vinod Koul, Dan Williams,
	Grant Likely, Jassi Brar, Liam Girdwood, Boojin Kim

On Mon, Jul 04, 2011 at 09:18:35PM +0900, Kukjin Kim wrote:

> +static void audio_buffdone(void *data)
> +{
> +	struct snd_pcm_substream *substream = data;
> +	struct runtime_data *prtd;
> +	struct dma_chan *chan;
> +
> +	prtd = substream->runtime->private_data;
> +
> +	chan = prtd->params->chan;
> +	prtd->params->desc =
> +		chan->device->device_prep_dma_cyclic(
> +		chan, prtd->dma_pos, prtd->dma_period, prtd->dma_period,
> +		substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
> +		DMA_TO_DEVICE : DMA_FROM_DEVICE);
> +	if (!prtd->params->desc)
> +		dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
> +
> +	prtd->params->desc->callback = audio_buffdone;
> +	prtd->params->desc->callback_param = substream;
> +	dmaengine_submit(prtd->params->desc);
> +
> +	prtd->dma_pos += prtd->dma_period;
> +	if (prtd->dma_pos >= prtd->dma_end)
> +		prtd->dma_pos = prtd->dma_start;
> +
> +	if (substream)
> +		snd_pcm_period_elapsed(substream);
> +}

Two questions here:

- It looks like a lot of this code can be shared between all the drivers
  using the dmaengine API.  Is there any reason not to factor it out?
- Should this not be adding a new driver for dmaengine based Samsung
  CPUs?  The ifdefs are very big.

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

* [PATCH 7/7] ASoC: Samsung: Update DMA interface
@ 2011-07-04 17:03     ` Mark Brown
  0 siblings, 0 replies; 86+ messages in thread
From: Mark Brown @ 2011-07-04 17:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 09:18:35PM +0900, Kukjin Kim wrote:

> +static void audio_buffdone(void *data)
> +{
> +	struct snd_pcm_substream *substream = data;
> +	struct runtime_data *prtd;
> +	struct dma_chan *chan;
> +
> +	prtd = substream->runtime->private_data;
> +
> +	chan = prtd->params->chan;
> +	prtd->params->desc =
> +		chan->device->device_prep_dma_cyclic(
> +		chan, prtd->dma_pos, prtd->dma_period, prtd->dma_period,
> +		substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
> +		DMA_TO_DEVICE : DMA_FROM_DEVICE);
> +	if (!prtd->params->desc)
> +		dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
> +
> +	prtd->params->desc->callback = audio_buffdone;
> +	prtd->params->desc->callback_param = substream;
> +	dmaengine_submit(prtd->params->desc);
> +
> +	prtd->dma_pos += prtd->dma_period;
> +	if (prtd->dma_pos >= prtd->dma_end)
> +		prtd->dma_pos = prtd->dma_start;
> +
> +	if (substream)
> +		snd_pcm_period_elapsed(substream);
> +}

Two questions here:

- It looks like a lot of this code can be shared between all the drivers
  using the dmaengine API.  Is there any reason not to factor it out?
- Should this not be adding a new driver for dmaengine based Samsung
  CPUs?  The ifdefs are very big.

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 17:02         ` Grant Likely
@ 2011-07-04 19:51           ` Heiko Stübner
  -1 siblings, 0 replies; 86+ messages in thread
From: Heiko Stübner @ 2011-07-04 19:51 UTC (permalink / raw)
  To: Grant Likely
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
> On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko Stübner wrote:
> > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > > On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > +			memset(&slave_config, 0, sizeof(slave_config));
> > > > +			slave_config.direction = DMA_TO_DEVICE;
> > > > +			slave_config.src_addr = xfer->tx_dma;
> > > > +			slave_config.dst_addr =
> > > > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > > > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > > > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > > > +
> > > > +			sg_init_table(&tx_sg, 1);
> > > > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer-
>tx_dma)),
> > > > +				xfer->len, offset_in_page(xfer->tx_dma));
> > > > +			sg_dma_len(&tx_sg) =  xfer->len;
> > > > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > > > +			sdd->tx_desc =
> > > > +				sdd->tx_chan->device->device_prep_slave_sg(
> > > > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > > > +				DMA_PREP_INTERRUPT);
> > > > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > > > +			sdd->tx_desc->callback_param = sdd;
> > > > +			dmaengine_submit(sdd->tx_desc);
> > > > +			dma_async_issue_pending(sdd->tx_chan);
> > > > +#else
> > > > 
> > > >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> > > >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> > > >  			
> > > >  						xfer->tx_dma, xfer->len);
> > > >  			
> > > >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > > > 
> > > > +#endif
> > > 
> > > Hmmm, this is not pretty.  The driver behaviour is entirely different
> > > depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> > > multiplatform kernels, is this going to break on some hardware?
> > > 
> > > > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > > > *work)
> > > > 
> > > >  	spin_unlock_irqrestore(&sdd->lock, flags);
> > > >  	
> > > >  	/* Free DMA channels */
> > > > 
> > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > +	dma_release_channel(sdd->tx_chan);
> > > > +	dma_release_channel(sdd->rx_chan);
> > > > +#else
> > > > 
> > > >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> > > >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > > > 
> > > > +#endif
> > > 
> > > Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> > > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> > > selected?  If so, can they be removed entirely, or are they required
> > > to support certain hardware?
> > 
> > The spi_s3c64xx driver can also support the SPI controller of the
> > S3C2416/S3C2443 line of SoCs.
> > As I'm currently working on a S3C2416 based project, my small wish from
> > the sidelines would be to not break this support with whatever solution
> > you will decide on :-) .
> 
> I will not merge a patch that either breaks a platform, or requires
> a compile time either/or choice of device support (enabling support
> for one device should not break support for another).

The patch above seems to contain the support for both SoCs (i.e. s3c2410_dma_* 
for S3C2416 etc), so it wouldn't break the support.
But this form will definitly break future multiplatform kernels when the 2416 
and some variant using the DMADEV_PL330 are selected at the same time.

The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller of 
this type. Implementing the DMA engine stuff for these SoCs would obviously 
solve the ifdef-problem but I don't know if this is possible to do.


Heiko

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-04 19:51           ` Heiko Stübner
  0 siblings, 0 replies; 86+ messages in thread
From: Heiko Stübner @ 2011-07-04 19:51 UTC (permalink / raw)
  To: linux-arm-kernel

Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
> On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko St?bner wrote:
> > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > > On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > +			memset(&slave_config, 0, sizeof(slave_config));
> > > > +			slave_config.direction = DMA_TO_DEVICE;
> > > > +			slave_config.src_addr = xfer->tx_dma;
> > > > +			slave_config.dst_addr =
> > > > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > > > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > > > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > > > +
> > > > +			sg_init_table(&tx_sg, 1);
> > > > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer-
>tx_dma)),
> > > > +				xfer->len, offset_in_page(xfer->tx_dma));
> > > > +			sg_dma_len(&tx_sg) =  xfer->len;
> > > > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > > > +			sdd->tx_desc =
> > > > +				sdd->tx_chan->device->device_prep_slave_sg(
> > > > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > > > +				DMA_PREP_INTERRUPT);
> > > > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > > > +			sdd->tx_desc->callback_param = sdd;
> > > > +			dmaengine_submit(sdd->tx_desc);
> > > > +			dma_async_issue_pending(sdd->tx_chan);
> > > > +#else
> > > > 
> > > >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> > > >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> > > >  			
> > > >  						xfer->tx_dma, xfer->len);
> > > >  			
> > > >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > > > 
> > > > +#endif
> > > 
> > > Hmmm, this is not pretty.  The driver behaviour is entirely different
> > > depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> > > multiplatform kernels, is this going to break on some hardware?
> > > 
> > > > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > > > *work)
> > > > 
> > > >  	spin_unlock_irqrestore(&sdd->lock, flags);
> > > >  	
> > > >  	/* Free DMA channels */
> > > > 
> > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > +	dma_release_channel(sdd->tx_chan);
> > > > +	dma_release_channel(sdd->rx_chan);
> > > > +#else
> > > > 
> > > >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> > > >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > > > 
> > > > +#endif
> > > 
> > > Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> > > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> > > selected?  If so, can they be removed entirely, or are they required
> > > to support certain hardware?
> > 
> > The spi_s3c64xx driver can also support the SPI controller of the
> > S3C2416/S3C2443 line of SoCs.
> > As I'm currently working on a S3C2416 based project, my small wish from
> > the sidelines would be to not break this support with whatever solution
> > you will decide on :-) .
> 
> I will not merge a patch that either breaks a platform, or requires
> a compile time either/or choice of device support (enabling support
> for one device should not break support for another).

The patch above seems to contain the support for both SoCs (i.e. s3c2410_dma_* 
for S3C2416 etc), so it wouldn't break the support.
But this form will definitly break future multiplatform kernels when the 2416 
and some variant using the DMADEV_PL330 are selected at the same time.

The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller of 
this type. Implementing the DMA engine stuff for these SoCs would obviously 
solve the ifdef-problem but I don't know if this is possible to do.


Heiko

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 19:51           ` Heiko Stübner
@ 2011-07-04 23:27             ` Grant Likely
  -1 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-04 23:27 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

On Mon, Jul 04, 2011 at 09:51:43PM +0200, Heiko Stübner wrote:
> Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
> > On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko Stübner wrote:
> > > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > > > On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > > +			memset(&slave_config, 0, sizeof(slave_config));
> > > > > +			slave_config.direction = DMA_TO_DEVICE;
> > > > > +			slave_config.src_addr = xfer->tx_dma;
> > > > > +			slave_config.dst_addr =
> > > > > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > > > > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > > > > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > > > > +
> > > > > +			sg_init_table(&tx_sg, 1);
> > > > > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer-
> >tx_dma)),
> > > > > +				xfer->len, offset_in_page(xfer->tx_dma));
> > > > > +			sg_dma_len(&tx_sg) =  xfer->len;
> > > > > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > > > > +			sdd->tx_desc =
> > > > > +				sdd->tx_chan->device->device_prep_slave_sg(
> > > > > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > > > > +				DMA_PREP_INTERRUPT);
> > > > > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > > > > +			sdd->tx_desc->callback_param = sdd;
> > > > > +			dmaengine_submit(sdd->tx_desc);
> > > > > +			dma_async_issue_pending(sdd->tx_chan);
> > > > > +#else
> > > > > 
> > > > >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> > > > >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> > > > >  			
> > > > >  						xfer->tx_dma, xfer->len);
> > > > >  			
> > > > >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > > > > 
> > > > > +#endif
> > > > 
> > > > Hmmm, this is not pretty.  The driver behaviour is entirely different
> > > > depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> > > > multiplatform kernels, is this going to break on some hardware?
> > > > 
> > > > > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > > > > *work)
> > > > > 
> > > > >  	spin_unlock_irqrestore(&sdd->lock, flags);
> > > > >  	
> > > > >  	/* Free DMA channels */
> > > > > 
> > > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > > +	dma_release_channel(sdd->tx_chan);
> > > > > +	dma_release_channel(sdd->rx_chan);
> > > > > +#else
> > > > > 
> > > > >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> > > > >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > > > > 
> > > > > +#endif
> > > > 
> > > > Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> > > > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> > > > selected?  If so, can they be removed entirely, or are they required
> > > > to support certain hardware?
> > > 
> > > The spi_s3c64xx driver can also support the SPI controller of the
> > > S3C2416/S3C2443 line of SoCs.
> > > As I'm currently working on a S3C2416 based project, my small wish from
> > > the sidelines would be to not break this support with whatever solution
> > > you will decide on :-) .
> > 
> > I will not merge a patch that either breaks a platform, or requires
> > a compile time either/or choice of device support (enabling support
> > for one device should not break support for another).
> 
> The patch above seems to contain the support for both SoCs (i.e. s3c2410_dma_* 
> for S3C2416 etc), so it wouldn't break the support.
> But this form will definitly break future multiplatform kernels when the 2416 
> and some variant using the DMADEV_PL330 are selected at the same time.

Yes, that's the breakage I'm talking about.

> The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller of 
> this type. Implementing the DMA engine stuff for these SoCs would obviously 
> solve the ifdef-problem but I don't know if this is possible to do.

Of course it's possible, it's just software.  :-D

If a config option is either/or then it needs to be really well
justified before I will accept it.  Most either/or options I've seen
aren't for any strong technical reason other than it was easier to
code that way.

g.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-04 23:27             ` Grant Likely
  0 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-04 23:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 09:51:43PM +0200, Heiko St?bner wrote:
> Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
> > On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko St?bner wrote:
> > > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > > > On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
> > > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > > +			memset(&slave_config, 0, sizeof(slave_config));
> > > > > +			slave_config.direction = DMA_TO_DEVICE;
> > > > > +			slave_config.src_addr = xfer->tx_dma;
> > > > > +			slave_config.dst_addr =
> > > > > +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> > > > > +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> > > > > +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> > > > > +
> > > > > +			sg_init_table(&tx_sg, 1);
> > > > > +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer-
> >tx_dma)),
> > > > > +				xfer->len, offset_in_page(xfer->tx_dma));
> > > > > +			sg_dma_len(&tx_sg) =  xfer->len;
> > > > > +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> > > > > +			sdd->tx_desc =
> > > > > +				sdd->tx_chan->device->device_prep_slave_sg(
> > > > > +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> > > > > +				DMA_PREP_INTERRUPT);
> > > > > +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> > > > > +			sdd->tx_desc->callback_param = sdd;
> > > > > +			dmaengine_submit(sdd->tx_desc);
> > > > > +			dma_async_issue_pending(sdd->tx_chan);
> > > > > +#else
> > > > > 
> > > > >  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> > > > >  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> > > > >  			
> > > > >  						xfer->tx_dma, xfer->len);
> > > > >  			
> > > > >  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> > > > > 
> > > > > +#endif
> > > > 
> > > > Hmmm, this is not pretty.  The driver behaviour is entirely different
> > > > depending on if CONFIG_DMADEV_PL330 is enabled?  When we get to
> > > > multiplatform kernels, is this going to break on some hardware?
> > > > 
> > > > > @@ -802,8 +951,13 @@ static void s3c64xx_spi_work(struct work_struct
> > > > > *work)
> > > > > 
> > > > >  	spin_unlock_irqrestore(&sdd->lock, flags);
> > > > >  	
> > > > >  	/* Free DMA channels */
> > > > > 
> > > > > +#if defined(CONFIG_DMADEV_PL330)
> > > > > +	dma_release_channel(sdd->tx_chan);
> > > > > +	dma_release_channel(sdd->rx_chan);
> > > > > +#else
> > > > > 
> > > > >  	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
> > > > >  	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
> > > > > 
> > > > > +#endif
> > > > 
> > > > Wow.  A lot of #ifdefs here.  It does not look multiplatform friendly
> > > > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330 is
> > > > selected?  If so, can they be removed entirely, or are they required
> > > > to support certain hardware?
> > > 
> > > The spi_s3c64xx driver can also support the SPI controller of the
> > > S3C2416/S3C2443 line of SoCs.
> > > As I'm currently working on a S3C2416 based project, my small wish from
> > > the sidelines would be to not break this support with whatever solution
> > > you will decide on :-) .
> > 
> > I will not merge a patch that either breaks a platform, or requires
> > a compile time either/or choice of device support (enabling support
> > for one device should not break support for another).
> 
> The patch above seems to contain the support for both SoCs (i.e. s3c2410_dma_* 
> for S3C2416 etc), so it wouldn't break the support.
> But this form will definitly break future multiplatform kernels when the 2416 
> and some variant using the DMADEV_PL330 are selected at the same time.

Yes, that's the breakage I'm talking about.

> The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller of 
> this type. Implementing the DMA engine stuff for these SoCs would obviously 
> solve the ifdef-problem but I don't know if this is possible to do.

Of course it's possible, it's just software.  :-D

If a config option is either/or then it needs to be really well
justified before I will accept it.  Most either/or options I've seen
aren't for any strong technical reason other than it was easier to
code that way.

g.

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

* Re: [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
  2011-07-04 12:18   ` Kukjin Kim
  (?)
@ 2011-07-05  2:36   ` Chanho Park
  -1 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  2:36 UTC (permalink / raw)
  To: linux-samsung-soc

Kukjin Kim <kgene.kim <at> samsung.com> writes:

> +struct dma_pl330_platdata exynos4_pdma0_pdata = {
> +	.nr_valid_peri = 32,
> +	.peri = pdma0_peri,
>  };

(snip)

> +struct dma_pl330_platdata exynos4_pdma1_pdata = {
> +	.nr_valid_peri = 32,
> +	.peri = pdma1_peri,
>  };
> 

I think you'd better use ARRAY_SIZE(peri) instead 32 for nr_valid_peri
because dma channels can be sparse.

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

* Re: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-04 12:18   ` Kukjin Kim
  (?)
@ 2011-07-05  4:50   ` Chanho Park
  -1 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  4:50 UTC (permalink / raw)
  To: linux-samsung-soc

Kukjin Kim <kgene.kim <at> samsung.com> writes:

(snip)

> +		if (slave_config->direction == DMA_TO_DEVICE) {
> +			if (slave_config->dst_addr)
> +				peri->fifo_addr = slave_config->dst_addr;
> +			if (slave_config->dst_addr_width) {
> +				i = 0;
> +				while (slave_config->dst_addr_width != (1 << 
i))
> +					i++;
> +				peri->burst_sz = i;
> +			}
> +		} else if (slave_config->direction == DMA_FROM_DEVICE) {
> +			if (slave_config->src_addr)
> +				peri->fifo_addr = slave_config->src_addr;
> +			if (slave_config->src_addr_width) {
> +				i = 0;
> +				while (slave_config->src_addr_width != (1 << 
i))
> +					i++;
> +				peri->burst_sz = i;

pl330 dmac only supports 1/2/4/8/16 bytes burst size.
If some bad D/D doesn't use powers of 2 width,
dmaengine is going to infinite loop.
You'd better check it instead of running loop.

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

* Re: [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-05  6:07     ` Alim Akhtar
  -1 siblings, 0 replies; 86+ messages in thread
From: Alim Akhtar @ 2011-07-05  6:07 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Vinod Koul, Dan Williams,
	Grant Likely, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

On Mon, Jul 4, 2011 at 5:48 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
>
> From: Boojin Kim <boojin.kim@samsung.com>
>
> This patch makes EXYNOS4 use DMA PL330 driver on DMADEVICE.
> EXYNOS4 uses DMA generic API instead of SAMSUNG specific S3C-PL330 API.
>
> Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> ---
>  arch/arm/mach-exynos4/Kconfig |    2 +-
>  arch/arm/mach-exynos4/clock.c |   16 +-
>  arch/arm/mach-exynos4/dma.c   |  323 +++++++++++++++++++++++++++--------------
>  3 files changed, 221 insertions(+), 120 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
> index 1435fc3..5cc9b7a 100644
> --- a/arch/arm/mach-exynos4/Kconfig
> +++ b/arch/arm/mach-exynos4/Kconfig
> @@ -11,7 +11,7 @@ if ARCH_EXYNOS4
>
>  config CPU_EXYNOS4210
>        bool
> -       select S3C_PL330_DMA
> +       select DMADEV_PL330
>        help
>          Enable EXYNOS4210 CPU support
>
> diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
> index 871f9d5..1b2e78c 100644
> --- a/arch/arm/mach-exynos4/clock.c
> +++ b/arch/arm/mach-exynos4/clock.c
> @@ -47,6 +47,11 @@ static struct clk clk_sclk_usbphy1 = {
>        .id             = -1,
>  };
>
> +static struct clk dummy_apb_pclk = {
> +       .name           = "apb_pclk",
> +       .id             = -1,
> +};
> +
What is the need to creating "dummy_apb_pclk" ?
>
>  static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
>  {
>        return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
> @@ -485,16 +490,11 @@ static struct clk init_clocks_off[] = {
>                .enable         = exynos4_clk_ip_fsys_ctrl,
>                .ctrlbit        = (1 << 10),
>        }, {
> -               .name           = "pdma",
> -               .id             = 0,
> +               .name           = "dma",
> +               .id             = -1,

Cannot this "dma" clock be used as apb_pclk clock?
Why not use the _clkdev_, that will resolve the issues dealing with 2
instances of DMA driver (pdma0 and pdma1)?
That will be needed once you register the exynos4_device_pdma1 as amba_device.
>
>                .enable         = exynos4_clk_ip_fsys_ctrl,
>                .ctrlbit        = (1 << 0),
>        }, {
> -               .name           = "pdma",
> -               .id             = 1,
> -               .enable         = exynos4_clk_ip_fsys_ctrl,
> -               .ctrlbit        = (1 << 1),
> -       }, {
>                .name           = "adc",
>                .id             = -1,
>                .enable         = exynos4_clk_ip_peril_ctrl,
> @@ -1212,5 +1212,7 @@ void __init exynos4_register_clocks(void)
>        s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
>        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
>
> +       s3c24xx_register_clock(&dummy_apb_pclk);
> +
>        s3c_pwmclk_init();
>  }
> diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
> index 564bb53..f81c6f1 100644
> --- a/arch/arm/mach-exynos4/dma.c
> +++ b/arch/arm/mach-exynos4/dma.c
> @@ -21,151 +21,250 @@
>  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>  */
>
> -#include <linux/platform_device.h>
>  #include <linux/dma-mapping.h>
>
> +#include <linux/amba/bus.h>
> +#include <linux/amba/pl330.h>
> +#include <asm/irq.h>
>  #include <plat/devs.h>
>  #include <plat/irqs.h>
>
>  #include <mach/map.h>
>  #include <mach/irqs.h>
> -
> -#include <plat/s3c-pl330-pdata.h>
> +#include <mach/dma.h>
>
>  static u64 dma_dmamask = DMA_BIT_MASK(32);
>
> -static struct resource exynos4_pdma0_resource[] = {
> -       [0] = {
> -               .start  = EXYNOS4_PA_PDMA0,
> -               .end    = EXYNOS4_PA_PDMA0 + SZ_4K,
> -               .flags  = IORESOURCE_MEM,
> -       },
> -       [1] = {
> -               .start  = IRQ_PDMA0,
> -               .end    = IRQ_PDMA0,
> -               .flags  = IORESOURCE_IRQ,
> +struct dma_pl330_peri pdma0_peri[32] = {
> +       {
> +               .peri_id = (u8)DMACH_PCM0_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_PCM0_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_PCM2_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_PCM2_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_MSM_REQ0,
> +       }, {
> +               .peri_id = (u8)DMACH_MSM_REQ2,
> +       }, {
> +               .peri_id = (u8)DMACH_SPI0_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 1,
> +       }, {
> +               .peri_id = (u8)DMACH_SPI0_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 1,
> +       }, {
> +               .peri_id = (u8)DMACH_SPI2_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 1,
> +       }, {
> +               .peri_id = (u8)DMACH_SPI2_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 1,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S0S_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S0_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S0_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_UART0_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART0_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART2_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART2_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART4_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART4_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS0_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS0_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS2_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS2_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS4_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS4_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_AC97_MICIN,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_AC97_PCMIN,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_AC97_PCMOUT,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
>        },
>  };
>
> -static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
> -       .peri = {
> -               [0] = DMACH_PCM0_RX,
> -               [1] = DMACH_PCM0_TX,
> -               [2] = DMACH_PCM2_RX,
> -               [3] = DMACH_PCM2_TX,
> -               [4] = DMACH_MSM_REQ0,
> -               [5] = DMACH_MSM_REQ2,
> -               [6] = DMACH_SPI0_RX,
> -               [7] = DMACH_SPI0_TX,
> -               [8] = DMACH_SPI2_RX,
> -               [9] = DMACH_SPI2_TX,
> -               [10] = DMACH_I2S0S_TX,
> -               [11] = DMACH_I2S0_RX,
> -               [12] = DMACH_I2S0_TX,
> -               [13] = DMACH_I2S2_RX,
> -               [14] = DMACH_I2S2_TX,
> -               [15] = DMACH_UART0_RX,
> -               [16] = DMACH_UART0_TX,
> -               [17] = DMACH_UART2_RX,
> -               [18] = DMACH_UART2_TX,
> -               [19] = DMACH_UART4_RX,
> -               [20] = DMACH_UART4_TX,
> -               [21] = DMACH_SLIMBUS0_RX,
> -               [22] = DMACH_SLIMBUS0_TX,
> -               [23] = DMACH_SLIMBUS2_RX,
> -               [24] = DMACH_SLIMBUS2_TX,
> -               [25] = DMACH_SLIMBUS4_RX,
> -               [26] = DMACH_SLIMBUS4_TX,
> -               [27] = DMACH_AC97_MICIN,
> -               [28] = DMACH_AC97_PCMIN,
> -               [29] = DMACH_AC97_PCMOUT,
> -               [30] = DMACH_MAX,
> -               [31] = DMACH_MAX,
> -       },
> +struct dma_pl330_platdata exynos4_pdma0_pdata = {
> +       .nr_valid_peri = 32,
> +       .peri = pdma0_peri,
>  };
>
> -static struct platform_device exynos4_device_pdma0 = {
> -       .name           = "s3c-pl330",
> -       .id             = 0,
> -       .num_resources  = ARRAY_SIZE(exynos4_pdma0_resource),
> -       .resource       = exynos4_pdma0_resource,
> -       .dev            = {
> +struct amba_device exynos4_device_pdma0 = {
> +       .dev = {
> +               .init_name = "dma-pl330",
>                .dma_mask = &dma_dmamask,
>                .coherent_dma_mask = DMA_BIT_MASK(32),
>                .platform_data = &exynos4_pdma0_pdata,
> -       },
> +               },
> +       .res = {
> +               .start = EXYNOS4_PA_PDMA0,
> +               .end = EXYNOS4_PA_PDMA0 + SZ_4K,
> +               .flags = IORESOURCE_MEM,
> +               },
> +       .irq = {IRQ_PDMA0, NO_IRQ},
> +       .periphid = 0x00041330,
>  };
>
> -static struct resource exynos4_pdma1_resource[] = {
> -       [0] = {
> -               .start  = EXYNOS4_PA_PDMA1,
> -               .end    = EXYNOS4_PA_PDMA1 + SZ_4K,
> -               .flags  = IORESOURCE_MEM,
> -       },
> -       [1] = {
> -               .start  = IRQ_PDMA1,
> -               .end    = IRQ_PDMA1,
> -               .flags  = IORESOURCE_IRQ,
> +struct dma_pl330_peri pdma1_peri[32] = {
> +       {
> +               .peri_id = (u8)DMACH_PCM0_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_PCM0_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_PCM1_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_PCM1_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_MSM_REQ1,
> +       }, {
> +               .peri_id = (u8)DMACH_MSM_REQ3,
> +       }, {
> +               .peri_id = (u8)DMACH_SPI1_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 1,
> +       }, {
> +               .peri_id = (u8)DMACH_SPI1_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 1,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S0S_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S0_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S0_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S1_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_I2S1_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_UART0_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART0_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART1_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART1_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART3_RX,
> +               .rqtype = DEVTOMEM,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_UART3_TX,
> +               .rqtype = MEMTODEV,
> +               .burst_sz = 4,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS1_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS1_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS3_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS3_TX,
> +               .rqtype = MEMTODEV,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS5_RX,
> +               .rqtype = DEVTOMEM,
> +       }, {
> +               .peri_id = (u8)DMACH_SLIMBUS5_TX,
> +               .rqtype = MEMTODEV,
>        },
>  };
>
> -static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
> -       .peri = {
> -               [0] = DMACH_PCM0_RX,
> -               [1] = DMACH_PCM0_TX,
> -               [2] = DMACH_PCM1_RX,
> -               [3] = DMACH_PCM1_TX,
> -               [4] = DMACH_MSM_REQ1,
> -               [5] = DMACH_MSM_REQ3,
> -               [6] = DMACH_SPI1_RX,
> -               [7] = DMACH_SPI1_TX,
> -               [8] = DMACH_I2S0S_TX,
> -               [9] = DMACH_I2S0_RX,
> -               [10] = DMACH_I2S0_TX,
> -               [11] = DMACH_I2S1_RX,
> -               [12] = DMACH_I2S1_TX,
> -               [13] = DMACH_UART0_RX,
> -               [14] = DMACH_UART0_TX,
> -               [15] = DMACH_UART1_RX,
> -               [16] = DMACH_UART1_TX,
> -               [17] = DMACH_UART3_RX,
> -               [18] = DMACH_UART3_TX,
> -               [19] = DMACH_SLIMBUS1_RX,
> -               [20] = DMACH_SLIMBUS1_TX,
> -               [21] = DMACH_SLIMBUS3_RX,
> -               [22] = DMACH_SLIMBUS3_TX,
> -               [23] = DMACH_SLIMBUS5_RX,
> -               [24] = DMACH_SLIMBUS5_TX,
> -               [25] = DMACH_SLIMBUS0AUX_RX,
> -               [26] = DMACH_SLIMBUS0AUX_TX,
> -               [27] = DMACH_SPDIF,
> -               [28] = DMACH_MAX,
> -               [29] = DMACH_MAX,
> -               [30] = DMACH_MAX,
> -               [31] = DMACH_MAX,
> -       },
> +struct dma_pl330_platdata exynos4_pdma1_pdata = {
> +       .nr_valid_peri = 32,
> +       .peri = pdma1_peri,
>  };
>
> -static struct platform_device exynos4_device_pdma1 = {
> -       .name           = "s3c-pl330",
> -       .id             = 1,
> -       .num_resources  = ARRAY_SIZE(exynos4_pdma1_resource),
> -       .resource       = exynos4_pdma1_resource,
> -       .dev            = {
> +struct amba_device exynos4_device_pdma1 = {
 "exynos4_device_pdma1" is not being used anywhere in this patch, i
think pdma1 is for the second instance of DMA.
> +       .dev = {
> +               .init_name = "dma-pl330",
>                .dma_mask = &dma_dmamask,
>                .coherent_dma_mask = DMA_BIT_MASK(32),
>                .platform_data = &exynos4_pdma1_pdata,
>        },
> -};
> -
> -static struct platform_device *exynos4_dmacs[] __initdata = {
> -       &exynos4_device_pdma0,
> -       &exynos4_device_pdma1,
> +       .res = {
> +               .start = EXYNOS4_PA_PDMA1,
> +               .end = EXYNOS4_PA_PDMA1 + SZ_4K,
> +               .flags = IORESOURCE_MEM,
> +       },
> +       .irq = {IRQ_PDMA1, NO_IRQ},
> +       .periphid = 0x00041330,
>  };
>
>  static int __init exynos4_dma_init(void)
>  {
> -       platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
> +       amba_device_register(&exynos4_device_pdma0, &iomem_resource);
For some reason you are not registering exynos4_device_pdma1, though
you have provided the platdata.
>
>        return 0;
>  }
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
@ 2011-07-05  6:07     ` Alim Akhtar
  0 siblings, 0 replies; 86+ messages in thread
From: Alim Akhtar @ 2011-07-05  6:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 4, 2011 at 5:48 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
>
> From: Boojin Kim <boojin.kim@samsung.com>
>
> This patch makes EXYNOS4 use DMA PL330 driver on DMADEVICE.
> EXYNOS4 uses DMA generic API instead of SAMSUNG specific S3C-PL330 API.
>
> Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> ---
> ?arch/arm/mach-exynos4/Kconfig | ? ?2 +-
> ?arch/arm/mach-exynos4/clock.c | ? 16 +-
> ?arch/arm/mach-exynos4/dma.c ? | ?323 +++++++++++++++++++++++++++--------------
> ?3 files changed, 221 insertions(+), 120 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
> index 1435fc3..5cc9b7a 100644
> --- a/arch/arm/mach-exynos4/Kconfig
> +++ b/arch/arm/mach-exynos4/Kconfig
> @@ -11,7 +11,7 @@ if ARCH_EXYNOS4
>
> ?config CPU_EXYNOS4210
> ? ? ? ?bool
> - ? ? ? select S3C_PL330_DMA
> + ? ? ? select DMADEV_PL330
> ? ? ? ?help
> ? ? ? ? ?Enable EXYNOS4210 CPU support
>
> diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
> index 871f9d5..1b2e78c 100644
> --- a/arch/arm/mach-exynos4/clock.c
> +++ b/arch/arm/mach-exynos4/clock.c
> @@ -47,6 +47,11 @@ static struct clk clk_sclk_usbphy1 = {
> ? ? ? ?.id ? ? ? ? ? ? = -1,
> ?};
>
> +static struct clk dummy_apb_pclk = {
> + ? ? ? .name ? ? ? ? ? = "apb_pclk",
> + ? ? ? .id ? ? ? ? ? ? = -1,
> +};
> +
What is the need to?creating "dummy_apb_pclk"??
>
> ?static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
> ?{
> ? ? ? ?return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
> @@ -485,16 +490,11 @@ static struct clk init_clocks_off[] = {
> ? ? ? ? ? ? ? ?.enable ? ? ? ? = exynos4_clk_ip_fsys_ctrl,
> ? ? ? ? ? ? ? ?.ctrlbit ? ? ? ?= (1 << 10),
> ? ? ? ?}, {
> - ? ? ? ? ? ? ? .name ? ? ? ? ? = "pdma",
> - ? ? ? ? ? ? ? .id ? ? ? ? ? ? = 0,
> + ? ? ? ? ? ? ? .name ? ? ? ? ? = "dma",
> + ? ? ? ? ? ? ? .id ? ? ? ? ? ? = -1,

Cannot this "dma" clock be used as apb_pclk clock?
Why not use the _clkdev_, that will resolve the issues dealing with 2
instances of DMA driver (pdma0 and pdma1)?
That will be needed once you register the exynos4_device_pdma1 as amba_device.
>
> ? ? ? ? ? ? ? ?.enable ? ? ? ? = exynos4_clk_ip_fsys_ctrl,
> ? ? ? ? ? ? ? ?.ctrlbit ? ? ? ?= (1 << 0),
> ? ? ? ?}, {
> - ? ? ? ? ? ? ? .name ? ? ? ? ? = "pdma",
> - ? ? ? ? ? ? ? .id ? ? ? ? ? ? = 1,
> - ? ? ? ? ? ? ? .enable ? ? ? ? = exynos4_clk_ip_fsys_ctrl,
> - ? ? ? ? ? ? ? .ctrlbit ? ? ? ?= (1 << 1),
> - ? ? ? }, {
> ? ? ? ? ? ? ? ?.name ? ? ? ? ? = "adc",
> ? ? ? ? ? ? ? ?.id ? ? ? ? ? ? = -1,
> ? ? ? ? ? ? ? ?.enable ? ? ? ? = exynos4_clk_ip_peril_ctrl,
> @@ -1212,5 +1212,7 @@ void __init exynos4_register_clocks(void)
> ? ? ? ?s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
> ? ? ? ?s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
>
> + ? ? ? s3c24xx_register_clock(&dummy_apb_pclk);
> +
> ? ? ? ?s3c_pwmclk_init();
> ?}
> diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
> index 564bb53..f81c6f1 100644
> --- a/arch/arm/mach-exynos4/dma.c
> +++ b/arch/arm/mach-exynos4/dma.c
> @@ -21,151 +21,250 @@
> ?* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> ?*/
>
> -#include <linux/platform_device.h>
> ?#include <linux/dma-mapping.h>
>
> +#include <linux/amba/bus.h>
> +#include <linux/amba/pl330.h>
> +#include <asm/irq.h>
> ?#include <plat/devs.h>
> ?#include <plat/irqs.h>
>
> ?#include <mach/map.h>
> ?#include <mach/irqs.h>
> -
> -#include <plat/s3c-pl330-pdata.h>
> +#include <mach/dma.h>
>
> ?static u64 dma_dmamask = DMA_BIT_MASK(32);
>
> -static struct resource exynos4_pdma0_resource[] = {
> - ? ? ? [0] = {
> - ? ? ? ? ? ? ? .start ?= EXYNOS4_PA_PDMA0,
> - ? ? ? ? ? ? ? .end ? ?= EXYNOS4_PA_PDMA0 + SZ_4K,
> - ? ? ? ? ? ? ? .flags ?= IORESOURCE_MEM,
> - ? ? ? },
> - ? ? ? [1] = {
> - ? ? ? ? ? ? ? .start ?= IRQ_PDMA0,
> - ? ? ? ? ? ? ? .end ? ?= IRQ_PDMA0,
> - ? ? ? ? ? ? ? .flags ?= IORESOURCE_IRQ,
> +struct dma_pl330_peri pdma0_peri[32] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM2_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM2_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_MSM_REQ0,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_MSM_REQ2,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SPI0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 1,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SPI0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 1,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SPI2_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 1,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SPI2_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 1,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S0S_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART2_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART2_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART4_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART4_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS2_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS2_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS4_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS4_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_AC97_MICIN,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_AC97_PCMIN,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_AC97_PCMOUT,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> ? ? ? ?},
> ?};
>
> -static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
> - ? ? ? .peri = {
> - ? ? ? ? ? ? ? [0] = DMACH_PCM0_RX,
> - ? ? ? ? ? ? ? [1] = DMACH_PCM0_TX,
> - ? ? ? ? ? ? ? [2] = DMACH_PCM2_RX,
> - ? ? ? ? ? ? ? [3] = DMACH_PCM2_TX,
> - ? ? ? ? ? ? ? [4] = DMACH_MSM_REQ0,
> - ? ? ? ? ? ? ? [5] = DMACH_MSM_REQ2,
> - ? ? ? ? ? ? ? [6] = DMACH_SPI0_RX,
> - ? ? ? ? ? ? ? [7] = DMACH_SPI0_TX,
> - ? ? ? ? ? ? ? [8] = DMACH_SPI2_RX,
> - ? ? ? ? ? ? ? [9] = DMACH_SPI2_TX,
> - ? ? ? ? ? ? ? [10] = DMACH_I2S0S_TX,
> - ? ? ? ? ? ? ? [11] = DMACH_I2S0_RX,
> - ? ? ? ? ? ? ? [12] = DMACH_I2S0_TX,
> - ? ? ? ? ? ? ? [13] = DMACH_I2S2_RX,
> - ? ? ? ? ? ? ? [14] = DMACH_I2S2_TX,
> - ? ? ? ? ? ? ? [15] = DMACH_UART0_RX,
> - ? ? ? ? ? ? ? [16] = DMACH_UART0_TX,
> - ? ? ? ? ? ? ? [17] = DMACH_UART2_RX,
> - ? ? ? ? ? ? ? [18] = DMACH_UART2_TX,
> - ? ? ? ? ? ? ? [19] = DMACH_UART4_RX,
> - ? ? ? ? ? ? ? [20] = DMACH_UART4_TX,
> - ? ? ? ? ? ? ? [21] = DMACH_SLIMBUS0_RX,
> - ? ? ? ? ? ? ? [22] = DMACH_SLIMBUS0_TX,
> - ? ? ? ? ? ? ? [23] = DMACH_SLIMBUS2_RX,
> - ? ? ? ? ? ? ? [24] = DMACH_SLIMBUS2_TX,
> - ? ? ? ? ? ? ? [25] = DMACH_SLIMBUS4_RX,
> - ? ? ? ? ? ? ? [26] = DMACH_SLIMBUS4_TX,
> - ? ? ? ? ? ? ? [27] = DMACH_AC97_MICIN,
> - ? ? ? ? ? ? ? [28] = DMACH_AC97_PCMIN,
> - ? ? ? ? ? ? ? [29] = DMACH_AC97_PCMOUT,
> - ? ? ? ? ? ? ? [30] = DMACH_MAX,
> - ? ? ? ? ? ? ? [31] = DMACH_MAX,
> - ? ? ? },
> +struct dma_pl330_platdata exynos4_pdma0_pdata = {
> + ? ? ? .nr_valid_peri = 32,
> + ? ? ? .peri = pdma0_peri,
> ?};
>
> -static struct platform_device exynos4_device_pdma0 = {
> - ? ? ? .name ? ? ? ? ? = "s3c-pl330",
> - ? ? ? .id ? ? ? ? ? ? = 0,
> - ? ? ? .num_resources ?= ARRAY_SIZE(exynos4_pdma0_resource),
> - ? ? ? .resource ? ? ? = exynos4_pdma0_resource,
> - ? ? ? .dev ? ? ? ? ? ?= {
> +struct amba_device exynos4_device_pdma0 = {
> + ? ? ? .dev = {
> + ? ? ? ? ? ? ? .init_name = "dma-pl330",
> ? ? ? ? ? ? ? ?.dma_mask = &dma_dmamask,
> ? ? ? ? ? ? ? ?.coherent_dma_mask = DMA_BIT_MASK(32),
> ? ? ? ? ? ? ? ?.platform_data = &exynos4_pdma0_pdata,
> - ? ? ? },
> + ? ? ? ? ? ? ? },
> + ? ? ? .res = {
> + ? ? ? ? ? ? ? .start = EXYNOS4_PA_PDMA0,
> + ? ? ? ? ? ? ? .end = EXYNOS4_PA_PDMA0 + SZ_4K,
> + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> + ? ? ? ? ? ? ? },
> + ? ? ? .irq = {IRQ_PDMA0, NO_IRQ},
> + ? ? ? .periphid = 0x00041330,
> ?};
>
> -static struct resource exynos4_pdma1_resource[] = {
> - ? ? ? [0] = {
> - ? ? ? ? ? ? ? .start ?= EXYNOS4_PA_PDMA1,
> - ? ? ? ? ? ? ? .end ? ?= EXYNOS4_PA_PDMA1 + SZ_4K,
> - ? ? ? ? ? ? ? .flags ?= IORESOURCE_MEM,
> - ? ? ? },
> - ? ? ? [1] = {
> - ? ? ? ? ? ? ? .start ?= IRQ_PDMA1,
> - ? ? ? ? ? ? ? .end ? ?= IRQ_PDMA1,
> - ? ? ? ? ? ? ? .flags ?= IORESOURCE_IRQ,
> +struct dma_pl330_peri pdma1_peri[32] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM1_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM1_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_MSM_REQ1,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_MSM_REQ3,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SPI1_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 1,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SPI1_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 1,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S0S_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S1_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_I2S1_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART0_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART0_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART1_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART1_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART3_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_UART3_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? ? ? ? ? .burst_sz = 4,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS1_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS1_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS3_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS3_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS5_RX,
> + ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .peri_id = (u8)DMACH_SLIMBUS5_TX,
> + ? ? ? ? ? ? ? .rqtype = MEMTODEV,
> ? ? ? ?},
> ?};
>
> -static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
> - ? ? ? .peri = {
> - ? ? ? ? ? ? ? [0] = DMACH_PCM0_RX,
> - ? ? ? ? ? ? ? [1] = DMACH_PCM0_TX,
> - ? ? ? ? ? ? ? [2] = DMACH_PCM1_RX,
> - ? ? ? ? ? ? ? [3] = DMACH_PCM1_TX,
> - ? ? ? ? ? ? ? [4] = DMACH_MSM_REQ1,
> - ? ? ? ? ? ? ? [5] = DMACH_MSM_REQ3,
> - ? ? ? ? ? ? ? [6] = DMACH_SPI1_RX,
> - ? ? ? ? ? ? ? [7] = DMACH_SPI1_TX,
> - ? ? ? ? ? ? ? [8] = DMACH_I2S0S_TX,
> - ? ? ? ? ? ? ? [9] = DMACH_I2S0_RX,
> - ? ? ? ? ? ? ? [10] = DMACH_I2S0_TX,
> - ? ? ? ? ? ? ? [11] = DMACH_I2S1_RX,
> - ? ? ? ? ? ? ? [12] = DMACH_I2S1_TX,
> - ? ? ? ? ? ? ? [13] = DMACH_UART0_RX,
> - ? ? ? ? ? ? ? [14] = DMACH_UART0_TX,
> - ? ? ? ? ? ? ? [15] = DMACH_UART1_RX,
> - ? ? ? ? ? ? ? [16] = DMACH_UART1_TX,
> - ? ? ? ? ? ? ? [17] = DMACH_UART3_RX,
> - ? ? ? ? ? ? ? [18] = DMACH_UART3_TX,
> - ? ? ? ? ? ? ? [19] = DMACH_SLIMBUS1_RX,
> - ? ? ? ? ? ? ? [20] = DMACH_SLIMBUS1_TX,
> - ? ? ? ? ? ? ? [21] = DMACH_SLIMBUS3_RX,
> - ? ? ? ? ? ? ? [22] = DMACH_SLIMBUS3_TX,
> - ? ? ? ? ? ? ? [23] = DMACH_SLIMBUS5_RX,
> - ? ? ? ? ? ? ? [24] = DMACH_SLIMBUS5_TX,
> - ? ? ? ? ? ? ? [25] = DMACH_SLIMBUS0AUX_RX,
> - ? ? ? ? ? ? ? [26] = DMACH_SLIMBUS0AUX_TX,
> - ? ? ? ? ? ? ? [27] = DMACH_SPDIF,
> - ? ? ? ? ? ? ? [28] = DMACH_MAX,
> - ? ? ? ? ? ? ? [29] = DMACH_MAX,
> - ? ? ? ? ? ? ? [30] = DMACH_MAX,
> - ? ? ? ? ? ? ? [31] = DMACH_MAX,
> - ? ? ? },
> +struct dma_pl330_platdata exynos4_pdma1_pdata = {
> + ? ? ? .nr_valid_peri = 32,
> + ? ? ? .peri = pdma1_peri,
> ?};
>
> -static struct platform_device exynos4_device_pdma1 = {
> - ? ? ? .name ? ? ? ? ? = "s3c-pl330",
> - ? ? ? .id ? ? ? ? ? ? = 1,
> - ? ? ? .num_resources ?= ARRAY_SIZE(exynos4_pdma1_resource),
> - ? ? ? .resource ? ? ? = exynos4_pdma1_resource,
> - ? ? ? .dev ? ? ? ? ? ?= {
> +struct amba_device exynos4_device_pdma1 = {
 "exynos4_device_pdma1" is not being used anywhere in this patch, i
think pdma1 is for the second instance of DMA.
> + ? ? ? .dev = {
> + ? ? ? ? ? ? ? .init_name = "dma-pl330",
> ? ? ? ? ? ? ? ?.dma_mask = &dma_dmamask,
> ? ? ? ? ? ? ? ?.coherent_dma_mask = DMA_BIT_MASK(32),
> ? ? ? ? ? ? ? ?.platform_data = &exynos4_pdma1_pdata,
> ? ? ? ?},
> -};
> -
> -static struct platform_device *exynos4_dmacs[] __initdata = {
> - ? ? ? &exynos4_device_pdma0,
> - ? ? ? &exynos4_device_pdma1,
> + ? ? ? .res = {
> + ? ? ? ? ? ? ? .start = EXYNOS4_PA_PDMA1,
> + ? ? ? ? ? ? ? .end = EXYNOS4_PA_PDMA1 + SZ_4K,
> + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> + ? ? ? },
> + ? ? ? .irq = {IRQ_PDMA1, NO_IRQ},
> + ? ? ? .periphid = 0x00041330,
> ?};
>
> ?static int __init exynos4_dma_init(void)
> ?{
> - ? ? ? platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
> + ? ? ? amba_device_register(&exynos4_device_pdma0, &iomem_resource);
For some reason you are not registering exynos4_device_pdma1, though
you have provided the platdata.
>
> ? ? ? ?return 0;
> ?}
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 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] 86+ messages in thread

* Re: [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-05  6:11     ` Alim Akhtar
  -1 siblings, 0 replies; 86+ messages in thread
From: Alim Akhtar @ 2011-07-05  6:11 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Vinod Koul, Dan Williams,
	Grant Likely, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

Hi,

On Mon, Jul 4, 2011 at 5:48 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> From: Boojin Kim <boojin.kim@samsung.com>
>
> Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
> Cc: Vinod Koul <vinod.koul@intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> ---
>  drivers/dma/pl330.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 61 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 6abe1ec..7bd72e9 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -17,6 +17,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/amba/bus.h>
>  #include <linux/amba/pl330.h>
> +#include <linux/pm_runtime.h>
>
>  #define NR_DEFAULT_DESC        16
>
> @@ -666,6 +667,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>        struct dma_device *pd;
>        struct resource *res;
>        int i, ret, irq;
> +       struct clk* clk;
>
>        pdat = adev->dev.platform_data;
>
> @@ -696,6 +698,28 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>                goto probe_err1;
>        }
>
> +#ifdef CONFIG_PM_RUNTIME
> +       /* to use the runtime PM helper functions */
> +       pm_runtime_enable(&adev->dev);
> +
> +       /* enable the power domain */
> +       if (pm_runtime_get_sync(&adev->dev)) {
> +               dev_err(&adev->dev, "failed to get runtime pm\n");
> +               ret = -ENODEV;
> +               goto probe_err1;
> +       }
> +#else
> +       /* enable dma clk */
> +       clk = clk_get(&adev->dev, "dma");

Does this really needed here?
AFAIR, amba_get_enable_pclk() does the same thing, provided clock name
as "apb_pclk"
please have a look at drivers/amba/bus.c

> +
> +       if (IS_ERR(clk)) {
> +               dev_err(&adev->dev, "Cannot get operation clock.\n");
> +               ret = -EINVAL;
> +               goto probe_err1;
> +       }
> +       clk_enable(clk);
> +#endif
> +
>        irq = adev->irq[0];
>        ret = request_irq(irq, pl330_irq_handler, 0,
>                        dev_name(&adev->dev), pi);
> @@ -838,10 +862,47 @@ static struct amba_id pl330_ids[] = {
>        { 0, 0 },
>  };
>
> +#ifdef CONFIG_PM_RUNTIME
> +static int pl330_runtime_suspend(struct device *dev)
> +{
> +       struct clk *dmaclk = clk_get(dev, "dma");
> +
> +       if (dmaclk == NULL) {
> +               dev_err(dev, "failed to find dma clock source\n");
> +               return -ENODEV;
> +       }
> +
> +       clk_disable(dmaclk);
> +       return 0;
> +}
> +
> +static int pl330_runtime_resume(struct device *dev)
> +{
> +       struct clk *dmaclk = clk_get(dev, "dma");
> +
> +       if (dmaclk == NULL) {
> +               dev_err(dev, "failed to find dma clock source\n");
> +               return -ENODEV;
> +       }
> +
> +       clk_enable(dmaclk);
> +       return 0;
> +}
> +#else
> +#define pl330_runtime_suspend  NULL
> +#define pl330_runtime_resume   NULL
> +#endif /* CONFIG_PM_RUNTIME */
> +
> +static const struct dev_pm_ops pl330_pm_ops = {
> +       .runtime_suspend = pl330_runtime_suspend,
> +       .runtime_resume = pl330_runtime_resume,
> +};
> +
>  static struct amba_driver pl330_driver = {
>        .drv = {
>                .owner = THIS_MODULE,
>                .name = "dma-pl330",
> +               .pm = &pl330_pm_ops,
>        },
>        .id_table = pl330_ids,
>        .probe = pl330_probe,
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

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

* [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
@ 2011-07-05  6:11     ` Alim Akhtar
  0 siblings, 0 replies; 86+ messages in thread
From: Alim Akhtar @ 2011-07-05  6:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Jul 4, 2011 at 5:48 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> From: Boojin Kim <boojin.kim@samsung.com>
>
> Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
> Cc: Vinod Koul <vinod.koul@intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> ---
> ?drivers/dma/pl330.c | ? 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
> ?1 files changed, 61 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 6abe1ec..7bd72e9 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -17,6 +17,7 @@
> ?#include <linux/interrupt.h>
> ?#include <linux/amba/bus.h>
> ?#include <linux/amba/pl330.h>
> +#include <linux/pm_runtime.h>
>
> ?#define NR_DEFAULT_DESC ? ? ? ?16
>
> @@ -666,6 +667,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
> ? ? ? ?struct dma_device *pd;
> ? ? ? ?struct resource *res;
> ? ? ? ?int i, ret, irq;
> + ? ? ? struct clk* clk;
>
> ? ? ? ?pdat = adev->dev.platform_data;
>
> @@ -696,6 +698,28 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
> ? ? ? ? ? ? ? ?goto probe_err1;
> ? ? ? ?}
>
> +#ifdef CONFIG_PM_RUNTIME
> + ? ? ? /* to use the runtime PM helper functions */
> + ? ? ? pm_runtime_enable(&adev->dev);
> +
> + ? ? ? /* enable the power domain */
> + ? ? ? if (pm_runtime_get_sync(&adev->dev)) {
> + ? ? ? ? ? ? ? dev_err(&adev->dev, "failed to get runtime pm\n");
> + ? ? ? ? ? ? ? ret = -ENODEV;
> + ? ? ? ? ? ? ? goto probe_err1;
> + ? ? ? }
> +#else
> + ? ? ? /* enable dma clk */
> + ? ? ? clk = clk_get(&adev->dev, "dma");

Does this really needed here?
AFAIR, amba_get_enable_pclk() does the same thing, provided clock name
as "apb_pclk"
please have a look at drivers/amba/bus.c

> +
> + ? ? ? if (IS_ERR(clk)) {
> + ? ? ? ? ? ? ? dev_err(&adev->dev, "Cannot get operation clock.\n");
> + ? ? ? ? ? ? ? ret = -EINVAL;
> + ? ? ? ? ? ? ? goto probe_err1;
> + ? ? ? }
> + ? ? ? clk_enable(clk);
> +#endif
> +
> ? ? ? ?irq = adev->irq[0];
> ? ? ? ?ret = request_irq(irq, pl330_irq_handler, 0,
> ? ? ? ? ? ? ? ? ? ? ? ?dev_name(&adev->dev), pi);
> @@ -838,10 +862,47 @@ static struct amba_id pl330_ids[] = {
> ? ? ? ?{ 0, 0 },
> ?};
>
> +#ifdef CONFIG_PM_RUNTIME
> +static int pl330_runtime_suspend(struct device *dev)
> +{
> + ? ? ? struct clk *dmaclk = clk_get(dev, "dma");
> +
> + ? ? ? if (dmaclk == NULL) {
> + ? ? ? ? ? ? ? dev_err(dev, "failed to find dma clock source\n");
> + ? ? ? ? ? ? ? return -ENODEV;
> + ? ? ? }
> +
> + ? ? ? clk_disable(dmaclk);
> + ? ? ? return 0;
> +}
> +
> +static int pl330_runtime_resume(struct device *dev)
> +{
> + ? ? ? struct clk *dmaclk = clk_get(dev, "dma");
> +
> + ? ? ? if (dmaclk == NULL) {
> + ? ? ? ? ? ? ? dev_err(dev, "failed to find dma clock source\n");
> + ? ? ? ? ? ? ? return -ENODEV;
> + ? ? ? }
> +
> + ? ? ? clk_enable(dmaclk);
> + ? ? ? return 0;
> +}
> +#else
> +#define pl330_runtime_suspend ?NULL
> +#define pl330_runtime_resume ? NULL
> +#endif /* CONFIG_PM_RUNTIME */
> +
> +static const struct dev_pm_ops pl330_pm_ops = {
> + ? ? ? .runtime_suspend = pl330_runtime_suspend,
> + ? ? ? .runtime_resume = pl330_runtime_resume,
> +};
> +
> ?static struct amba_driver pl330_driver = {
> ? ? ? ?.drv = {
> ? ? ? ? ? ? ? ?.owner = THIS_MODULE,
> ? ? ? ? ? ? ? ?.name = "dma-pl330",
> + ? ? ? ? ? ? ? .pm = &pl330_pm_ops,
> ? ? ? ?},
> ? ? ? ?.id_table = pl330_ids,
> ? ? ? ?.probe = pl330_probe,
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 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] 86+ messages in thread

* Re: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-05  6:33     ` Chanho Park
  -1 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  6:33 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Vinod Koul, Dan Williams,
	Grant Likely, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

Kukjin Kim <kgene.kim <at> samsung.com> writes:

(snip)

> +             if (slave_config->direction == DMA_TO_DEVICE) {
> +                     if (slave_config->dst_addr)
> +                             peri->fifo_addr = slave_config->dst_addr;
> +                     if (slave_config->dst_addr_width) {
> +                             i = 0;
> +                             while (slave_config->dst_addr_width != (1 <<
i))
> +                                     i++;
> +                             peri->burst_sz = i;
> +                     }
> +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
> +                     if (slave_config->src_addr)
> +                             peri->fifo_addr = slave_config->src_addr;
> +                     if (slave_config->src_addr_width) {
> +                             i = 0;
> +                             while (slave_config->src_addr_width != (1 <<
i))
> +                                     i++;
> +                             peri->burst_sz = i;

Re-send including cc and mailing lists
--
pl330 dmac only supports 1/2/4/8/16 bytes burst size.
If some bad D/D doesn't use powers of 2 width,
dmaengine is going to infinite loop.
You'd better check it instead of running loop.

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-05  6:33     ` Chanho Park
  0 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  6:33 UTC (permalink / raw)
  To: linux-arm-kernel

Kukjin Kim <kgene.kim <at> samsung.com> writes:

(snip)

> +             if (slave_config->direction == DMA_TO_DEVICE) {
> +                     if (slave_config->dst_addr)
> +                             peri->fifo_addr = slave_config->dst_addr;
> +                     if (slave_config->dst_addr_width) {
> +                             i = 0;
> +                             while (slave_config->dst_addr_width != (1 <<
i))
> +                                     i++;
> +                             peri->burst_sz = i;
> +                     }
> +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
> +                     if (slave_config->src_addr)
> +                             peri->fifo_addr = slave_config->src_addr;
> +                     if (slave_config->src_addr_width) {
> +                             i = 0;
> +                             while (slave_config->src_addr_width != (1 <<
i))
> +                                     i++;
> +                             peri->burst_sz = i;

Re-send including cc and mailing lists
--
pl330 dmac only supports 1/2/4/8/16 bytes burst size.
If some bad D/D doesn't use powers of 2 width,
dmaengine is going to infinite loop.
You'd better check it instead of running loop.

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

* RE: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 23:27             ` Grant Likely
@ 2011-07-05  7:05               ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:05 UTC (permalink / raw)
  To: 'Grant Likely', 'Heiko Stübner'
  Cc: linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Jassi Brar',
	'Liam Girdwood', 'Mark Brown',
	'Boojin Kim'

Grant Likely wrote:
> 
> On Mon, Jul 04, 2011 at 09:51:43PM +0200, Heiko Stübner wrote:
> > Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
> > > On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko Stübner wrote:
> > > > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > > > >
> > > > > Wow.  A lot of #ifdefs here.  It does not look multiplatform
friendly
> > > > > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330
is
> > > > > selected?  If so, can they be removed entirely, or are they
required
> > > > > to support certain hardware?
> > > >
> > > > The spi_s3c64xx driver can also support the SPI controller of the
> > > > S3C2416/S3C2443 line of SoCs.
> > > > As I'm currently working on a S3C2416 based project, my small wish
from
> > > > the sidelines would be to not break this support with whatever
solution
> > > > you will decide on :-) .
> > >
> > > I will not merge a patch that either breaks a platform, or requires
> > > a compile time either/or choice of device support (enabling support
> > > for one device should not break support for another).
> >
> > The patch above seems to contain the support for both SoCs (i.e.
> s3c2410_dma_*
> > for S3C2416 etc), so it wouldn't break the support.
> > But this form will definitly break future multiplatform kernels when the
2416
> > and some variant using the DMADEV_PL330 are selected at the same time.
> 
> Yes, that's the breakage I'm talking about.
> 
> > The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller
of
> > this type. Implementing the DMA engine stuff for these SoCs would
obviously
> > solve the ifdef-problem but I don't know if this is possible to do.
> 
> Of course it's possible, it's just software.  :-D
> 
> If a config option is either/or then it needs to be really well
> justified before I will accept it.  Most either/or options I've seen
> aren't for any strong technical reason other than it was easier to
> code that way.

Hi all,

Yes I know your concerns on this.

First of all, please see below which is block diagram of Samsung DMA usage
and 1st step will be finished with other patches for S5PC100 and S5PV210
soon. Basically we need more time maybe 2 or 3 days to test on boards.

+---------------------------------------------------------------------+
| Each drivers which uses DMA                                         |
+---------------------------------------------------------------------+
| S3C DMA API (such as s3c2410_dma_xxxx)                              |
+-------------------------------+-------------------------------------+
| PL080 DMA driver              | S3C PL330 DMA API driver            |
| for S3C24XX and S3C64XX       | (arch/arm/plat-samsung/s3c-pl330.c) |
|                               +-------------------------------------+
| (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver              |
| (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c)           |
+-------------------------------+-------------------------------------+
                               ||
          (1st step. removing S3C DMA API for PL330)
                               ||
                               \/
+---------------------------------------------------------------------+
| Each drivers which uses DMA                                         |
+-------------------------------+-------------------------------------+
| S3C DMA API(s3c2410_dma_xxx)  | DMA generic API for PL330           |
+-------------------------------+-------------------------------------+
| PL080 DMA driver              | PL330 DMA API driver                |
| for S3C24XX and S3C64XX       | (drivers/dma/pl330.c)               |
|                               +-------------------------------------+
| (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver              |
| (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c)           |
+-------------------------------+-------------------------------------+

As you saw, the S3C_DMA_API is still used for PL080 DMA for compatibilities
with this patches in each driver, e.g., spi and audio. As a note, S3C24XX
and S3C64XX include PL080 DMAC not PL330.

Of course, if we can remove every S3C_DMA_API, that can be the best solution
but it needs more time. I'd like to go to our goal step by step.

Thanks.

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

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05  7:05               ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:05 UTC (permalink / raw)
  To: linux-arm-kernel

Grant Likely wrote:
> 
> On Mon, Jul 04, 2011 at 09:51:43PM +0200, Heiko St?bner wrote:
> > Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
> > > On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko St?bner wrote:
> > > > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
> > > > >
> > > > > Wow.  A lot of #ifdefs here.  It does not look multiplatform
friendly
> > > > > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330
is
> > > > > selected?  If so, can they be removed entirely, or are they
required
> > > > > to support certain hardware?
> > > >
> > > > The spi_s3c64xx driver can also support the SPI controller of the
> > > > S3C2416/S3C2443 line of SoCs.
> > > > As I'm currently working on a S3C2416 based project, my small wish
from
> > > > the sidelines would be to not break this support with whatever
solution
> > > > you will decide on :-) .
> > >
> > > I will not merge a patch that either breaks a platform, or requires
> > > a compile time either/or choice of device support (enabling support
> > > for one device should not break support for another).
> >
> > The patch above seems to contain the support for both SoCs (i.e.
> s3c2410_dma_*
> > for S3C2416 etc), so it wouldn't break the support.
> > But this form will definitly break future multiplatform kernels when the
2416
> > and some variant using the DMADEV_PL330 are selected at the same time.
> 
> Yes, that's the breakage I'm talking about.
> 
> > The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller
of
> > this type. Implementing the DMA engine stuff for these SoCs would
obviously
> > solve the ifdef-problem but I don't know if this is possible to do.
> 
> Of course it's possible, it's just software.  :-D
> 
> If a config option is either/or then it needs to be really well
> justified before I will accept it.  Most either/or options I've seen
> aren't for any strong technical reason other than it was easier to
> code that way.

Hi all,

Yes I know your concerns on this.

First of all, please see below which is block diagram of Samsung DMA usage
and 1st step will be finished with other patches for S5PC100 and S5PV210
soon. Basically we need more time maybe 2 or 3 days to test on boards.

+---------------------------------------------------------------------+
| Each drivers which uses DMA                                         |
+---------------------------------------------------------------------+
| S3C DMA API (such as s3c2410_dma_xxxx)                              |
+-------------------------------+-------------------------------------+
| PL080 DMA driver              | S3C PL330 DMA API driver            |
| for S3C24XX and S3C64XX       | (arch/arm/plat-samsung/s3c-pl330.c) |
|                               +-------------------------------------+
| (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver              |
| (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c)           |
+-------------------------------+-------------------------------------+
                               ||
          (1st step. removing S3C DMA API for PL330)
                               ||
                               \/
+---------------------------------------------------------------------+
| Each drivers which uses DMA                                         |
+-------------------------------+-------------------------------------+
| S3C DMA API(s3c2410_dma_xxx)  | DMA generic API for PL330           |
+-------------------------------+-------------------------------------+
| PL080 DMA driver              | PL330 DMA API driver                |
| for S3C24XX and S3C64XX       | (drivers/dma/pl330.c)               |
|                               +-------------------------------------+
| (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver              |
| (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c)           |
+-------------------------------+-------------------------------------+

As you saw, the S3C_DMA_API is still used for PL080 DMA for compatibilities
with this patches in each driver, e.g., spi and audio. As a note, S3C24XX
and S3C64XX include PL080 DMAC not PL330.

Of course, if we can remove every S3C_DMA_API, that can be the best solution
but it needs more time. I'd like to go to our goal step by step.

Thanks.

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

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

* RE: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-05  6:33     ` Chanho Park
@ 2011-07-05  7:10       ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:10 UTC (permalink / raw)
  To: 'Chanho Park'
  Cc: linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Grant Likely',
	'Jassi Brar', 'Liam Girdwood',
	'Mark Brown', 'Boojin Kim'

Chanho Park wrote:
> 
> Kukjin Kim <kgene.kim <at> samsung.com> writes:
> 
> (snip)
> 
> > +             if (slave_config->direction == DMA_TO_DEVICE) {
> > +                     if (slave_config->dst_addr)
> > +                             peri->fifo_addr = slave_config->dst_addr;
> > +                     if (slave_config->dst_addr_width) {
> > +                             i = 0;
> > +                             while (slave_config->dst_addr_width != (1
<<
> i))
> > +                                     i++;
> > +                             peri->burst_sz = i;
> > +                     }
> > +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
> > +                     if (slave_config->src_addr)
> > +                             peri->fifo_addr = slave_config->src_addr;
> > +                     if (slave_config->src_addr_width) {
> > +                             i = 0;
> > +                             while (slave_config->src_addr_width != (1
<<
> i))
> > +                                     i++;
> > +                             peri->burst_sz = i;
> 
> Re-send including cc and mailing lists
> --
> pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> If some bad D/D doesn't use powers of 2 width,
> dmaengine is going to infinite loop.
> You'd better check it instead of running loop.

Basically, src_addr_width is defined as a 'enum dma_slave_buswidth' so I
think we don't need to consider it.

Thanks.

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

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-05  7:10       ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:10 UTC (permalink / raw)
  To: linux-arm-kernel

Chanho Park wrote:
> 
> Kukjin Kim <kgene.kim <at> samsung.com> writes:
> 
> (snip)
> 
> > +             if (slave_config->direction == DMA_TO_DEVICE) {
> > +                     if (slave_config->dst_addr)
> > +                             peri->fifo_addr = slave_config->dst_addr;
> > +                     if (slave_config->dst_addr_width) {
> > +                             i = 0;
> > +                             while (slave_config->dst_addr_width != (1
<<
> i))
> > +                                     i++;
> > +                             peri->burst_sz = i;
> > +                     }
> > +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
> > +                     if (slave_config->src_addr)
> > +                             peri->fifo_addr = slave_config->src_addr;
> > +                     if (slave_config->src_addr_width) {
> > +                             i = 0;
> > +                             while (slave_config->src_addr_width != (1
<<
> i))
> > +                                     i++;
> > +                             peri->burst_sz = i;
> 
> Re-send including cc and mailing lists
> --
> pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> If some bad D/D doesn't use powers of 2 width,
> dmaengine is going to infinite loop.
> You'd better check it instead of running loop.

Basically, src_addr_width is defined as a 'enum dma_slave_buswidth' so I
think we don't need to consider it.

Thanks.

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

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

* RE: [PATCH 7/7] ASoC: Samsung: Update DMA interface
  2011-07-04 17:03     ` Mark Brown
@ 2011-07-05  7:19       ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:19 UTC (permalink / raw)
  To: 'Mark Brown'
  Cc: linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Grant Likely',
	'Jassi Brar', 'Liam Girdwood',
	'Boojin Kim'

Mark Brown wrote:
> 
Hi Mark,

Please refer to my other comment which includes block diagram, it can help
our understanding about current Samsung DMA usage.

> Two questions here:
> 
> - It looks like a lot of this code can be shared between all the drivers
>   using the dmaengine API.  Is there any reason not to factor it out?

Hmm...I'm not sure, but let us think/check your suggestions. Thanks :)

> - Should this not be adding a new driver for dmaengine based Samsung
>   CPUs?  The ifdefs are very big.

OK, we will try.

Grant, I think, Mark's suggestion can support multiple platform...

Thanks.

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

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

* [PATCH 7/7] ASoC: Samsung: Update DMA interface
@ 2011-07-05  7:19       ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Mark Brown wrote:
> 
Hi Mark,

Please refer to my other comment which includes block diagram, it can help
our understanding about current Samsung DMA usage.

> Two questions here:
> 
> - It looks like a lot of this code can be shared between all the drivers
>   using the dmaengine API.  Is there any reason not to factor it out?

Hmm...I'm not sure, but let us think/check your suggestions. Thanks :)

> - Should this not be adding a new driver for dmaengine based Samsung
>   CPUs?  The ifdefs are very big.

OK, we will try.

Grant, I think, Mark's suggestion can support multiple platform...

Thanks.

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

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

* RE: [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
  2011-07-05  6:11     ` Alim Akhtar
@ 2011-07-05  7:26       ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:26 UTC (permalink / raw)
  To: 'Alim Akhtar'
  Cc: linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Grant Likely',
	'Jassi Brar', 'Liam Girdwood',
	'Mark Brown', 'Boojin Kim'

Alim Akhtar wrote:
> > +       /* enable dma clk */
> > +       clk = clk_get(&adev->dev, "dma");
> 
> Does this really needed here?
> AFAIR, amba_get_enable_pclk() does the same thing, provided clock name
> as "apb_pclk"
> please have a look at drivers/amba/bus.c
> 
As I know, you can access Samsung datasheet, please check it.

Actually, the 'apb_pclk' should be dummy clock on current S5P SoCs so can't
use it now.

Thanks.

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

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

* [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
@ 2011-07-05  7:26       ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-05  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

Alim Akhtar wrote:
> > + ? ? ? /* enable dma clk */
> > + ? ? ? clk = clk_get(&adev->dev, "dma");
> 
> Does this really needed here?
> AFAIR, amba_get_enable_pclk() does the same thing, provided clock name
> as "apb_pclk"
> please have a look at drivers/amba/bus.c
> 
As I know, you can access Samsung datasheet, please check it.

Actually, the 'apb_pclk' should be dummy clock on current S5P SoCs so can't
use it now.

Thanks.

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

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

* Re: [PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-05  7:36     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  7:36 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Mark Brown, Boojin Kim,
	Vinod Koul, Jassi Brar, Grant Likely, Dan Williams,
	Liam Girdwood

On Mon, Jul 04, 2011 at 09:18:30PM +0900, Kukjin Kim wrote:
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 25cf327..9b7f15a 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
>  config PL330_DMA
>  	tristate "DMA API Driver for PL330"
>  	select DMA_ENGINE
> -	depends on PL330
> +	select ARM_AMBA

This is the wrong way around.  If your SoC supports Primecells, then you are
supposed to select ARM_AMBA from the SoC to allow the Primecell drivers to be
enabled.  Primecell drivers should then depend on ARM_AMBA.

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

* [PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
@ 2011-07-05  7:36     ` Russell King - ARM Linux
  0 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  7:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 09:18:30PM +0900, Kukjin Kim wrote:
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 25cf327..9b7f15a 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
>  config PL330_DMA
>  	tristate "DMA API Driver for PL330"
>  	select DMA_ENGINE
> -	depends on PL330
> +	select ARM_AMBA

This is the wrong way around.  If your SoC supports Primecells, then you are
supposed to select ARM_AMBA from the SoC to allow the Primecell drivers to be
enabled.  Primecell drivers should then depend on ARM_AMBA.

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

* Re: [PATCH 7/7] ASoC: Samsung: Update DMA interface
  2011-07-04 17:03     ` Mark Brown
@ 2011-07-05  7:45       ` Seungwhan Youn
  -1 siblings, 0 replies; 86+ messages in thread
From: Seungwhan Youn @ 2011-07-05  7:45 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Grant Likely, Jassi Brar, Liam Girdwood,
	Boojin Kim

> Two questions here:
>
> - It looks like a lot of this code can be shared between all the drivers
>  using the dmaengine API.  Is there any reason not to factor it out?
> - Should this not be adding a new driver for dmaengine based Samsung
>  CPUs?  The ifdefs are very big.

I think that dma code looks very similar to current one, so how about
using platform_resource setting for dma type and make some inline
functions to cover these differences? We already have platform driver
for dma in arch/arm and dev-audio.c.

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

* [PATCH 7/7] ASoC: Samsung: Update DMA interface
@ 2011-07-05  7:45       ` Seungwhan Youn
  0 siblings, 0 replies; 86+ messages in thread
From: Seungwhan Youn @ 2011-07-05  7:45 UTC (permalink / raw)
  To: linux-arm-kernel

> Two questions here:
>
> - It looks like a lot of this code can be shared between all the drivers
> ?using the dmaengine API. ?Is there any reason not to factor it out?
> - Should this not be adding a new driver for dmaengine based Samsung
> ?CPUs? ?The ifdefs are very big.

I think that dma code looks very similar to current one, so how about
using platform_resource setting for dma type and make some inline
functions to cover these differences? We already have platform driver
for dma in arch/arm and dev-audio.c.

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-05  7:48     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  7:48 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Mark Brown, Boojin Kim,
	Vinod Koul, Jassi Brar, Grant Likely, Dan Williams,
	Liam Girdwood

On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
>  static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  				struct spi_device *spi,
>  				struct spi_transfer *xfer, int dma_mode)
> @@ -236,6 +322,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
>  	void __iomem *regs = sdd->regs;
>  	u32 modecfg, chcfg;
> +#if defined(CONFIG_DMADEV_PL330)
> +	struct dma_slave_config slave_config;
> +	struct scatterlist tx_sg;
> +	struct scatterlist rx_sg;
> +#endif
>  
>  	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
>  	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
> @@ -261,10 +352,34 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
>  		if (dma_mode) {
>  			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
> +#if defined(CONFIG_DMADEV_PL330)
> +			memset(&slave_config, 0, sizeof(slave_config));
> +			slave_config.direction = DMA_TO_DEVICE;
> +			slave_config.src_addr = xfer->tx_dma;

If you're doing DMA to the device, you should not set src_addr here.
That comes from the SG list passed in via the prep function.

> +			slave_config.dst_addr =
> +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> +
> +			sg_init_table(&tx_sg, 1);
> +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> +				xfer->len, offset_in_page(xfer->tx_dma));
> +			sg_dma_len(&tx_sg) =  xfer->len;
> +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> +			sdd->tx_desc =
> +				sdd->tx_chan->device->device_prep_slave_sg(
> +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> +			sdd->tx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->tx_desc);
> +			dma_async_issue_pending(sdd->tx_chan);
> +#else
>  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
>  						xfer->tx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> +#endif
>  		} else {
>  			switch (sdd->cur_bpw) {
>  			case 32:
> @@ -296,10 +411,33 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
>  					| S3C64XX_SPI_PACKET_CNT_EN,
>  					regs + S3C64XX_SPI_PACKET_CNT);
> +#if defined(CONFIG_DMADEV_PL330)
> +			slave_config.direction = DMA_FROM_DEVICE;
> +			slave_config.dst_addr = xfer->rx_dma;

If you're doing DMA from the device, you should not set dst_addr here.
That comes from the SG list passed in via the prep function.

> +			slave_config.src_addr =
> +				sdd->sfr_start + S3C64XX_SPI_RX_DATA;
> +			slave_config.src_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->rx_chan, &slave_config);
> +
> +			sg_init_table(&rx_sg, 1);
> +			sg_set_page(&rx_sg, pfn_to_page(PFN_DOWN(xfer->rx_dma)),
> +				xfer->len, offset_in_page(xfer->rx_dma));
> +			sg_dma_len(&rx_sg) =  xfer->len;
> +			sg_dma_address(&rx_sg) = xfer->rx_dma;
> +			sdd->rx_desc =
> +				sdd->rx_chan->device->device_prep_slave_sg(
> +				sdd->rx_chan, &rx_sg, 1, DMA_FROM_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->rx_desc->callback = s3c64xx_spi_dma_rxcb;
> +			sdd->rx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->rx_desc);
> +			dma_async_issue_pending(sdd->rx_chan);
> +#else
>  			s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
>  						xfer->rx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
> +#endif
>  		}
>  	}
>  

> @@ -742,8 +848,50 @@ out:
>  		msg->complete(msg->context);
>  }
>  
> +#if defined(CONFIG_DMADEV_PL330)
> +static bool rxfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->rx_dmach)
> +		return false;
> +
> +	return true;
> +}

Blank line here please.

> +static bool txfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->tx_dmach)
> +		return false;
> +
> +	return true;
> +}
> +#endif
> +
>  static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
>  {
> +#if defined(CONFIG_DMADEV_PL330)
> +	dma_cap_mask_t mask;
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_SLAVE, mask);
> +	sdd->rx_chan =
> +		dma_request_channel(mask, rxfilter, (void *)sdd);

No need to split this line.

> +	if (!sdd->rx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> +		return 0;
> +	}
> +	sdd->tx_chan =
> +		dma_request_channel(mask, txfilter, (void *)sdd);

Nor this one.

> +	if (!sdd->tx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
> +		return 0;
> +	}

As you have separate DMA channels for TX and RX, you should be able to
configure the channels once here, and avoid making the
dmaengine_slave_config calls during normal operation.

> +#else
>  	if (s3c2410_dma_request(sdd->rx_dmach,
>  					&s3c64xx_spi_dma_client, NULL) < 0) {
>  		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");

Last point - for correctness, the struct device which should be used
when mapping and unmapping buffers for the DMA engine is the DMA
engine's struct device.

In other words, sdd->tx_chan->device->dev for TX transfers, and
sdd->rx_chan->device->dev for RX transfers.

The DMA engine device is the struct device which actually performs the
reading/writing of memory, and has the limitations on SG geometry, not
the peripheral device.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05  7:48     ` Russell King - ARM Linux
  0 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  7:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 09:18:34PM +0900, Kukjin Kim wrote:
>  static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  				struct spi_device *spi,
>  				struct spi_transfer *xfer, int dma_mode)
> @@ -236,6 +322,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
>  	void __iomem *regs = sdd->regs;
>  	u32 modecfg, chcfg;
> +#if defined(CONFIG_DMADEV_PL330)
> +	struct dma_slave_config slave_config;
> +	struct scatterlist tx_sg;
> +	struct scatterlist rx_sg;
> +#endif
>  
>  	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
>  	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
> @@ -261,10 +352,34 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
>  		if (dma_mode) {
>  			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
> +#if defined(CONFIG_DMADEV_PL330)
> +			memset(&slave_config, 0, sizeof(slave_config));
> +			slave_config.direction = DMA_TO_DEVICE;
> +			slave_config.src_addr = xfer->tx_dma;

If you're doing DMA to the device, you should not set src_addr here.
That comes from the SG list passed in via the prep function.

> +			slave_config.dst_addr =
> +				sdd->sfr_start + S3C64XX_SPI_TX_DATA;
> +			slave_config.dst_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->tx_chan, &slave_config);
> +
> +			sg_init_table(&tx_sg, 1);
> +			sg_set_page(&tx_sg, pfn_to_page(PFN_DOWN(xfer->tx_dma)),
> +				xfer->len, offset_in_page(xfer->tx_dma));
> +			sg_dma_len(&tx_sg) =  xfer->len;
> +			sg_dma_address(&tx_sg) = xfer->tx_dma;
> +			sdd->tx_desc =
> +				sdd->tx_chan->device->device_prep_slave_sg(
> +				sdd->tx_chan, &tx_sg, 1, DMA_TO_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->tx_desc->callback = s3c64xx_spi_dma_txcb;
> +			sdd->tx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->tx_desc);
> +			dma_async_issue_pending(sdd->tx_chan);
> +#else
>  			s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
>  						xfer->tx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> +#endif
>  		} else {
>  			switch (sdd->cur_bpw) {
>  			case 32:
> @@ -296,10 +411,33 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>  			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
>  					| S3C64XX_SPI_PACKET_CNT_EN,
>  					regs + S3C64XX_SPI_PACKET_CNT);
> +#if defined(CONFIG_DMADEV_PL330)
> +			slave_config.direction = DMA_FROM_DEVICE;
> +			slave_config.dst_addr = xfer->rx_dma;

If you're doing DMA from the device, you should not set dst_addr here.
That comes from the SG list passed in via the prep function.

> +			slave_config.src_addr =
> +				sdd->sfr_start + S3C64XX_SPI_RX_DATA;
> +			slave_config.src_addr_width = sdd->cur_bpw / 8;
> +			dmaengine_slave_config(sdd->rx_chan, &slave_config);
> +
> +			sg_init_table(&rx_sg, 1);
> +			sg_set_page(&rx_sg, pfn_to_page(PFN_DOWN(xfer->rx_dma)),
> +				xfer->len, offset_in_page(xfer->rx_dma));
> +			sg_dma_len(&rx_sg) =  xfer->len;
> +			sg_dma_address(&rx_sg) = xfer->rx_dma;
> +			sdd->rx_desc =
> +				sdd->rx_chan->device->device_prep_slave_sg(
> +				sdd->rx_chan, &rx_sg, 1, DMA_FROM_DEVICE,
> +				DMA_PREP_INTERRUPT);
> +			sdd->rx_desc->callback = s3c64xx_spi_dma_rxcb;
> +			sdd->rx_desc->callback_param = sdd;
> +			dmaengine_submit(sdd->rx_desc);
> +			dma_async_issue_pending(sdd->rx_chan);
> +#else
>  			s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
>  			s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
>  						xfer->rx_dma, xfer->len);
>  			s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
> +#endif
>  		}
>  	}
>  

> @@ -742,8 +848,50 @@ out:
>  		msg->complete(msg->context);
>  }
>  
> +#if defined(CONFIG_DMADEV_PL330)
> +static bool rxfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->rx_dmach)
> +		return false;
> +
> +	return true;
> +}

Blank line here please.

> +static bool txfilter(struct dma_chan *chan, void *param)
> +{
> +	struct s3c64xx_spi_driver_data *sdd
> +		= (struct s3c64xx_spi_driver_data *)param;
> +	struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan->private;
> +
> +	if (peri->peri_id != sdd->tx_dmach)
> +		return false;
> +
> +	return true;
> +}
> +#endif
> +
>  static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
>  {
> +#if defined(CONFIG_DMADEV_PL330)
> +	dma_cap_mask_t mask;
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_SLAVE, mask);
> +	sdd->rx_chan =
> +		dma_request_channel(mask, rxfilter, (void *)sdd);

No need to split this line.

> +	if (!sdd->rx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> +		return 0;
> +	}
> +	sdd->tx_chan =
> +		dma_request_channel(mask, txfilter, (void *)sdd);

Nor this one.

> +	if (!sdd->tx_chan) {
> +		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
> +		return 0;
> +	}

As you have separate DMA channels for TX and RX, you should be able to
configure the channels once here, and avoid making the
dmaengine_slave_config calls during normal operation.

> +#else
>  	if (s3c2410_dma_request(sdd->rx_dmach,
>  					&s3c64xx_spi_dma_client, NULL) < 0) {
>  		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");

Last point - for correctness, the struct device which should be used
when mapping and unmapping buffers for the DMA engine is the DMA
engine's struct device.

In other words, sdd->tx_chan->device->dev for TX transfers, and
sdd->rx_chan->device->dev for RX transfers.

The DMA engine device is the struct device which actually performs the
reading/writing of memory, and has the limitations on SG geometry, not
the peripheral device.

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-05  7:05               ` Kukjin Kim
@ 2011-07-05  7:53                 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  7:53 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: 'Grant Likely', 'Heiko Stübner',
	linux-samsung-soc, 'Boojin Kim', 'Vinod Koul',
	'Jassi Brar', 'Mark Brown',
	'Dan Williams', 'Liam Girdwood',
	linux-arm-kernel

On Tue, Jul 05, 2011 at 04:05:32PM +0900, Kukjin Kim wrote:
> Of course, if we can remove every S3C_DMA_API, that can be the best solution
> but it needs more time. I'd like to go to our goal step by step.

Surely one of the preconditions then is to improve the existing PL080
dmaengine driver to do what you need it to.

I've worked on that driver to bring it closer to sanity and correctness,
and its almost there.  The problem I have working on the driver is the
crippled ARM development hardware, where most DMA just doesn't work in
one way or another.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05  7:53                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  7:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 05, 2011 at 04:05:32PM +0900, Kukjin Kim wrote:
> Of course, if we can remove every S3C_DMA_API, that can be the best solution
> but it needs more time. I'd like to go to our goal step by step.

Surely one of the preconditions then is to improve the existing PL080
dmaengine driver to do what you need it to.

I've worked on that driver to bring it closer to sanity and correctness,
and its almost there.  The problem I have working on the driver is the
crippled ARM development hardware, where most DMA just doesn't work in
one way or another.

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

* Re: [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-05  8:04     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  8:04 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Mark Brown, Boojin Kim,
	Vinod Koul, Jassi Brar, Grant Likely, Dan Williams,
	Liam Girdwood

On Mon, Jul 04, 2011 at 09:18:29PM +0900, Kukjin Kim wrote:
> @@ -666,6 +667,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  	struct dma_device *pd;
>  	struct resource *res;
>  	int i, ret, irq;
> +	struct clk* clk;

Please use checkpatch.  'struct clk *clk;'

> @@ -696,6 +698,28 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  		goto probe_err1;
>  	}
>  

Get the clock here and save its pointer.  put the clock in the remove function.

> +#ifdef CONFIG_PM_RUNTIME
> +	/* to use the runtime PM helper functions */
> +	pm_runtime_enable(&adev->dev);
> +
> +	/* enable the power domain */
> +	if (pm_runtime_get_sync(&adev->dev)) {
> +		dev_err(&adev->dev, "failed to get runtime pm\n");
> +		ret = -ENODEV;
> +		goto probe_err1;
> +	}
> +#else
> +	/* enable dma clk */
> +	clk = clk_get(&adev->dev, "dma");
> +
> +	if (IS_ERR(clk)) {
> +		dev_err(&adev->dev, "Cannot get operation clock.\n");
> +		ret = -EINVAL;
> +		goto probe_err1;
> +	}
> +	clk_enable(clk);
> +#endif
> +
>  	irq = adev->irq[0];
>  	ret = request_irq(irq, pl330_irq_handler, 0,
>  			dev_name(&adev->dev), pi);
> @@ -838,10 +862,47 @@ static struct amba_id pl330_ids[] = {
>  	{ 0, 0 },
>  };
>  
> +#ifdef CONFIG_PM_RUNTIME
> +static int pl330_runtime_suspend(struct device *dev)
> +{
> +	struct clk *dmaclk = clk_get(dev, "dma");
> +
> +	if (dmaclk == NULL) {
> +		dev_err(dev, "failed to find dma clock source\n");
> +		return -ENODEV;
> +	}

Obviously wrong.

Use the clock you got in the probe function here.

> +
> +	clk_disable(dmaclk);
> +	return 0;
> +}
> +
> +static int pl330_runtime_resume(struct device *dev)
> +{
> +	struct clk *dmaclk = clk_get(dev, "dma");
> +
> +	if (dmaclk == NULL) {
> +		dev_err(dev, "failed to find dma clock source\n");
> +		return -ENODEV;
> +	}

Obviously wrong as well.

Use the clock you got in the probe function here too.

> +
> +	clk_enable(dmaclk);
> +	return 0;
> +}
> +#else
> +#define pl330_runtime_suspend	NULL
> +#define pl330_runtime_resume	NULL
> +#endif /* CONFIG_PM_RUNTIME */
> +
> +static const struct dev_pm_ops pl330_pm_ops = {
> +	.runtime_suspend = pl330_runtime_suspend,
> +	.runtime_resume = pl330_runtime_resume,
> +};
> +
>  static struct amba_driver pl330_driver = {
>  	.drv = {
>  		.owner = THIS_MODULE,
>  		.name = "dma-pl330",
> +		.pm = &pl330_pm_ops,
>  	},
>  	.id_table = pl330_ids,
>  	.probe = pl330_probe,
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> 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] 86+ messages in thread

* [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
@ 2011-07-05  8:04     ` Russell King - ARM Linux
  0 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05  8:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 04, 2011 at 09:18:29PM +0900, Kukjin Kim wrote:
> @@ -666,6 +667,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  	struct dma_device *pd;
>  	struct resource *res;
>  	int i, ret, irq;
> +	struct clk* clk;

Please use checkpatch.  'struct clk *clk;'

> @@ -696,6 +698,28 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>  		goto probe_err1;
>  	}
>  

Get the clock here and save its pointer.  put the clock in the remove function.

> +#ifdef CONFIG_PM_RUNTIME
> +	/* to use the runtime PM helper functions */
> +	pm_runtime_enable(&adev->dev);
> +
> +	/* enable the power domain */
> +	if (pm_runtime_get_sync(&adev->dev)) {
> +		dev_err(&adev->dev, "failed to get runtime pm\n");
> +		ret = -ENODEV;
> +		goto probe_err1;
> +	}
> +#else
> +	/* enable dma clk */
> +	clk = clk_get(&adev->dev, "dma");
> +
> +	if (IS_ERR(clk)) {
> +		dev_err(&adev->dev, "Cannot get operation clock.\n");
> +		ret = -EINVAL;
> +		goto probe_err1;
> +	}
> +	clk_enable(clk);
> +#endif
> +
>  	irq = adev->irq[0];
>  	ret = request_irq(irq, pl330_irq_handler, 0,
>  			dev_name(&adev->dev), pi);
> @@ -838,10 +862,47 @@ static struct amba_id pl330_ids[] = {
>  	{ 0, 0 },
>  };
>  
> +#ifdef CONFIG_PM_RUNTIME
> +static int pl330_runtime_suspend(struct device *dev)
> +{
> +	struct clk *dmaclk = clk_get(dev, "dma");
> +
> +	if (dmaclk == NULL) {
> +		dev_err(dev, "failed to find dma clock source\n");
> +		return -ENODEV;
> +	}

Obviously wrong.

Use the clock you got in the probe function here.

> +
> +	clk_disable(dmaclk);
> +	return 0;
> +}
> +
> +static int pl330_runtime_resume(struct device *dev)
> +{
> +	struct clk *dmaclk = clk_get(dev, "dma");
> +
> +	if (dmaclk == NULL) {
> +		dev_err(dev, "failed to find dma clock source\n");
> +		return -ENODEV;
> +	}

Obviously wrong as well.

Use the clock you got in the probe function here too.

> +
> +	clk_enable(dmaclk);
> +	return 0;
> +}
> +#else
> +#define pl330_runtime_suspend	NULL
> +#define pl330_runtime_resume	NULL
> +#endif /* CONFIG_PM_RUNTIME */
> +
> +static const struct dev_pm_ops pl330_pm_ops = {
> +	.runtime_suspend = pl330_runtime_suspend,
> +	.runtime_resume = pl330_runtime_resume,
> +};
> +
>  static struct amba_driver pl330_driver = {
>  	.drv = {
>  		.owner = THIS_MODULE,
>  		.name = "dma-pl330",
> +		.pm = &pl330_pm_ops,
>  	},
>  	.id_table = pl330_ids,
>  	.probe = pl330_probe,
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> 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] 86+ messages in thread

* Re: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-05  7:10       ` Kukjin Kim
@ 2011-07-05  8:08         ` Chanho Park
  -1 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  8:08 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Vinod Koul, Dan Williams,
	Grant Likely, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

>
> Basically, src_addr_width is defined as a 'enum dma_slave_buswidth' so I
> think we don't need to consider it.
>

Client D/D normally uses 'enum dma_slave_buswidth' type.
However, dmaengine driver cannot guarantee all client D/D uses it.
See below your spi driver. Thus, the dmaengine driver check it correctly.

+#if defined(CONFIG_DMADEV_PL330)
+                       memset(&slave_config, 0, sizeof(slave_config));
+                       slave_config.direction = DMA_TO_DEVICE;
+                       slave_config.src_addr = xfer->tx_dma;
+                       slave_config.dst_addr =
+                               sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+                       slave_config.dst_addr_width = sdd->cur_bpw / 8;
+                       dmaengine_slave_config(sdd->tx_chan, &slave_config);

-- 
Best Regards,
Chanho Park

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-05  8:08         ` Chanho Park
  0 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  8:08 UTC (permalink / raw)
  To: linux-arm-kernel

>
> Basically, src_addr_width is defined as a 'enum dma_slave_buswidth' so I
> think we don't need to consider it.
>

Client D/D normally uses 'enum dma_slave_buswidth' type.
However, dmaengine driver cannot guarantee all client D/D uses it.
See below your spi driver. Thus, the dmaengine driver check it correctly.

+#if defined(CONFIG_DMADEV_PL330)
+                       memset(&slave_config, 0, sizeof(slave_config));
+                       slave_config.direction = DMA_TO_DEVICE;
+                       slave_config.src_addr = xfer->tx_dma;
+                       slave_config.dst_addr =
+                               sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+                       slave_config.dst_addr_width = sdd->cur_bpw / 8;
+                       dmaengine_slave_config(sdd->tx_chan, &slave_config);

-- 
Best Regards,
Chanho Park

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

* Re: [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
  2011-07-05  6:07     ` Alim Akhtar
@ 2011-07-05  8:30       ` Sangwook Lee
  -1 siblings, 0 replies; 86+ messages in thread
From: Sangwook Lee @ 2011-07-05  8:30 UTC (permalink / raw)
  To: Alim Akhtar
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Grant Likely, Jassi Brar, Liam Girdwood,
	Mark Brown, Boojin Kim

>> @@ -47,6 +47,11 @@ static struct clk clk_sclk_usbphy1 = {
>>        .id             = -1,
>>  };
>>
>> +static struct clk dummy_apb_pclk = {
>> +       .name           = "apb_pclk",
>> +       .id             = -1,
>> +};
>> +
> What is the need to creating "dummy_apb_pclk" ?

I guess this is right, because amba device should call amba_device_reigster and
this function requires apb_pclk, even if that is dummy clock.

>>
>>  static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)

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

* [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver
@ 2011-07-05  8:30       ` Sangwook Lee
  0 siblings, 0 replies; 86+ messages in thread
From: Sangwook Lee @ 2011-07-05  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

>> @@ -47,6 +47,11 @@ static struct clk clk_sclk_usbphy1 = {
>> ? ? ? ?.id ? ? ? ? ? ? = -1,
>> ?};
>>
>> +static struct clk dummy_apb_pclk = {
>> + ? ? ? .name ? ? ? ? ? = "apb_pclk",
>> + ? ? ? .id ? ? ? ? ? ? = -1,
>> +};
>> +
> What is the need to?creating "dummy_apb_pclk"??

I guess this is right, because amba device should call amba_device_reigster and
this function requires apb_pclk, even if that is dummy clock.

>>
>> ?static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-04 12:18   ` Kukjin Kim
@ 2011-07-05  8:39     ` Chanho Park
  -1 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  8:39 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-arm-kernel, linux-samsung-soc, Vinod Koul, Dan Williams,
	Grant Likely, Jassi Brar, Liam Girdwood, Mark Brown, Boojin Kim

>  static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
>  {
> +#if defined(CONFIG_DMADEV_PL330)
> +       dma_cap_mask_t mask;
> +       dma_cap_zero(mask);
> +       dma_cap_set(DMA_SLAVE, mask);
> +       sdd->rx_chan =
> +               dma_request_channel(mask, rxfilter, (void *)sdd);
> +       if (!sdd->rx_chan) {
> +               dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> +               return 0;
> +       }
> +       sdd->tx_chan =
> +               dma_request_channel(mask, txfilter, (void *)sdd);
> +       if (!sdd->tx_chan) {
> +               dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
> +               return 0;
> +       }
> +#else

When acquiring tx_chan is failed, you must release a rx_chan before
error return.
If not, the rx_chan is always busy because it was allocated in the
previous attempt.

-- 
Best Regards,
Chanho Park

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05  8:39     ` Chanho Park
  0 siblings, 0 replies; 86+ messages in thread
From: Chanho Park @ 2011-07-05  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

> ?static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
> ?{
> +#if defined(CONFIG_DMADEV_PL330)
> + ? ? ? dma_cap_mask_t mask;
> + ? ? ? dma_cap_zero(mask);
> + ? ? ? dma_cap_set(DMA_SLAVE, mask);
> + ? ? ? sdd->rx_chan =
> + ? ? ? ? ? ? ? dma_request_channel(mask, rxfilter, (void *)sdd);
> + ? ? ? if (!sdd->rx_chan) {
> + ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
> + ? ? ? ? ? ? ? return 0;
> + ? ? ? }
> + ? ? ? sdd->tx_chan =
> + ? ? ? ? ? ? ? dma_request_channel(mask, txfilter, (void *)sdd);
> + ? ? ? if (!sdd->tx_chan) {
> + ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
> + ? ? ? ? ? ? ? return 0;
> + ? ? ? }
> +#else

When acquiring tx_chan is failed, you must release a rx_chan before
error return.
If not, the rx_chan is always busy because it was allocated in the
previous attempt.

-- 
Best Regards,
Chanho Park

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-05  7:05               ` Kukjin Kim
@ 2011-07-05 10:51                 ` Heiko Stübner
  -1 siblings, 0 replies; 86+ messages in thread
From: Heiko Stübner @ 2011-07-05 10:51 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: linux-samsung-soc, 'Boojin Kim', 'Vinod Koul',
	'Jassi Brar', 'Grant Likely',
	'Mark Brown', 'Dan Williams',
	'Liam Girdwood',
	linux-arm-kernel

Am Dienstag, 5. Juli 2011, 09:05:32 schrieb Kukjin Kim:
[...]
> As a note, S3C24XX and S3C64XX include PL080 DMAC not PL330.
Are you sure the S3C24xx also uses a PL080?

At least for the 2416, the manual does not tell the type of DMA controller 
used. Also according to it it's a 6 channel controller where the pl080 has 8 
channels according to amba-pl08x.c .

So, to my untrained eye it looks like another type of controller - but I may 
be wrong.

Heiko

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05 10:51                 ` Heiko Stübner
  0 siblings, 0 replies; 86+ messages in thread
From: Heiko Stübner @ 2011-07-05 10:51 UTC (permalink / raw)
  To: linux-arm-kernel

Am Dienstag, 5. Juli 2011, 09:05:32 schrieb Kukjin Kim:
[...]
> As a note, S3C24XX and S3C64XX include PL080 DMAC not PL330.
Are you sure the S3C24xx also uses a PL080?

At least for the 2416, the manual does not tell the type of DMA controller 
used. Also according to it it's a 6 channel controller where the pl080 has 8 
channels according to amba-pl08x.c .

So, to my untrained eye it looks like another type of controller - but I may 
be wrong.

Heiko

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-05  7:05               ` Kukjin Kim
@ 2011-07-05 11:16                 ` Jassi Brar
  -1 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-05 11:16 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: Grant Likely, Heiko Stübner, linux-arm-kernel,
	linux-samsung-soc, Vinod Koul, Dan Williams, Liam Girdwood,
	Mark Brown, Boojin Kim

On Tue, Jul 5, 2011 at 12:35 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> Grant Likely wrote:
>>
>> On Mon, Jul 04, 2011 at 09:51:43PM +0200, Heiko Stübner wrote:
>> > Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
>> > > On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko Stübner wrote:
>> > > > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
>> > > > >
>> > > > > Wow.  A lot of #ifdefs here.  It does not look multiplatform
> friendly
>> > > > > at all.  Are the s3c2410_dma functions obsolete when DMADEV_PL330
> is
>> > > > > selected?  If so, can they be removed entirely, or are they
> required
>> > > > > to support certain hardware?
>> > > >
>> > > > The spi_s3c64xx driver can also support the SPI controller of the
>> > > > S3C2416/S3C2443 line of SoCs.
>> > > > As I'm currently working on a S3C2416 based project, my small wish
> from
>> > > > the sidelines would be to not break this support with whatever
> solution
>> > > > you will decide on :-) .
>> > >
>> > > I will not merge a patch that either breaks a platform, or requires
>> > > a compile time either/or choice of device support (enabling support
>> > > for one device should not break support for another).
>> >
>> > The patch above seems to contain the support for both SoCs (i.e.
>> s3c2410_dma_*
>> > for S3C2416 etc), so it wouldn't break the support.
>> > But this form will definitly break future multiplatform kernels when the
> 2416
>> > and some variant using the DMADEV_PL330 are selected at the same time.
>>
>> Yes, that's the breakage I'm talking about.
>>
>> > The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller
> of
>> > this type. Implementing the DMA engine stuff for these SoCs would
> obviously
>> > solve the ifdef-problem but I don't know if this is possible to do.
>>
>> Of course it's possible, it's just software.  :-D
>>
>> If a config option is either/or then it needs to be really well
>> justified before I will accept it.  Most either/or options I've seen
>> aren't for any strong technical reason other than it was easier to
>> code that way.
>
> Hi all,
>
> Yes I know your concerns on this.
>
> First of all, please see below which is block diagram of Samsung DMA usage
> and 1st step will be finished with other patches for S5PC100 and S5PV210
> soon. Basically we need more time maybe 2 or 3 days to test on boards.
>
> +---------------------------------------------------------------------+
> | Each drivers which uses DMA                                         |
> +---------------------------------------------------------------------+
> | S3C DMA API (such as s3c2410_dma_xxxx)                              |
> +-------------------------------+-------------------------------------+
> | PL080 DMA driver              | S3C PL330 DMA API driver            |
> | for S3C24XX and S3C64XX       | (arch/arm/plat-samsung/s3c-pl330.c) |
> |                               +-------------------------------------+
> | (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver              |
> | (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c)           |
> +-------------------------------+-------------------------------------+
>                               ||
>          (1st step. removing S3C DMA API for PL330)
>                               ||
>                               \/
> +---------------------------------------------------------------------+
> | Each drivers which uses DMA                                         |
> +-------------------------------+-------------------------------------+
> | S3C DMA API(s3c2410_dma_xxx)  | DMA generic API for PL330           |
> +-------------------------------+-------------------------------------+
> | PL080 DMA driver              | PL330 DMA API driver                |
> | for S3C24XX and S3C64XX       | (drivers/dma/pl330.c)               |
> |                               +-------------------------------------+
> | (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver              |
> | (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c)           |
> +-------------------------------+-------------------------------------+
>
> As you saw, the S3C_DMA_API is still used for PL080 DMA for compatibilities
> with this patches in each driver, e.g., spi and audio. As a note, S3C24XX
> and S3C64XX include PL080 DMAC not PL330.
Not exactly.
S3C24XX  use 2-3 different versions of Samsung's DMA implementations.
S3C6400/10  use PL080
S5P and later series use PL330

>
> Of course, if we can remove every S3C_DMA_API, that can be the best solution
> but it needs more time. I'd like to go to our goal step by step.
>
Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled for s3c64xx
And new generic dma api drivers written for S3C24xx in drivers/dma/

-j

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05 11:16                 ` Jassi Brar
  0 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-05 11:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 5, 2011 at 12:35 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> Grant Likely wrote:
>>
>> On Mon, Jul 04, 2011 at 09:51:43PM +0200, Heiko St?bner wrote:
>> > Am Montag 04 Juli 2011, 19:02:17 schrieb Grant Likely:
>> > > On Mon, Jul 04, 2011 at 06:59:11PM +0200, Heiko St?bner wrote:
>> > > > Am Montag 04 Juli 2011, 18:42:51 schrieb Grant Likely:
>> > > > >
>> > > > > Wow. ?A lot of #ifdefs here. ?It does not look multiplatform
> friendly
>> > > > > at all. ?Are the s3c2410_dma functions obsolete when DMADEV_PL330
> is
>> > > > > selected? ?If so, can they be removed entirely, or are they
> required
>> > > > > to support certain hardware?
>> > > >
>> > > > The spi_s3c64xx driver can also support the SPI controller of the
>> > > > S3C2416/S3C2443 line of SoCs.
>> > > > As I'm currently working on a S3C2416 based project, my small wish
> from
>> > > > the sidelines would be to not break this support with whatever
> solution
>> > > > you will decide on :-) .
>> > >
>> > > I will not merge a patch that either breaks a platform, or requires
>> > > a compile time either/or choice of device support (enabling support
>> > > for one device should not break support for another).
>> >
>> > The patch above seems to contain the support for both SoCs (i.e.
>> s3c2410_dma_*
>> > for S3C2416 etc), so it wouldn't break the support.
>> > But this form will definitly break future multiplatform kernels when the
> 2416
>> > and some variant using the DMADEV_PL330 are selected at the same time.
>>
>> Yes, that's the breakage I'm talking about.
>>
>> > The 2416/2443 seem to be the first Samsung-SoCs to have a SPI-controller
> of
>> > this type. Implementing the DMA engine stuff for these SoCs would
> obviously
>> > solve the ifdef-problem but I don't know if this is possible to do.
>>
>> Of course it's possible, it's just software. ?:-D
>>
>> If a config option is either/or then it needs to be really well
>> justified before I will accept it. ?Most either/or options I've seen
>> aren't for any strong technical reason other than it was easier to
>> code that way.
>
> Hi all,
>
> Yes I know your concerns on this.
>
> First of all, please see below which is block diagram of Samsung DMA usage
> and 1st step will be finished with other patches for S5PC100 and S5PV210
> soon. Basically we need more time maybe 2 or 3 days to test on boards.
>
> +---------------------------------------------------------------------+
> | Each drivers which uses DMA ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> +---------------------------------------------------------------------+
> | S3C DMA API (such as s3c2410_dma_xxxx) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
> +-------------------------------+-------------------------------------+
> | PL080 DMA driver ? ? ? ? ? ? ?| S3C PL330 DMA API driver ? ? ? ? ? ?|
> | for S3C24XX and S3C64XX ? ? ? | (arch/arm/plat-samsung/s3c-pl330.c) |
> | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +-------------------------------------+
> | (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver ? ? ? ? ? ? ?|
> | (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c) ? ? ? ? ? |
> +-------------------------------+-------------------------------------+
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ||
> ? ? ? ? ?(1st step. removing S3C DMA API for PL330)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ||
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \/
> +---------------------------------------------------------------------+
> | Each drivers which uses DMA ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> +-------------------------------+-------------------------------------+
> | S3C DMA API(s3c2410_dma_xxx) ?| DMA generic API for PL330 ? ? ? ? ? |
> +-------------------------------+-------------------------------------+
> | PL080 DMA driver ? ? ? ? ? ? ?| PL330 DMA API driver ? ? ? ? ? ? ? ?|
> | for S3C24XX and S3C64XX ? ? ? | (drivers/dma/pl330.c) ? ? ? ? ? ? ? |
> | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? +-------------------------------------+
> | (arch/arm/plat-s3c24xx/dma.c) | Common DMA core driver ? ? ? ? ? ? ?|
> | (arch/arm/mach-s3c64xx/dma.c) | (arch/arm/common/pl330.c) ? ? ? ? ? |
> +-------------------------------+-------------------------------------+
>
> As you saw, the S3C_DMA_API is still used for PL080 DMA for compatibilities
> with this patches in each driver, e.g., spi and audio. As a note, S3C24XX
> and S3C64XX include PL080 DMAC not PL330.
Not exactly.
S3C24XX  use 2-3 different versions of Samsung's DMA implementations.
S3C6400/10  use PL080
S5P and later series use PL330

>
> Of course, if we can remove every S3C_DMA_API, that can be the best solution
> but it needs more time. I'd like to go to our goal step by step.
>
Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled for s3c64xx
And new generic dma api drivers written for S3C24xx in drivers/dma/

-j

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-05 11:16                 ` Jassi Brar
@ 2011-07-05 11:27                   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05 11:27 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Kukjin Kim, linux-samsung-soc, Heiko Stübner, Boojin Kim,
	Vinod Koul, Mark Brown, Grant Likely, Dan Williams,
	Liam Girdwood, linux-arm-kernel

On Tue, Jul 05, 2011 at 04:46:47PM +0530, Jassi Brar wrote:
> Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled
> for s3c64xx And new generic dma api drivers written for S3C24xx in
> drivers/dma/

Another solution would be to write a DMA engine driver which massages
the Samsung DMA API into the DMA engine way of doing things.  You can
then convert all the Samsung drivers to using DMA engine, and then
sort out the Samsung DMA API as a separate issue.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05 11:27                   ` Russell King - ARM Linux
  0 siblings, 0 replies; 86+ messages in thread
From: Russell King - ARM Linux @ 2011-07-05 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 05, 2011 at 04:46:47PM +0530, Jassi Brar wrote:
> Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled
> for s3c64xx And new generic dma api drivers written for S3C24xx in
> drivers/dma/

Another solution would be to write a DMA engine driver which massages
the Samsung DMA API into the DMA engine way of doing things.  You can
then convert all the Samsung drivers to using DMA engine, and then
sort out the Samsung DMA API as a separate issue.

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

* Re: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-05 11:27                   ` Russell King - ARM Linux
@ 2011-07-05 11:45                     ` Jassi Brar
  -1 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-05 11:45 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Kukjin Kim, linux-samsung-soc, Heiko Stübner, Boojin Kim,
	Vinod Koul, Mark Brown, Grant Likely, Dan Williams,
	Liam Girdwood, linux-arm-kernel

On Tue, Jul 5, 2011 at 4:57 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Jul 05, 2011 at 04:46:47PM +0530, Jassi Brar wrote:
>> Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled
>> for s3c64xx And new generic dma api drivers written for S3C24xx in
>> drivers/dma/
>
> Another solution would be to write a DMA engine driver which massages
> the Samsung DMA API into the DMA engine way of doing things.  You can
> then convert all the Samsung drivers to using DMA engine, and then
> sort out the Samsung DMA API as a separate issue.
>
OK, but before that we need to see if the effort involved in writing
the api 'mapping'
 driver would be sufficiently lesser than that of writing a common
driver for 24xx, which
IIRC are variations of each other.

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-05 11:45                     ` Jassi Brar
  0 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-05 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 5, 2011 at 4:57 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Jul 05, 2011 at 04:46:47PM +0530, Jassi Brar wrote:
>> Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled
>> for s3c64xx And new generic dma api drivers written for S3C24xx in
>> drivers/dma/
>
> Another solution would be to write a DMA engine driver which massages
> the Samsung DMA API into the DMA engine way of doing things. ?You can
> then convert all the Samsung drivers to using DMA engine, and then
> sort out the Samsung DMA API as a separate issue.
>
OK, but before that we need to see if the effort involved in writing
the api 'mapping'
 driver would be sufficiently lesser than that of writing a common
driver for 24xx, which
IIRC are variations of each other.

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

* Re: [PATCH 7/7] ASoC: Samsung: Update DMA interface
  2011-07-05  7:19       ` Kukjin Kim
@ 2011-07-05 18:04         ` Grant Likely
  -1 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-05 18:04 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: 'Mark Brown',
	linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Jassi Brar',
	'Liam Girdwood', 'Boojin Kim'

On Tue, Jul 05, 2011 at 04:19:05PM +0900, Kukjin Kim wrote:
> Mark Brown wrote:
> > 
> Hi Mark,
> 
> Please refer to my other comment which includes block diagram, it can help
> our understanding about current Samsung DMA usage.
> 
> > Two questions here:
> > 
> > - It looks like a lot of this code can be shared between all the drivers
> >   using the dmaengine API.  Is there any reason not to factor it out?
> 
> Hmm...I'm not sure, but let us think/check your suggestions. Thanks :)
> 
> > - Should this not be adding a new driver for dmaengine based Samsung
> >   CPUs?  The ifdefs are very big.
> 
> OK, we will try.
> 
> Grant, I think, Mark's suggestion can support multiple platform...

Yes, it should.

g.

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

* [PATCH 7/7] ASoC: Samsung: Update DMA interface
@ 2011-07-05 18:04         ` Grant Likely
  0 siblings, 0 replies; 86+ messages in thread
From: Grant Likely @ 2011-07-05 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 05, 2011 at 04:19:05PM +0900, Kukjin Kim wrote:
> Mark Brown wrote:
> > 
> Hi Mark,
> 
> Please refer to my other comment which includes block diagram, it can help
> our understanding about current Samsung DMA usage.
> 
> > Two questions here:
> > 
> > - It looks like a lot of this code can be shared between all the drivers
> >   using the dmaengine API.  Is there any reason not to factor it out?
> 
> Hmm...I'm not sure, but let us think/check your suggestions. Thanks :)
> 
> > - Should this not be adding a new driver for dmaengine based Samsung
> >   CPUs?  The ifdefs are very big.
> 
> OK, we will try.
> 
> Grant, I think, Mark's suggestion can support multiple platform...

Yes, it should.

g.

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

* RE: [PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
  2011-07-05  7:36     ` Russell King - ARM Linux
@ 2011-07-08  7:57       ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-08  7:57 UTC (permalink / raw)
  To: 'Russell King - ARM Linux'
  Cc: linux-arm-kernel, linux-samsung-soc, 'Mark Brown',
	'Boojin Kim', 'Vinod Koul', 'Jassi Brar',
	'Grant Likely', 'Dan Williams',
	'Liam Girdwood'

Russell King - ARM Linux wrote:
> 
> On Mon, Jul 04, 2011 at 09:18:30PM +0900, Kukjin Kim wrote:
> > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> > index 25cf327..9b7f15a 100644
> > --- a/drivers/dma/Kconfig
> > +++ b/drivers/dma/Kconfig
> > @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
> >  config PL330_DMA
> >  	tristate "DMA API Driver for PL330"
> >  	select DMA_ENGINE
> > -	depends on PL330
> > +	select ARM_AMBA
> 
> This is the wrong way around.  If your SoC supports Primecells, then you
are
> supposed to select ARM_AMBA from the SoC to allow the Primecell drivers to
be
> enabled.  Primecell drivers should then depend on ARM_AMBA.

OK, will address comments.

Thanks.

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

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

* [PATCH 2/7] DMA: PL330: Update PL330 DMA API driver
@ 2011-07-08  7:57       ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-08  7:57 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> 
> On Mon, Jul 04, 2011 at 09:18:30PM +0900, Kukjin Kim wrote:
> > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> > index 25cf327..9b7f15a 100644
> > --- a/drivers/dma/Kconfig
> > +++ b/drivers/dma/Kconfig
> > @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
> >  config PL330_DMA
> >  	tristate "DMA API Driver for PL330"
> >  	select DMA_ENGINE
> > -	depends on PL330
> > +	select ARM_AMBA
> 
> This is the wrong way around.  If your SoC supports Primecells, then you
are
> supposed to select ARM_AMBA from the SoC to allow the Primecell drivers to
be
> enabled.  Primecell drivers should then depend on ARM_AMBA.

OK, will address comments.

Thanks.

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

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

* RE: [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
  2011-07-05 11:16                 ` Jassi Brar
@ 2011-07-08  9:26                   ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-08  9:26 UTC (permalink / raw)
  To: 'Jassi Brar'
  Cc: 'Grant Likely', 'Heiko Stübner',
	linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Liam Girdwood',
	'Mark Brown', 'Boojin Kim'

Jassi Brar wrote:
> 
> > As you saw, the S3C_DMA_API is still used for PL080 DMA for compatibilities
> > with this patches in each driver, e.g., spi and audio. As a note, S3C24XX
> > and S3C64XX include PL080 DMAC not PL330.
> Not exactly.
> S3C24XX  use 2-3 different versions of Samsung's DMA implementations.
> S3C6400/10  use PL080
> S5P and later series use PL330

Your information is correct, I was confused.

> > Of course, if we can remove every S3C_DMA_API, that can be the best solution
> > but it needs more time. I'd like to go to our goal step by step.
> >
> Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled for s3c64xx
> And new generic dma api drivers written for S3C24xx in drivers/dma/
> 
We're thinking about this :)

Thanks.

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

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

* [PATCH 6/7] spi/s3c64xx: Add support DMA engine API
@ 2011-07-08  9:26                   ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-08  9:26 UTC (permalink / raw)
  To: linux-arm-kernel

Jassi Brar wrote:
> 
> > As you saw, the S3C_DMA_API is still used for PL080 DMA for compatibilities
> > with this patches in each driver, e.g., spi and audio. As a note, S3C24XX
> > and S3C64XX include PL080 DMAC not PL330.
> Not exactly.
> S3C24XX  use 2-3 different versions of Samsung's DMA implementations.
> S3C6400/10  use PL080
> S5P and later series use PL330

Your information is correct, I was confused.

> > Of course, if we can remove every S3C_DMA_API, that can be the best solution
> > but it needs more time. I'd like to go to our goal step by step.
> >
> Ideally, like PL330 for S5Pxxxx, drivers/dma/pl080 should be enabled for s3c64xx
> And new generic dma api drivers written for S3C24xx in drivers/dma/
> 
We're thinking about this :)

Thanks.

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

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

* RE: [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
  2011-07-05  8:04     ` Russell King - ARM Linux
@ 2011-07-08 10:18       ` Kukjin Kim
  -1 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-08 10:18 UTC (permalink / raw)
  To: 'Russell King - ARM Linux'
  Cc: linux-arm-kernel, linux-samsung-soc, 'Mark Brown',
	'Boojin Kim', 'Vinod Koul', 'Jassi Brar',
	'Grant Likely', 'Dan Williams',
	'Liam Girdwood'

Russell King - ARM Linux wrote:
> 
Russell, thanks for your time.
OK, will address comments from you on this series.

Will re-submit the beginning of next week.

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

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

* [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC
@ 2011-07-08 10:18       ` Kukjin Kim
  0 siblings, 0 replies; 86+ messages in thread
From: Kukjin Kim @ 2011-07-08 10:18 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> 
Russell, thanks for your time.
OK, will address comments from you on this series.

Will re-submit the beginning of next week.

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

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

* Re: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-05  6:33     ` Chanho Park
@ 2011-07-12  8:32       ` Jassi Brar
  -1 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-12  8:32 UTC (permalink / raw)
  To: Chanho Park
  Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, Vinod Koul,
	Dan Williams, Grant Likely, Liam Girdwood, Mark Brown,
	Boojin Kim

On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
> Kukjin Kim <kgene.kim <at> samsung.com> writes:
>
> (snip)
>
>> +             if (slave_config->direction == DMA_TO_DEVICE) {
>> +                     if (slave_config->dst_addr)
>> +                             peri->fifo_addr = slave_config->dst_addr;
>> +                     if (slave_config->dst_addr_width) {
>> +                             i = 0;
>> +                             while (slave_config->dst_addr_width != (1 <<
> i))
>> +                                     i++;
>> +                             peri->burst_sz = i;
>> +                     }
>> +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
>> +                     if (slave_config->src_addr)
>> +                             peri->fifo_addr = slave_config->src_addr;
>> +                     if (slave_config->src_addr_width) {
>> +                             i = 0;
>> +                             while (slave_config->src_addr_width != (1 <<
> i))
>> +                                     i++;
>> +                             peri->burst_sz = i;
>
> Re-send including cc and mailing lists
> --
> pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> If some bad D/D doesn't use powers of 2 width,
> dmaengine is going to infinite loop.
> You'd better check it instead of running loop.
>
It might be even better to start with max possible width and
keep decreasing 'i' in the loop.

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-12  8:32       ` Jassi Brar
  0 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-12  8:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
> Kukjin Kim <kgene.kim <at> samsung.com> writes:
>
> (snip)
>
>> + ? ? ? ? ? ? if (slave_config->direction == DMA_TO_DEVICE) {
>> + ? ? ? ? ? ? ? ? ? ? if (slave_config->dst_addr)
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->fifo_addr = slave_config->dst_addr;
>> + ? ? ? ? ? ? ? ? ? ? if (slave_config->dst_addr_width) {
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? i = 0;
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? while (slave_config->dst_addr_width != (1 <<
> i))
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i++;
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->burst_sz = i;
>> + ? ? ? ? ? ? ? ? ? ? }
>> + ? ? ? ? ? ? } else if (slave_config->direction == DMA_FROM_DEVICE) {
>> + ? ? ? ? ? ? ? ? ? ? if (slave_config->src_addr)
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->fifo_addr = slave_config->src_addr;
>> + ? ? ? ? ? ? ? ? ? ? if (slave_config->src_addr_width) {
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? i = 0;
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? while (slave_config->src_addr_width != (1 <<
> i))
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i++;
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->burst_sz = i;
>
> Re-send including cc and mailing lists
> --
> pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> If some bad D/D doesn't use powers of 2 width,
> dmaengine is going to infinite loop.
> You'd better check it instead of running loop.
>
It might be even better to start with max possible width and
keep decreasing 'i' in the loop.

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

* RE: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-12  8:32       ` Jassi Brar
@ 2011-07-14  0:57         ` boojin
  -1 siblings, 0 replies; 86+ messages in thread
From: boojin @ 2011-07-14  0:57 UTC (permalink / raw)
  To: 'Jassi Brar', 'Chanho Park'
  Cc: 'Kukjin Kim',
	linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Grant Likely',
	'Liam Girdwood', 'Mark Brown'

Jassi Brar wrote:

> On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
> > Kukjin Kim <kgene.kim <at> samsung.com> writes:
> >
> > (snip)
> >
> >> +             if (slave_config->direction == DMA_TO_DEVICE) {
> >> +                     if (slave_config->dst_addr)
> >> +                             peri->fifo_addr = slave_config->dst_addr;
> >> +                     if (slave_config->dst_addr_width) {
> >> +                             i = 0;
> >> +                             while (slave_config->dst_addr_width != (1 <<
> > i))
> >> +                                     i++;
> >> +                             peri->burst_sz = i;
> >> +                     }
> >> +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
> >> +                     if (slave_config->src_addr)
> >> +                             peri->fifo_addr = slave_config->src_addr;
> >> +                     if (slave_config->src_addr_width) {
> >> +                             i = 0;
> >> +                             while (slave_config->src_addr_width != (1 <<
> > i))
> >> +                                     i++;
> >> +                             peri->burst_sz = i;
> >
> > Re-send including cc and mailing lists
> > --
> > pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> > If some bad D/D doesn't use powers of 2 width,
> > dmaengine is going to infinite loop.
> > You'd better check it instead of running loop.
> >
> It might be even better to start with max possible width and
> keep decreasing 'i' in the loop.
I will addressed your comment on next release.

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-14  0:57         ` boojin
  0 siblings, 0 replies; 86+ messages in thread
From: boojin @ 2011-07-14  0:57 UTC (permalink / raw)
  To: linux-arm-kernel

Jassi Brar wrote:

> On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
> > Kukjin Kim <kgene.kim <at> samsung.com> writes:
> >
> > (snip)
> >
> >> +             if (slave_config->direction == DMA_TO_DEVICE) {
> >> +                     if (slave_config->dst_addr)
> >> +                             peri->fifo_addr = slave_config->dst_addr;
> >> +                     if (slave_config->dst_addr_width) {
> >> +                             i = 0;
> >> +                             while (slave_config->dst_addr_width != (1 <<
> > i))
> >> +                                     i++;
> >> +                             peri->burst_sz = i;
> >> +                     }
> >> +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
> >> +                     if (slave_config->src_addr)
> >> +                             peri->fifo_addr = slave_config->src_addr;
> >> +                     if (slave_config->src_addr_width) {
> >> +                             i = 0;
> >> +                             while (slave_config->src_addr_width != (1 <<
> > i))
> >> +                                     i++;
> >> +                             peri->burst_sz = i;
> >
> > Re-send including cc and mailing lists
> > --
> > pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> > If some bad D/D doesn't use powers of 2 width,
> > dmaengine is going to infinite loop.
> > You'd better check it instead of running loop.
> >
> It might be even better to start with max possible width and
> keep decreasing 'i' in the loop.
I will addressed your comment on next release.

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

* Re: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-14  0:57         ` boojin
@ 2011-07-14  3:53           ` Jassi Brar
  -1 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-14  3:53 UTC (permalink / raw)
  To: boojin
  Cc: Chanho Park, Kukjin Kim, linux-arm-kernel, linux-samsung-soc,
	Vinod Koul, Dan Williams, Grant Likely, Liam Girdwood,
	Mark Brown

On Thu, Jul 14, 2011 at 6:27 AM, boojin <boojin.kim@samsung.com> wrote:
> Jassi Brar wrote:
>
>> On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
>> > Kukjin Kim <kgene.kim <at> samsung.com> writes:
>> >
>> > (snip)
>> >
>> >> +             if (slave_config->direction == DMA_TO_DEVICE) {
>> >> +                     if (slave_config->dst_addr)
>> >> +                             peri->fifo_addr = slave_config->dst_addr;
>> >> +                     if (slave_config->dst_addr_width) {
>> >> +                             i = 0;
>> >> +                             while (slave_config->dst_addr_width != (1 <<
>> > i))
>> >> +                                     i++;
>> >> +                             peri->burst_sz = i;
>> >> +                     }
>> >> +             } else if (slave_config->direction == DMA_FROM_DEVICE) {
>> >> +                     if (slave_config->src_addr)
>> >> +                             peri->fifo_addr = slave_config->src_addr;
>> >> +                     if (slave_config->src_addr_width) {
>> >> +                             i = 0;
>> >> +                             while (slave_config->src_addr_width != (1 <<
>> > i))
>> >> +                                     i++;
>> >> +                             peri->burst_sz = i;
>> >
>> > Re-send including cc and mailing lists
>> > --
>> > pl330 dmac only supports 1/2/4/8/16 bytes burst size.
>> > If some bad D/D doesn't use powers of 2 width,
>> > dmaengine is going to infinite loop.
>> > You'd better check it instead of running loop.
>> >
>> It might be even better to start with max possible width and
>> keep decreasing 'i' in the loop.
> I will addressed your comment on next release.

Actually, best would be to simply do
    peri->burst_sz =  __ffs(slave_config->src_addr_width);

And sorry I haven't yet reviewed the patches because I have been
very busy lately. Will be more active in a few days.

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-14  3:53           ` Jassi Brar
  0 siblings, 0 replies; 86+ messages in thread
From: Jassi Brar @ 2011-07-14  3:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 14, 2011 at 6:27 AM, boojin <boojin.kim@samsung.com> wrote:
> Jassi Brar wrote:
>
>> On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
>> > Kukjin Kim <kgene.kim <at> samsung.com> writes:
>> >
>> > (snip)
>> >
>> >> + ? ? ? ? ? ? if (slave_config->direction == DMA_TO_DEVICE) {
>> >> + ? ? ? ? ? ? ? ? ? ? if (slave_config->dst_addr)
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->fifo_addr = slave_config->dst_addr;
>> >> + ? ? ? ? ? ? ? ? ? ? if (slave_config->dst_addr_width) {
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? i = 0;
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? while (slave_config->dst_addr_width != (1 <<
>> > i))
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i++;
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->burst_sz = i;
>> >> + ? ? ? ? ? ? ? ? ? ? }
>> >> + ? ? ? ? ? ? } else if (slave_config->direction == DMA_FROM_DEVICE) {
>> >> + ? ? ? ? ? ? ? ? ? ? if (slave_config->src_addr)
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->fifo_addr = slave_config->src_addr;
>> >> + ? ? ? ? ? ? ? ? ? ? if (slave_config->src_addr_width) {
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? i = 0;
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? while (slave_config->src_addr_width != (1 <<
>> > i))
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i++;
>> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? peri->burst_sz = i;
>> >
>> > Re-send including cc and mailing lists
>> > --
>> > pl330 dmac only supports 1/2/4/8/16 bytes burst size.
>> > If some bad D/D doesn't use powers of 2 width,
>> > dmaengine is going to infinite loop.
>> > You'd better check it instead of running loop.
>> >
>> It might be even better to start with max possible width and
>> keep decreasing 'i' in the loop.
> I will addressed your comment on next release.

Actually, best would be to simply do
    peri->burst_sz =  __ffs(slave_config->src_addr_width);

And sorry I haven't yet reviewed the patches because I have been
very busy lately. Will be more active in a few days.

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

* RE: [PATCH 3/7] DMA: PL330: Add DMA capabilities
  2011-07-14  3:53           ` Jassi Brar
@ 2011-07-14  9:04             ` boojin
  -1 siblings, 0 replies; 86+ messages in thread
From: boojin @ 2011-07-14  9:04 UTC (permalink / raw)
  To: 'Jassi Brar'
  Cc: 'Chanho Park', 'Kukjin Kim',
	linux-arm-kernel, linux-samsung-soc, 'Vinod Koul',
	'Dan Williams', 'Grant Likely',
	'Liam Girdwood', 'Mark Brown'

Jassi Brar Wrote:
> On Thu, Jul 14, 2011 at 6:27 AM, boojin <boojin.kim@samsung.com> wrote:
> > Jassi Brar wrote:
> >
> >> On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
> >> > Kukjin Kim <kgene.kim <at> samsung.com> writes:
> >> >
> >> > (snip)
> >> >
> >> >> +             if (slave_config->direction == DMA_TO_DEVICE) {
> >> >> +                     if (slave_config->dst_addr)
> >> >> +                             peri->fifo_addr = slave_config->dst_addr;
> >> >> +                     if (slave_config->dst_addr_width) {
> >> >> +                             i = 0;
> >> >> +                             while (slave_config->dst_addr_width != (1
> <<
> >> > i))
> >> >> +                                     i++;
> >> >> +                             peri->burst_sz = i;
> >> >> +                     }
> >> >> +             } else if (slave_config->direction == DMA_FROM_DEVICE)
> {
> >> >> +                     if (slave_config->src_addr)
> >> >> +                             peri->fifo_addr = slave_config->src_addr;
> >> >> +                     if (slave_config->src_addr_width) {
> >> >> +                             i = 0;
> >> >> +                             while (slave_config->src_addr_width != (1
> <<
> >> > i))
> >> >> +                                     i++;
> >> >> +                             peri->burst_sz = i;
> >> >
> >> > Re-send including cc and mailing lists
> >> > --
> >> > pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> >> > If some bad D/D doesn't use powers of 2 width,
> >> > dmaengine is going to infinite loop.
> >> > You'd better check it instead of running loop.
> >> >
> >> It might be even better to start with max possible width and
> >> keep decreasing 'i' in the loop.
> > I will addressed your comment on next release.
> 
> Actually, best would be to simply do
>     peri->burst_sz =  __ffs(slave_config->src_addr_width);
> 
> And sorry I haven't yet reviewed the patches because I have been
> very busy lately. Will be more active in a few days.

Thanks for good information. Please give me your feedback.
I will release next version after gathering and reflecting all comments.

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

* [PATCH 3/7] DMA: PL330: Add DMA capabilities
@ 2011-07-14  9:04             ` boojin
  0 siblings, 0 replies; 86+ messages in thread
From: boojin @ 2011-07-14  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

Jassi Brar Wrote:
> On Thu, Jul 14, 2011 at 6:27 AM, boojin <boojin.kim@samsung.com> wrote:
> > Jassi Brar wrote:
> >
> >> On Tue, Jul 5, 2011 at 12:03 PM, Chanho Park <parkch98@gmail.com> wrote:
> >> > Kukjin Kim <kgene.kim <at> samsung.com> writes:
> >> >
> >> > (snip)
> >> >
> >> >> +             if (slave_config->direction == DMA_TO_DEVICE) {
> >> >> +                     if (slave_config->dst_addr)
> >> >> +                             peri->fifo_addr = slave_config->dst_addr;
> >> >> +                     if (slave_config->dst_addr_width) {
> >> >> +                             i = 0;
> >> >> +                             while (slave_config->dst_addr_width != (1
> <<
> >> > i))
> >> >> +                                     i++;
> >> >> +                             peri->burst_sz = i;
> >> >> +                     }
> >> >> +             } else if (slave_config->direction == DMA_FROM_DEVICE)
> {
> >> >> +                     if (slave_config->src_addr)
> >> >> +                             peri->fifo_addr = slave_config->src_addr;
> >> >> +                     if (slave_config->src_addr_width) {
> >> >> +                             i = 0;
> >> >> +                             while (slave_config->src_addr_width != (1
> <<
> >> > i))
> >> >> +                                     i++;
> >> >> +                             peri->burst_sz = i;
> >> >
> >> > Re-send including cc and mailing lists
> >> > --
> >> > pl330 dmac only supports 1/2/4/8/16 bytes burst size.
> >> > If some bad D/D doesn't use powers of 2 width,
> >> > dmaengine is going to infinite loop.
> >> > You'd better check it instead of running loop.
> >> >
> >> It might be even better to start with max possible width and
> >> keep decreasing 'i' in the loop.
> > I will addressed your comment on next release.
> 
> Actually, best would be to simply do
>     peri->burst_sz =  __ffs(slave_config->src_addr_width);
> 
> And sorry I haven't yet reviewed the patches because I have been
> very busy lately. Will be more active in a few days.

Thanks for good information. Please give me your feedback.
I will release next version after gathering and reflecting all comments.

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

end of thread, other threads:[~2011-07-14  9:04 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-04 12:18 [PATCH 0/7] ARM: S5P: Use generic DMA APIs Kukjin Kim
2011-07-04 12:18 ` Kukjin Kim
2011-07-04 12:18 ` [PATCH 1/7] DMA: PL330: Add support runtime PM for PL330 DMAC Kukjin Kim
2011-07-04 12:18   ` Kukjin Kim
2011-07-05  6:11   ` Alim Akhtar
2011-07-05  6:11     ` Alim Akhtar
2011-07-05  7:26     ` Kukjin Kim
2011-07-05  7:26       ` Kukjin Kim
2011-07-05  8:04   ` Russell King - ARM Linux
2011-07-05  8:04     ` Russell King - ARM Linux
2011-07-08 10:18     ` Kukjin Kim
2011-07-08 10:18       ` Kukjin Kim
2011-07-04 12:18 ` [PATCH 2/7] DMA: PL330: Update PL330 DMA API driver Kukjin Kim
2011-07-04 12:18   ` Kukjin Kim
2011-07-05  7:36   ` Russell King - ARM Linux
2011-07-05  7:36     ` Russell King - ARM Linux
2011-07-08  7:57     ` Kukjin Kim
2011-07-08  7:57       ` Kukjin Kim
2011-07-04 12:18 ` [PATCH 3/7] DMA: PL330: Add DMA capabilities Kukjin Kim
2011-07-04 12:18   ` Kukjin Kim
2011-07-05  4:50   ` Chanho Park
2011-07-05  6:33   ` Chanho Park
2011-07-05  6:33     ` Chanho Park
2011-07-05  7:10     ` Kukjin Kim
2011-07-05  7:10       ` Kukjin Kim
2011-07-05  8:08       ` Chanho Park
2011-07-05  8:08         ` Chanho Park
2011-07-12  8:32     ` Jassi Brar
2011-07-12  8:32       ` Jassi Brar
2011-07-14  0:57       ` boojin
2011-07-14  0:57         ` boojin
2011-07-14  3:53         ` Jassi Brar
2011-07-14  3:53           ` Jassi Brar
2011-07-14  9:04           ` boojin
2011-07-14  9:04             ` boojin
2011-07-04 12:18 ` [PATCH 4/7] ARM: SAMSUNG: Update to use PL330-DMA driver Kukjin Kim
2011-07-04 12:18   ` Kukjin Kim
2011-07-04 12:18 ` [PATCH 5/7] ARM: EXYNOS4: Use generic DMA PL330 driver Kukjin Kim
2011-07-04 12:18   ` Kukjin Kim
2011-07-05  2:36   ` Chanho Park
2011-07-05  6:07   ` Alim Akhtar
2011-07-05  6:07     ` Alim Akhtar
2011-07-05  8:30     ` Sangwook Lee
2011-07-05  8:30       ` Sangwook Lee
2011-07-04 12:18 ` [PATCH 6/7] spi/s3c64xx: Add support DMA engine API Kukjin Kim
2011-07-04 12:18   ` Kukjin Kim
2011-07-04 16:42   ` Grant Likely
2011-07-04 16:42     ` Grant Likely
2011-07-04 16:56     ` Mark Brown
2011-07-04 16:56       ` Mark Brown
2011-07-04 16:59     ` Heiko Stübner
2011-07-04 16:59       ` Heiko Stübner
2011-07-04 17:02       ` Grant Likely
2011-07-04 17:02         ` Grant Likely
2011-07-04 19:51         ` Heiko Stübner
2011-07-04 19:51           ` Heiko Stübner
2011-07-04 23:27           ` Grant Likely
2011-07-04 23:27             ` Grant Likely
2011-07-05  7:05             ` Kukjin Kim
2011-07-05  7:05               ` Kukjin Kim
2011-07-05  7:53               ` Russell King - ARM Linux
2011-07-05  7:53                 ` Russell King - ARM Linux
2011-07-05 10:51               ` Heiko Stübner
2011-07-05 10:51                 ` Heiko Stübner
2011-07-05 11:16               ` Jassi Brar
2011-07-05 11:16                 ` Jassi Brar
2011-07-05 11:27                 ` Russell King - ARM Linux
2011-07-05 11:27                   ` Russell King - ARM Linux
2011-07-05 11:45                   ` Jassi Brar
2011-07-05 11:45                     ` Jassi Brar
2011-07-08  9:26                 ` Kukjin Kim
2011-07-08  9:26                   ` Kukjin Kim
2011-07-05  7:48   ` Russell King - ARM Linux
2011-07-05  7:48     ` Russell King - ARM Linux
2011-07-05  8:39   ` Chanho Park
2011-07-05  8:39     ` Chanho Park
2011-07-04 12:18 ` [PATCH 7/7] ASoC: Samsung: Update DMA interface Kukjin Kim
2011-07-04 12:18   ` Kukjin Kim
2011-07-04 17:03   ` Mark Brown
2011-07-04 17:03     ` Mark Brown
2011-07-05  7:19     ` Kukjin Kim
2011-07-05  7:19       ` Kukjin Kim
2011-07-05 18:04       ` Grant Likely
2011-07-05 18:04         ` Grant Likely
2011-07-05  7:45     ` Seungwhan Youn
2011-07-05  7:45       ` Seungwhan Youn

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.