Skip to contentSkip to conversation

To use DMA generic APIs for Samsung DMA

PATCH Superseded Kukjin Kim 4 participants 17 messages Jul 16, 2011 – Jul 18, 2011

Subsystems (9)

v3 of 8 Superseded Latest is v8 →

lore
Share & tools
lore

Kukjin Kim

author
#0 lore raw

v3 cover To use DMA generic APIs for Samsung DMA

Following is diagram of this changes

+---------------------------------------------------------------------+
| Each drivers which uses DMA                                         |
+---------------------------------------------------------------------+
| S3C DMA API (such as s3c2410_dma_xxxx)                              |
+-------------------------------+-------------------------------------+
| DMA driver for S3C24XX        | S3C PL330 DMA API driver            |
| PL080 DMA driver for 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)           |
+-------------------------------+-------------------------------------+
                               ||
               (removing S3C DMA API for PL330)
                               ||
                               \/
+---------------------------------------------------------------------+
| Each drivers which uses DMA                                         |
+-------------------------------+-------------------------------------+
| S3C DMA API(s3c2410_dma_xxx)  | DMA generic API for PL330           |
+-------------------------------+-------------------------------------+
| DMA driver for S3C24XX        | PL330 DMA API driver                |
| PL080 DMA driver for 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)           |
+-------------------------------+-------------------------------------+

[PATCH V3 01/13] DMA: PL330: Add support runtime PM for PL330 DMAC [PATCH V3 02/13] DMA: PL330: Update PL330 DMA API driver
[PATCH V3 03/13] DMA: PL330: Add DMA capabilities
[PATCH V3 04/13] ARM: SAMSUNG: Update to use PL330-DMA driver
[PATCH V3 05/13] ARM: SAMSUNG: Add common DMA operations
[PATCH V3 06/13] ARM: EXYNOS4: Use generic DMA PL330 driver
[PATCH V3 07/13] ARM: S5PV210: Use generic DMA PL330 driver
[PATCH V3 08/13] ARM: S5PC100: Use generic DMA PL330 driver
[PATCH V3 09/13] ARM: S5P64X0: Use generic DMA PL330 driver
[PATCH V3 10/13] ARM: SAMSUNG: Remove S3C-PL330-DMA driver
[PATCH V3 11/13] spi/s3c64xx: Add support DMA engine API
[PATCH V3 12/13] ASoC: Samsung: Update DMA interface
[PATCH V3 13/13] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction

author
#1 lore raw

PATCH v3 1/13 DMA: PL330: Add support runtime PM for PL330 DMAC

From: Boojin Kim <[email protected]>

---
 drivers/dma/pl330.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 75 insertions(+), 3 deletions(-)
drivers/dma/pl330.c +75 -3
index 6abe1ec..39e9ffd 100644
@@ -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
 
@@ -83,6 +84,8 @@ struct dma_pl330_dmac {
 
 	/* Peripheral channels connected to this DMAC */
 	struct dma_pl330_chan peripherals[0]; /* keep at end */
+
+	struct clk *clk;
 };
 
 struct dma_pl330_desc {
@@ -688,7 +691,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	pi->mcbufsz = pdat->mcbuf_sz;
 
 	res = &adev->res;
-	request_mem_region(res->start, resource_size(res), "dma-pl330");
+	request_mem_region(res->start,
+		resource_size(res), dev_name(&adev->dev));
 
 	pi->base = ioremap(res->start, resource_size(res));
 	if (!pi->base) {
@@ -696,6 +700,30 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		goto probe_err1;
 	}
 
+	pdmac->clk = clk_get(&adev->dev, "dma");
+	if (IS_ERR(pdmac->clk)) {
+		dev_err(&adev->dev, "Cannot get operation clock.\n");
+		ret = -EINVAL;
+		goto probe_err1;
+	}
+
+	amba_set_drvdata(adev, pdmac);
+
+#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_enable(pdmac->clk);
+#endif
+
 	irq = adev->irq[0];
 	ret = request_irq(irq, pl330_irq_handler, 0,
 			dev_name(&adev->dev), pi);
@@ -763,8 +791,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		goto probe_err4;
 	}
 
-	amba_set_drvdata(adev, pdmac);
-
 	dev_info(&adev->dev,
 		"Loaded driver for PL330 DMAC-%d\n", adev->periphid);
 	dev_info(&adev->dev,
@@ -825,6 +851,13 @@ static int __devexit pl330_remove(struct amba_device *adev)
 	res = &adev->res;
 	release_mem_region(res->start, resource_size(res));
 
+#ifdef CONFIG_PM_RUNTIME
+	pm_runtime_put(&adev->dev);
+	pm_runtime_disable(&adev->dev);
+#else
+	clk_disable(pdmac->clk);
+#endif
+
 	kfree(pdmac);
 
 	return 0;
@@ -838,10 +871,49 @@ static struct amba_id pl330_ids[] = {
 	{ 0, 0 },
 };
 
+#ifdef CONFIG_PM_RUNTIME
+static int pl330_runtime_suspend(struct device *dev)
+{
+	struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
+
+	if (!pdmac) {
+		dev_err(dev, "failed to get dmac\n");
+		return -ENODEV;
+	}
+
+	clk_disable(pdmac->clk);
+
+	return 0;
+}
+
+static int pl330_runtime_resume(struct device *dev)
+{
+	struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
+
+	if (!pdmac) {
+		dev_err(dev, "failed to get dmac\n");
+		return -ENODEV;
+	}
+
+	clk_enable(pdmac->clk);
+
+	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,
Signature · 1 line
1.7.1
author
#2 lore raw

PATCH v3 2/13 DMA: PL330: Update PL330 DMA API driver

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

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.

---
 drivers/dma/Kconfig        |    3 ++-
 drivers/dma/pl330.c        |   31 ++++++++++++++++---------------
 include/linux/amba/pl330.h |    2 +-
 3 files changed, 19 insertions(+), 17 deletions(-)
drivers/dma/Kconfig +2 -1
index 25cf327..569cb14 100644
@@ -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
+	depends on ARM_AMBA
+	select PL330
 	help
 	  Select if your platform has one or more PL330 DMACs.
 	  You need to provide platform specific settings via
drivers/dma/pl330.c +16 -15
index 39e9ffd..9bdda7b 100644
@@ -455,7 +455,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);
 
@@ -577,7 +577,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))
@@ -594,7 +594,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	}
 
 	addr = peri->fifo_addr;
-	burst_size = peri->burst_sz;
 
 	first = NULL;
 
@@ -642,7 +641,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;
 	}
 
@@ -749,17 +748,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);
include/linux/amba/pl330.h +1 -1
index cbee7de..17b0ada 100644
@@ -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 */
Signature · 1 line
1.7.1
author
#3 lore raw

PATCH v3 3/13 DMA: PL330: Add DMA capabilities

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

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

---
 drivers/dma/pl330.c |  175 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 160 insertions(+), 15 deletions(-)
drivers/dma/pl330.c +160 -15
index 9bdda7b..980a145 100644
@@ -69,6 +69,9 @@ struct dma_pl330_chan {
 	 * NULL if the channel is available to be acquired.
 	 */
 	void *pl330_chid;
+
+	/* taks for cyclic capability */
+	struct tasklet_struct *cyclic_task;
 };
 
 struct dma_pl330_dmac {
@@ -105,6 +108,7 @@ struct dma_pl330_desc {
 
 	/* The channel which currently holds this desc */
 	struct dma_pl330_chan *pchan;
+	bool cyclic;
 };
 
 static inline struct dma_pl330_chan *
@@ -184,6 +188,41 @@ static inline void fill_queue(struct dma_pl330_chan *pch)
 	}
 }
 
+static void pl330_tasklet_cyclic(unsigned long data)
+{
+	struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data;
+	struct dma_pl330_desc *desc, *_dt;
+	unsigned long flags;
+	LIST_HEAD(list);
+
+	spin_lock_irqsave(&pch->lock, flags);
+
+	/* Pick up ripe tomatoes */
+	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
+		if ((desc->status == DONE) && desc->cyclic) {
+			dma_async_tx_callback callback;
+
+			list_move_tail(&desc->node, &pch->work_list);
+			pch->completed = desc->txd.cookie;
+
+			desc->status = PREP;
+
+			/* Try to submit a req imm.
+			next to the last completed cookie */
+			fill_queue(pch);
+
+			/* Make sure the PL330 Channel thread is active */
+			pl330_chan_ctrl(pch->pl330_chid, PL330_OP_START);
+
+			callback = desc->txd.callback;
+			if (callback)
+				callback(desc->txd.callback_param);
+
+		}
+
+	spin_unlock_irqrestore(&pch->lock, flags);
+}
+
 static void pl330_tasklet(unsigned long data)
 {
 	struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data;
@@ -227,7 +266,10 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
 
 	spin_unlock_irqrestore(&pch->lock, flags);
 
-	tasklet_schedule(&pch->task);
+	if (pch->cyclic_task)
+		tasklet_schedule(pch->cyclic_task);
+	else
+		tasklet_schedule(&pch->task);
 }
 
 static int pl330_alloc_chan_resources(struct dma_chan *chan)
@@ -256,27 +298,68 @@ 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;
+	LIST_HEAD(list);
 
-	/* Only supports DMA_TERMINATE_ALL */
-	if (cmd != DMA_TERMINATE_ALL)
-		return -ENXIO;
+	switch (cmd) {
+	case DMA_TERMINATE_ALL:
+		spin_lock_irqsave(&pch->lock, flags);
 
-	spin_lock_irqsave(&pch->lock, flags);
+		/* FLUSH the PL330 Channel thread */
+		pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
+
+		/* 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);
+		}
+
+		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)
+				peri->burst_sz = __ffs(slave_config->dst_addr_width);
+		} 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)
+				peri->burst_sz = __ffs(slave_config->src_addr_width);
+		}
+		break;
+	default:
+		dev_err(pch->dmac->pif.dev, "Not supported command.\n");
+		return -ENXIO;
+	}
 
-	/* FLUSH the PL330 Channel thread */
-	pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
+	return 0;
+}
 
-	/* Mark all desc done */
-	list_for_each_entry(desc, &pch->work_list, node)
-		desc->status = DONE;
+static void pl330_cyclic_free(struct dma_pl330_chan *pch)
+{
+	struct dma_pl330_dmac *pdmac = pch->dmac;
+	struct dma_pl330_desc *desc, *_dt;
+	LIST_HEAD(list);
 
-	spin_unlock_irqrestore(&pch->lock, flags);
+	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
+		if (desc->cyclic)
+			list_move_tail(&desc->node, &list);
 
-	pl330_tasklet((unsigned long) pch);
+	list_splice_tail_init(&list, &pdmac->desc_pool);
 
-	return 0;
+	tasklet_kill(pch->cyclic_task);
+	pch->cyclic_task = NULL;
 }
 
 static void pl330_free_chan_resources(struct dma_chan *chan)
@@ -291,6 +374,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
 	pl330_release_channel(pch->pl330_chid);
 	pch->pl330_chid = NULL;
 
+	if (pch->cyclic_task)
+		pl330_cyclic_free(pch);
+
 	spin_unlock_irqrestore(&pch->lock, flags);
 }
 
@@ -522,6 +608,63 @@ 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)
+		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;
+
+	if (!pch->cyclic_task) {
+		pch->cyclic_task =
+			kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
+		tasklet_init(pch->cyclic_task,
+			pl330_tasklet_cyclic, (unsigned int)pch);
+	}
+
+	desc->cyclic = true;
+
+	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)
@@ -691,7 +834,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	res = &adev->res;
 	request_mem_region(res->start,
-		resource_size(res), dev_name(&adev->dev));
+		resource_size(res), "dma-pl330");
 
 	pi->base = ioremap(res->start, resource_size(res));
 	if (!pi->base) {
@@ -756,6 +899,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");
@@ -781,6 +925,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;
Signature · 1 line
1.7.1
author
#4 lore raw

PATCH v3 4/13 ARM: SAMSUNG: Update to use PL330-DMA driver

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

This patch adds to support PL330-DMA driver on DMADEVICE for S5P SoCs.

---
 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                      |    8 +++++++
 .../include/plat/{s3c-dma-pl330.h => dma-pl330.h}  |   21 +++++++++++++------
 .../plat-samsung/include/plat/s3c-pl330-pdata.h    |    2 +-
 7 files changed, 28 insertions(+), 13 deletions(-)
 rename arch/arm/plat-samsung/include/plat/{s3c-dma-pl330.h => dma-pl330.h} (84%)
arch/arm/mach-exynos4/include/mach/dma.h +2 -2
index 81209eb..201842a 100644
@@ -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 */
arch/arm/mach-s5p64x0/include/mach/dma.h +1 -1
index 81209eb..1beae2c 100644
@@ -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 */
arch/arm/mach-s5pc100/include/mach/dma.h +1 -1
index 81209eb..1beae2c 100644
@@ -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 */
arch/arm/mach-s5pv210/include/mach/dma.h +1 -1
index 81209eb..1beae2c 100644
@@ -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 */
arch/arm/plat-samsung/Kconfig +8 -0
index 4d79519..cb170a6 100644
@@ -300,6 +300,14 @@ config S3C_PL330_DMA
 	help
 	  S3C DMA API Driver for PL330 DMAC.
 
+config DMADEV_PL330
+	bool
+	select DMADEVICES
+	select PL330_DMA
+	select ARM_AMBA
+	help
+	  Use DMA device engine for PL330 DMAC.
+
 comment "Power management"
 
 config SAMSUNG_PM_DEBUG
arch/arm/plat-samsung/include/plat/dma-pl330.h renamed from arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h +14 -7
similarity index 84%
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..c402719 100644
@@ -8,19 +8,18 @@
  * (at your option) any later version.
  */
 
-#ifndef	__S3C_DMA_PL330_H_
-#define	__S3C_DMA_PL330_H_
-
-#define S3C2410_DMAF_AUTOSTART		(1 << 0)
-#define S3C2410_DMAF_CIRCULAR		(1 << 1)
+#ifndef __DMA_PL330_H_
+#define __DMA_PL330_H_ __FILE__
 
+#define S3C2410_DMAF_AUTOSTART	(1 << 0)
+#define S3C2410_DMAF_CIRCULAR	(1 << 1)
 /*
  * PL330 can assign any channel to communicate with
  * any of the peripherals attched to the DMAC.
  * For the sake of consistency across client drivers,
  * We keep the channel names unchanged and only add
  * missing peripherals are added.
- * Order is not important since S3C PL330 API driver
+ * Order is not important since DMA PL330 API driver
  * use these just as IDs.
  */
 enum dma_ch {
@@ -84,6 +83,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,
 };
@@ -95,4 +102,4 @@ static inline bool s3c_dma_has_circular(void)
 
 #include <plat/dma.h>
 
-#endif	/* __S3C_DMA_PL330_H_ */
+#endif	/* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +1 -1
index bf5e2a9..64fdf66 100644
@@ -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,
Signature · 1 line
1.7.1
author
#5 lore raw

PATCH v3 5/13 ARM: SAMSUNG: Add common DMA operations

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

This patch adds common DMA operations which are used for Samsung DMA drivers. Currently there are two types of DMA driver for Samsung SoCs. The one is S3C-DMA for S3C SoCs and the other is PL330-DMA for S5P SoCs. This patch provides funcion pointers for common DMA operations to DMA client driver like SPI and Audio. It makes DMA client drivers support multi-platform.
In addition, this common DMA operations implement the shared actions that are needed for DMA client driver. For example shared actions are filter() function for dma_request_channel() and parameter passing for device_prep_slave_sg().

---
 arch/arm/mach-s3c2410/include/mach/dma.h       |    8 ++-
 arch/arm/mach-s3c64xx/include/mach/dma.h       |    4 +
 arch/arm/plat-samsung/Makefile                 |    6 +-
 arch/arm/plat-samsung/dma-ops.c                |  130 ++++++++++++++++++++++++
 arch/arm/plat-samsung/include/plat/dma-ops.h   |   72 +++++++++++++
 arch/arm/plat-samsung/include/plat/dma-pl330.h |    7 ++
 arch/arm/plat-samsung/include/plat/dma.h       |    1 +
 arch/arm/plat-samsung/s3c-dma-ops.c            |  129 +++++++++++++++++++++++
 8 files changed, 354 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/plat-samsung/dma-ops.c
 create mode 100644 arch/arm/plat-samsung/include/plat/dma-ops.h
 create mode 100644 arch/arm/plat-samsung/s3c-dma-ops.c
arch/arm/mach-s3c2410/include/mach/dma.h +7 -1
index b2b2a5b..e61a91f 100644
@@ -13,7 +13,6 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H __FILE__
 
-#include <plat/dma.h>
 #include <linux/sysdev.h>
 
 #define MAX_DMA_TRANSFER_SIZE   0x100000 /* Data Unit is half word  */
@@ -51,6 +50,13 @@ enum dma_ch {
 	DMACH_MAX,		/* the end entry */
 };
 
+static inline bool samsung_dma_is_dmadev(void)
+{
+	return false;
+}
+
+#include <plat/dma.h>
+
 #define DMACH_LOW_LEVEL	(1<<28)	/* use this to specifiy hardware ch no */
 
 /* we have 4 dma channels */
arch/arm/mach-s3c64xx/include/mach/dma.h +4 -0
index 0a5d926..49c3a53 100644
@@ -63,6 +63,10 @@ static __inline__ bool s3c_dma_has_circular(void)
 	return true;
 }
 
+static inline bool samsung_dma_is_dmadev(void)
+{
+	return false;
+}
 #define S3C2410_DMAF_CIRCULAR		(1 << 0)
 
 #include <plat/dma.h>
arch/arm/plat-samsung/Makefile +4 -2
index 53eb15b..9ecf2aa 100644
@@ -62,9 +62,11 @@ obj-$(CONFIG_SAMSUNG_DEV_PWM)	+= dev-pwm.o
 
 # DMA support
 
-obj-$(CONFIG_S3C_DMA)		+= dma.o
+obj-$(CONFIG_S3C_DMA)		+= dma.o s3c-dma-ops.o
 
-obj-$(CONFIG_S3C_PL330_DMA)	+= s3c-pl330.o
+obj-$(CONFIG_DMADEV_PL330)	+= dma-ops.o
+
+obj-$(CONFIG_S3C_PL330_DMA)	+= s3c-pl330.o s3c-dma-ops.o
 
 # PM support
 
arch/arm/plat-samsung/dma-ops.c new file +130 -0

130 lines not on this page · raw message

arch/arm/plat-samsung/include/plat/dma-ops.h new file +72 -0

72 lines not on this page · raw message

arch/arm/plat-samsung/include/plat/dma-pl330.h +4 -0
index c402719..91933e0 100644
@@ -100,6 +100,10 @@ static inline bool s3c_dma_has_circular(void)
 	return true;
 }
 
+static inline bool samsung_dma_is_dmadev(void)
+{
+	return true;
+}
 #include <plat/dma.h>
 
 #endif	/* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/dma.h +1 -0
index 2e8f8c6..e87c6be 100644
@@ -125,3 +125,4 @@ extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);
 extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn);
 
 
+#include <plat/dma-ops.h>
arch/arm/plat-samsung/s3c-dma-ops.c new file +130 -0

130 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#6 lore raw

PATCH v3 6/13 ARM: EXYNOS4: Use generic DMA PL330 driver

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

This patch makes Samsung EXYNOS4 to use DMA PL330 driver on DMADEVICE. The EXYNOS4 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.

---
 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(-)
arch/arm/mach-exynos4/Kconfig +1 -1
index 1435fc3..5cc9b7a 100644
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4
 
 config CPU_EXYNOS4210
 	bool
-	select S3C_PL330_DMA
+	select DMADEV_PL330
 	help
 	  Enable EXYNOS4210 CPU support
 
arch/arm/mach-exynos4/clock.c +9 -7
index 871f9d5..1b2e78c 100644
@@ -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();
 }
arch/arm/mach-exynos4/dma.c +211 -112

362 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#7 lore raw

PATCH v3 7/13 ARM: S5PV210: Use generic DMA PL330 driver

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

This patch makes Samsung S5PV210 to use DMA PL330 driver on DMADEVICE. The S5PV210 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.

---
 arch/arm/mach-s5pv210/Kconfig |    2 +-
 arch/arm/mach-s5pv210/clock.c |   16 +-
 arch/arm/mach-s5pv210/dma.c   |  346 +++++++++++++++++++++++++++--------------
 3 files changed, 241 insertions(+), 123 deletions(-)
arch/arm/mach-s5pv210/Kconfig +1 -1
index 37b5a97..fb11e38 100644
@@ -11,7 +11,7 @@ if ARCH_S5PV210
 
 config CPU_S5PV210
 	bool
-	select S3C_PL330_DMA
+	select DMADEV_PL330
 	select S5P_EXT_INT
 	select S5P_HRT
 	select S5PV210_PM if PM
arch/arm/mach-s5pv210/clock.c +8 -8
index 2d59949..dbe7285 100644
@@ -221,6 +221,11 @@ static struct clk clk_pcmcdclk2 = {
 	.id		= -1,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name		= "apb_pclk",
+	.id		= -1,
+};
+
 static struct clk *clkset_vpllsrc_list[] = {
 	[0] = &clk_fin_vpll,
 	[1] = &clk_sclk_hdmi27m,
@@ -311,18 +316,12 @@ static struct clk_ops clk_fout_apll_ops = {
 
 static struct clk init_clocks_off[] = {
 	{
-		.name		= "pdma",
-		.id		= 0,
+		.name		= "dma",
+		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1 << 3),
 	}, {
-		.name		= "pdma",
-		.id		= 1,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 4),
-	}, {
 		.name		= "rot",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
@@ -1239,5 +1238,6 @@ void __init s5pv210_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();
 }
arch/arm/mach-s5pv210/dma.c +232 -114

387 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#8 lore raw

PATCH v3 8/13 ARM: S5PC100: Use generic DMA PL330 driver

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

This patch makes Samsung S5PC100 to use DMA PL330 driver on DMADEVICE. The S5PC100 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.

---
 arch/arm/mach-s5pc100/Kconfig |    2 +-
 arch/arm/mach-s5pc100/clock.c |   23 +--
 arch/arm/mach-s5pc100/dma.c   |  357 ++++++++++++++++++++++++++++-------------
 3 files changed, 253 insertions(+), 129 deletions(-)
arch/arm/mach-s5pc100/Kconfig +1 -1
index 608722f..379fadc 100644
@@ -10,7 +10,7 @@ if ARCH_S5PC100
 config CPU_S5PC100
 	bool
 	select S5P_EXT_INT
-	select S3C_PL330_DMA
+	select DMADEV_PL330
 	help
 	  Enable S5PC100 CPU support
 
arch/arm/mach-s5pc100/clock.c +9 -14
index 0305e9b..891acfe 100644
@@ -34,6 +34,11 @@ static struct clk s5p_clk_otgphy = {
 	.id		= -1,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name		= "apb_pclk",
+	.id		= -1,
+};
+
 static struct clk *clk_src_mout_href_list[] = {
 	[0] = &s5p_clk_27m,
 	[1] = &clk_fin_hpll,
@@ -416,12 +421,6 @@ static struct clk init_clocks_off[] = {
 		.enable		= s5pc100_d0_0_ctrl,
 		.ctrlbit	= (1 << 4),
 	}, {
-		.name		= "mdma",
-		.id		= -1,
-		.parent		= &clk_div_d0_bus.clk,
-		.enable		= s5pc100_d0_0_ctrl,
-		.ctrlbit	= (1 << 3),
-	}, {
 		.name		= "cfcon",
 		.id		= -1,
 		.parent		= &clk_div_d0_bus.clk,
@@ -488,14 +487,8 @@ static struct clk init_clocks_off[] = {
 		.enable		= s5pc100_d1_0_ctrl,
 		.ctrlbit	= (1 << 2),
 	}, {
-		.name		= "pdma",
-		.id		= 1,
-		.parent		= &clk_div_d1_bus.clk,
-		.enable		= s5pc100_d1_0_ctrl,
-		.ctrlbit	= (1 << 1),
-	}, {
-		.name		= "pdma",
-		.id		= 0,
+		.name		= "dma",
+		.id		= -1,
 		.parent		= &clk_div_d1_bus.clk,
 		.enable		= s5pc100_d1_0_ctrl,
 		.ctrlbit	= (1 << 0),
@@ -1394,5 +1387,7 @@ void __init s5pc100_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();
 }
arch/arm/mach-s5pc100/dma.c +243 -114

397 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#9 lore raw

PATCH v3 9/13 ARM: S5P64X0: Use generic DMA PL330 driver

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

This patch makes Samsung S5P64X0 to use DMA PL330 driver on DMADEVICE. The S5P64X0 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.

---
 arch/arm/mach-s5p64x0/Kconfig         |    4 +-
 arch/arm/mach-s5p64x0/clock-s5p6440.c |    9 +-
 arch/arm/mach-s5p64x0/clock-s5p6450.c |    9 +-
 arch/arm/mach-s5p64x0/dma.c           |  317 +++++++++++++++++++++++----------
 4 files changed, 242 insertions(+), 97 deletions(-)
arch/arm/mach-s5p64x0/Kconfig +2 -2
index 017af4c..7108e7e 100644
@@ -9,14 +9,14 @@ if ARCH_S5P64X0
 
 config CPU_S5P6440
 	bool
-	select S3C_PL330_DMA
+	select DMADEV_PL330
 	select S5P_HRT
 	help
 	  Enable S5P6440 CPU support
 
 config CPU_S5P6450
 	bool
-	select S3C_PL330_DMA
+	select DMADEV_PL330
 	select S5P_HRT
 	help
 	  Enable S5P6450 CPU support
arch/arm/mach-s5p64x0/clock-s5p6440.c +8 -1
index 9f12c2e..5f7ad9e 100644
@@ -153,7 +153,7 @@ static struct clk init_clocks_off[] = {
 		.enable		= s5p64x0_hclk0_ctrl,
 		.ctrlbit	= (1 << 8),
 	}, {
-		.name		= "pdma",
+		.name		= "dma",
 		.id		= -1,
 		.parent		= &clk_hclk_low.clk,
 		.enable		= s5p64x0_hclk0_ctrl,
@@ -533,6 +533,11 @@ static struct clksrc_clk *sysclks[] = {
 	&clk_pclk_low,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name		= "apb_pclk",
+	.id		= -1,
+};
+
 void __init_or_cpufreq s5p6440_setup_clocks(void)
 {
 	struct clk *xtal_clk;
@@ -615,5 +620,7 @@ void __init s5p6440_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();
 }
arch/arm/mach-s5p64x0/clock-s5p6450.c +8 -1
index 4eec457..62d4707 100644
@@ -189,7 +189,7 @@ static struct clk init_clocks_off[] = {
 		.enable		= s5p64x0_hclk0_ctrl,
 		.ctrlbit	= (1 << 3),
 	}, {
-		.name		= "pdma",
+		.name		= "dma",
 		.id		= -1,
 		.parent		= &clk_hclk_low.clk,
 		.enable		= s5p64x0_hclk0_ctrl,
@@ -583,6 +583,11 @@ static struct clksrc_clk *sysclks[] = {
 	&clk_sclk_audio0,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name		= "apb_pclk",
+	.id		= -1,
+};
+
 void __init_or_cpufreq s5p6450_setup_clocks(void)
 {
 	struct clk *xtal_clk;
@@ -662,5 +667,7 @@ void __init s5p6450_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();
 }
arch/arm/mach-s5p64x0/dma.c +224 -93

354 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#10 lore raw

PATCH v3 10/13 ARM: SAMSUNG: Remove S3C-PL330-DMA driver

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

Since DMA generic APIs can be used for Samsung DMA now so that the s3c-pl330 which includes Samsung specific DMA APIs can be removed.

---
 arch/arm/plat-samsung/Kconfig                      |    6 -
 arch/arm/plat-samsung/Makefile                     |    2 -
 arch/arm/plat-samsung/include/plat/dma-pl330.h     |    9 +-
 .../plat-samsung/include/plat/s3c-pl330-pdata.h    |   32 -
 arch/arm/plat-samsung/s3c-pl330.c                  | 1244 --------------------
 5 files changed, 6 insertions(+), 1287 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
 delete mode 100644 arch/arm/plat-samsung/s3c-pl330.c
arch/arm/plat-samsung/Kconfig +0 -6
index cb170a6..db789d7 100644
@@ -294,12 +294,6 @@ config S3C_DMA
 	help
 	  Internal configuration for S3C DMA core
 
-config S3C_PL330_DMA
-	bool
-	select PL330
-	help
-	  S3C DMA API Driver for PL330 DMAC.
-
 config DMADEV_PL330
 	bool
 	select DMADEVICES
arch/arm/plat-samsung/Makefile +0 -2
index 9ecf2aa..ea98621 100644
@@ -66,8 +66,6 @@ obj-$(CONFIG_S3C_DMA)		+= dma.o s3c-dma-ops.o
 
 obj-$(CONFIG_DMADEV_PL330)	+= dma-ops.o
 
-obj-$(CONFIG_S3C_PL330_DMA)	+= s3c-pl330.o s3c-dma-ops.o
-
 # PM support
 
 obj-$(CONFIG_PM)		+= pm.o
arch/arm/plat-samsung/include/plat/dma-pl330.h +6 -3
index 91933e0..e7565c0 100644
@@ -14,8 +14,6 @@
 #ifndef __DMA_PL330_H_
 #define __DMA_PL330_H_ __FILE__
 
-#define S3C2410_DMAF_AUTOSTART	(1 << 0)
-#define S3C2410_DMAF_CIRCULAR	(1 << 1)
 /*
  * PL330 can assign any channel to communicate with
  * any of the peripherals attched to the DMAC.
@@ -98,6 +96,10 @@ enum dma_ch {
 	DMACH_MAX,
 };
 
+struct s3c2410_dma_client {
+	char	*name;
+};
+
 static inline bool s3c_dma_has_circular(void)
 {
 	return true;
@@ -107,6 +109,7 @@ static inline bool samsung_dma_is_dmadev(void)
 {
 	return true;
 }
-#include <plat/dma.h>
+
+#include <plat/dma-ops.h>
 
 #endif	/* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h deleted +0 -32
deleted file mode 100644
index 64fdf66..0000000
@@ -1,32 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *	Jaswinder Singh <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __S3C_PL330_PDATA_H
-#define __S3C_PL330_PDATA_H
-
-#include <plat/dma-pl330.h>
-
-/*
- * Every PL330 DMAC has max 32 peripheral interfaces,
- * of which some may be not be really used in your
- * DMAC's configuration.
- * Populate this array of 32 peri i/fs with relevant
- * channel IDs for used peri i/f and DMACH_MAX for
- * those unused.
- *
- * The platforms just need to provide this info
- * to the S3C DMA API driver for PL330.
- */
-struct s3c_pl330_platdata {
-	enum dma_ch peri[32];
-};
-
-#endif /* __S3C_PL330_PDATA_H */
arch/arm/plat-samsung/s3c-pl330.c deleted +0 -1244

1,244 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#11 lore raw

PATCH v3 11/13 spi/s3c64xx: Add support DMA engine API

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

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.

---
 drivers/spi/spi_s3c64xx.c |  141 ++++++++++++++++++++++-----------------------
 1 files changed, 69 insertions(+), 72 deletions(-)
drivers/spi/spi_s3c64xx.c +69 -72
index 8945e20..a4cf76a 100644
@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data {
 	unsigned                        state;
 	unsigned                        cur_mode, cur_bpw;
 	unsigned                        cur_speed;
+	unsigned			rx_ch;
+	unsigned			tx_ch;
+	struct samsung_dma_ops		*ops;
 };
 
 static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
@@ -227,6 +230,38 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
 	writel(val, regs + S3C64XX_SPI_CH_CFG);
 }
 
+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);
+}
+
 static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 				struct spi_device *spi,
 				struct spi_transfer *xfer, int dma_mode)
@@ -234,6 +269,7 @@ 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;
+	struct samsung_dma_prep_info info;
 
 	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
 	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
@@ -259,10 +295,14 @@ 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;
-			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);
+			info.cap = DMA_SLAVE;
+			info.direction = DMA_TO_DEVICE;
+			info.buf = xfer->tx_dma;
+			info.len = xfer->len;
+			info.fp = s3c64xx_spi_dma_txcb;
+			info.fp_param = sdd;
+			sdd->ops->prepare(sdd->tx_ch, &info);
+			sdd->ops->trigger(sdd->tx_ch);
 		} else {
 			switch (sdd->cur_bpw) {
 			case 32:
@@ -294,10 +334,14 @@ 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);
-			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);
+			info.cap = DMA_SLAVE;
+			info.direction = DMA_FROM_DEVICE;
+			info.buf = xfer->rx_dma;
+			info.len = xfer->len;
+			info.fp = s3c64xx_spi_dma_rxcb;
+			info.fp_param = sdd;
+			sdd->ops->prepare(sdd->rx_ch, &info);
+			sdd->ops->trigger(sdd->rx_ch);
 		}
 	}
 
@@ -483,46 +527,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,
@@ -697,12 +701,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
 			if (use_dma) {
 				if (xfer->tx_buf != NULL
 						&& (sdd->state & TXBUSY))
-					s3c2410_dma_ctrl(sdd->tx_dmach,
-							S3C2410_DMAOP_FLUSH);
+					sdd->ops->stop(sdd->tx_ch);
 				if (xfer->rx_buf != NULL
 						&& (sdd->state & RXBUSY))
-					s3c2410_dma_ctrl(sdd->rx_dmach,
-							S3C2410_DMAOP_FLUSH);
+					sdd->ops->stop(sdd->rx_ch);
 			}
 
 			goto out;
@@ -742,24 +744,19 @@ out:
 
 static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
 {
-	if (s3c2410_dma_request(sdd->rx_dmach,
-					&s3c64xx_spi_dma_client, NULL) < 0) {
-		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
-		return 0;
-	}
-	s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb);
-	s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW,
-					sdd->sfr_start + S3C64XX_SPI_RX_DATA);
-
-	if (s3c2410_dma_request(sdd->tx_dmach,
-					&s3c64xx_spi_dma_client, NULL) < 0) {
-		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
-		s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
-		return 0;
-	}
-	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);
+
+	struct samsung_dma_info info;
+	sdd->ops = samsung_dma_get_ops();
+
+	info.cap = DMA_SLAVE;
+	info.client = &s3c64xx_spi_dma_client;
+	info.direction = DMA_FROM_DEVICE;
+	info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
+	info.width = sdd->cur_bpw / 8;
+	sdd->rx_ch = sdd->ops->request(sdd->rx_dmach, &info);
+	info.direction = DMA_TO_DEVICE;
+	info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+	sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info);
 
 	return 1;
 }
@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
 	spin_unlock_irqrestore(&sdd->lock, flags);
 
 	/* Free DMA channels */
-	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
-	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+	sdd->ops->release(sdd->rx_ch, &s3c64xx_spi_dma_client);
+	sdd->ops->release(sdd->tx_ch, &s3c64xx_spi_dma_client);
 }
 
 static int s3c64xx_spi_transfer(struct spi_device *spi,
Signature · 1 line
1.7.1
#12 lore raw

PATCH v3 11/13 spi/s3c64xx: Add support DMA engine API

Quoted 10 lines · Kukjin Kim

From: Boojin Kim <[email protected]>

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.

Quoted 222 lines
---
 drivers/spi/spi_s3c64xx.c |  141 ++++++++++++++++++++++-----------------------
 1 files changed, 69 insertions(+), 72 deletions(-)
drivers/spi/spi_s3c64xx.c +69 -72
index 8945e20..a4cf76a 100644
@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data {
 	unsigned                        state;
 	unsigned                        cur_mode, cur_bpw;
 	unsigned                        cur_speed;
+	unsigned			rx_ch;
+	unsigned			tx_ch;
+	struct samsung_dma_ops		*ops;
 };
 
 static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
@@ -227,6 +230,38 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
 	writel(val, regs + S3C64XX_SPI_CH_CFG);
 }
 
+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);
+}
+
 static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 				struct spi_device *spi,
 				struct spi_transfer *xfer, int dma_mode)
@@ -234,6 +269,7 @@ 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;
+	struct samsung_dma_prep_info info;
 
 	modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
 	modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
@@ -259,10 +295,14 @@ 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;
-			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);
+			info.cap = DMA_SLAVE;
+			info.direction = DMA_TO_DEVICE;
+			info.buf = xfer->tx_dma;
+			info.len = xfer->len;
+			info.fp = s3c64xx_spi_dma_txcb;
+			info.fp_param = sdd;
+			sdd->ops->prepare(sdd->tx_ch, &info);
+			sdd->ops->trigger(sdd->tx_ch);
 		} else {
 			switch (sdd->cur_bpw) {
 			case 32:
@@ -294,10 +334,14 @@ 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);
-			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);
+			info.cap = DMA_SLAVE;
+			info.direction = DMA_FROM_DEVICE;
+			info.buf = xfer->rx_dma;
+			info.len = xfer->len;
+			info.fp = s3c64xx_spi_dma_rxcb;
+			info.fp_param = sdd;
+			sdd->ops->prepare(sdd->rx_ch, &info);
+			sdd->ops->trigger(sdd->rx_ch);
 		}
 	}
 
@@ -483,46 +527,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,
@@ -697,12 +701,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
 			if (use_dma) {
 				if (xfer->tx_buf != NULL
 						&& (sdd->state & TXBUSY))
-					s3c2410_dma_ctrl(sdd->tx_dmach,
-							S3C2410_DMAOP_FLUSH);
+					sdd->ops->stop(sdd->tx_ch);
 				if (xfer->rx_buf != NULL
 						&& (sdd->state & RXBUSY))
-					s3c2410_dma_ctrl(sdd->rx_dmach,
-							S3C2410_DMAOP_FLUSH);
+					sdd->ops->stop(sdd->rx_ch);
 			}
 
 			goto out;
@@ -742,24 +744,19 @@ out:
 
 static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
 {
-	if (s3c2410_dma_request(sdd->rx_dmach,
-					&s3c64xx_spi_dma_client, NULL) < 0) {
-		dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
-		return 0;
-	}
-	s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb);
-	s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW,
-					sdd->sfr_start + S3C64XX_SPI_RX_DATA);
-
-	if (s3c2410_dma_request(sdd->tx_dmach,
-					&s3c64xx_spi_dma_client, NULL) < 0) {
-		dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
-		s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
-		return 0;
-	}
-	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);
+
+	struct samsung_dma_info info;
+	sdd->ops = samsung_dma_get_ops();
+
+	info.cap = DMA_SLAVE;
+	info.client = &s3c64xx_spi_dma_client;
+	info.direction = DMA_FROM_DEVICE;
+	info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
+	info.width = sdd->cur_bpw / 8;
+	sdd->rx_ch = sdd->ops->request(sdd->rx_dmach, &info);
+	info.direction = DMA_TO_DEVICE;
+	info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+	sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info);
 
 	return 1;
 }
@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
 	spin_unlock_irqrestore(&sdd->lock, flags);
 
 	/* Free DMA channels */
-	s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
-	s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+	sdd->ops->release(sdd->rx_ch, &s3c64xx_spi_dma_client);
+	sdd->ops->release(sdd->tx_ch, &s3c64xx_spi_dma_client);
 }
 
 static int s3c64xx_spi_transfer(struct spi_device *spi,
Signature · 7 lines
1.7.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#13 lore raw

PATCH v3 12/13 ASoC: Samsung: Update DMA interface

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

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.

Cc Jassi Brar <[email protected]>
Cc Liam Girdwood <[email protected]>
Cc Mark Brown <[email protected]>
---
 arch/arm/mach-s3c2410/include/mach/dma.h       |   10 +-
 arch/arm/mach-s3c64xx/include/mach/dma.h       |    2 +-
 arch/arm/plat-samsung/include/plat/dma-pl330.h |    2 +-
 sound/soc/samsung/ac97.c                       |   10 ++-
 sound/soc/samsung/dma.c                        |  144 ++++++++++--------------
 sound/soc/samsung/dma.h                        |    4 +-
 6 files changed, 78 insertions(+), 94 deletions(-)
arch/arm/mach-s3c2410/include/mach/dma.h +5 -5
index e61a91f..4e485ba 100644
@@ -50,6 +50,11 @@ enum dma_ch {
 	DMACH_MAX,		/* the end entry */
 };
 
+static inline bool samsung_dma_has_circular(void)
+{
+	return false;
+}
+
 static inline bool samsung_dma_is_dmadev(void)
 {
 	return false;
@@ -202,9 +207,4 @@ struct s3c2410_dma_chan {
 
 typedef unsigned long dma_device_t;
 
-static inline bool s3c_dma_has_circular(void)
-{
-	return false;
-}
-
 #endif /* __ASM_ARCH_DMA_H */
arch/arm/mach-s3c64xx/include/mach/dma.h +1 -1
index 49c3a53..74fdf25 100644
@@ -58,7 +58,7 @@ enum dma_ch {
 	DMACH_MAX		/* the end */
 };
 
-static __inline__ bool s3c_dma_has_circular(void)
+static inline bool samsung_dma_has_circular(void)
 {
 	return true;
 }
arch/arm/plat-samsung/include/plat/dma-pl330.h +1 -1
index e7565c0..4b8b81d 100644
@@ -100,7 +100,7 @@ struct s3c2410_dma_client {
 	char	*name;
 };
 
-static inline bool s3c_dma_has_circular(void)
+static inline bool samsung_dma_has_circular(void)
 {
 	return true;
 }
sound/soc/samsung/ac97.c +8 -2
index f97110e..b4f9b00 100644
@@ -271,7 +271,10 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 
 	writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
-	s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
+	if (!dma_data->ops)
+		dma_data->ops = samsung_dma_get_ops();
+
+	dma_data->ops->started(dma_data->channel);
 
 	return 0;
 }
@@ -317,7 +320,10 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
 
 	writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
-	s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
+	if (!dma_data->ops)
+		dma_data->ops = samsung_dma_get_ops();
+
+	dma_data->ops->started(dma_data->channel);
 
 	return 0;
 }
sound/soc/samsung/dma.c +60 -84

233 lines not on this page · raw message

sound/soc/samsung/dma.h +3 -1
index c506592..7d1ead7 100644
@@ -6,7 +6,7 @@
  *  Free Software Foundation;  either version 2 of the  License, or (at your
  *  option) any later version.
  *
- *  ALSA PCM interface for the Samsung S3C24xx CPU
+ *  ALSA PCM interface for the Samsung SoC
  */
 
 #ifndef _S3C_AUDIO_H
@@ -17,6 +17,8 @@ struct s3c_dma_params {
 	int channel;				/* Channel ID */
 	dma_addr_t dma_addr;
 	int dma_size;			/* Size of the DMA transfer */
+	unsigned ch;
+	struct samsung_dma_ops *ops;
 };
 
 #endif
Signature · 1 line
1.7.1
#14 lore raw

PATCH v3 12/13 ASoC: Samsung: Update DMA interface

Quoted 6 lines · Kukjin Kim

From: Boojin Kim <[email protected]>

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.

author
#15 lore raw

PATCH v3 13/13 ARM: SAMSUNG: Remove Samsung specific enum type for dma direction

In reply to Kukjin Kim

From: Boojin Kim <[email protected]>

This patch removes the samsung specific enum type 's3c2410_dmasrc' and uses 'dma_data_direction' instead.

---
 arch/arm/mach-s3c2410/include/mach/dma.h         |    2 +-
 arch/arm/mach-s3c2412/dma.c                      |    4 ++--
 arch/arm/mach-s3c64xx/dma.c                      |   10 +++++-----
 arch/arm/mach-s3c64xx/include/mach/dma.h         |    2 +-
 arch/arm/plat-s3c24xx/dma.c                      |   10 +++++-----
 arch/arm/plat-samsung/include/plat/dma-s3c24xx.h |    2 +-
 arch/arm/plat-samsung/include/plat/dma.h         |    9 +++------
 arch/arm/plat-samsung/s3c-dma-ops.c              |    5 +----
 drivers/mmc/host/s3cmci.c                        |    6 +++---
 9 files changed, 22 insertions(+), 28 deletions(-)
arch/arm/mach-s3c2410/include/mach/dma.h +1 -1
index 4e485ba..ae8e482 100644
@@ -174,7 +174,7 @@ struct s3c2410_dma_chan {
 	struct s3c2410_dma_client *client;
 
 	/* channel configuration */
-	enum s3c2410_dmasrc	 source;
+	enum dma_data_direction	 source;
 	enum dma_ch		 req_ch;
 	unsigned long		 dev_addr;
 	unsigned long		 load_timeout;
arch/arm/mach-s3c2412/dma.c +2 -2
index 7abecfc..1c42972 100644
@@ -148,11 +148,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
 
 static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
 				  struct s3c24xx_dma_map *map,
-				  enum s3c2410_dmasrc dir)
+				  enum dma_data_direction dir)
 {
 	unsigned long chsel;
 
-	if (dir == S3C2410_DMASRC_HW)
+	if (dir == DMA_FROM_DEVICE)
 		chsel = map->channels_rx[0];
 	else
 		chsel = map->channels[0];
arch/arm/mach-s3c64xx/dma.c +5 -5
index b197171..d96ed4c 100644
@@ -147,14 +147,14 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
 	u32 control0, control1;
 
 	switch (chan->source) {
-	case S3C2410_DMASRC_HW:
+	case DMA_FROM_DEVICE:
 		src = chan->dev_addr;
 		dst = data;
 		control0 = PL080_CONTROL_SRC_AHB2;
 		control0 |= PL080_CONTROL_DST_INCR;
 		break;
 
-	case S3C2410_DMASRC_MEM:
+	case DMA_TO_DEVICE:
 		src = data;
 		dst = chan->dev_addr;
 		control0 = PL080_CONTROL_DST_AHB2;
@@ -416,7 +416,7 @@ EXPORT_SYMBOL(s3c2410_dma_enqueue);
 
 
 int s3c2410_dma_devconfig(unsigned int channel,
-			  enum s3c2410_dmasrc source,
+			  enum dma_data_direction source,
 			  unsigned long devaddr)
 {
 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
@@ -437,11 +437,11 @@ int s3c2410_dma_devconfig(unsigned int channel,
 	pr_debug("%s: peripheral %d\n", __func__, peripheral);
 
 	switch (source) {
-	case S3C2410_DMASRC_HW:
+	case DMA_FROM_DEVICE:
 		config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
 		config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
 		break;
-	case S3C2410_DMASRC_MEM:
+	case DMA_TO_DEVICE:
 		config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
 		config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
 		break;
arch/arm/mach-s3c64xx/include/mach/dma.h +1 -1
index 74fdf25..fe1a98c 100644
@@ -99,7 +99,7 @@ struct s3c2410_dma_chan {
 	unsigned char		 peripheral;
 
 	unsigned int		 flags;
-	enum s3c2410_dmasrc	 source;
+	enum dma_data_direction	 source;
 
 
 	dma_addr_t		dev_addr;
arch/arm/plat-s3c24xx/dma.c +5 -5
index a79a8cc..036ff81 100644
@@ -1094,14 +1094,14 @@ EXPORT_SYMBOL(s3c2410_dma_config);
  *
  * configure the dma source/destination hardware type and address
  *
- * source:    S3C2410_DMASRC_HW: source is hardware
- *            S3C2410_DMASRC_MEM: source is memory
+ * source:    DMA_FROM_DEVICE: source is hardware
+ *            DMA_TO_DEVICE: source is memory
  *
  * devaddr:   physical address of the source
 */
 
 int s3c2410_dma_devconfig(unsigned int channel,
-			  enum s3c2410_dmasrc source,
+			  enum dma_data_direction source,
 			  unsigned long devaddr)
 {
 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
@@ -1131,7 +1131,7 @@ int s3c2410_dma_devconfig(unsigned int channel,
 	 hwcfg |= S3C2410_DISRCC_INC;
 
 	switch (source) {
-	case S3C2410_DMASRC_HW:
+	case DMA_FROME_DEVICE:
 		/* source is hardware */
 		pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
 			 __func__, devaddr, hwcfg);
@@ -1142,7 +1142,7 @@ int s3c2410_dma_devconfig(unsigned int channel,
 		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
 		break;
 
-	case S3C2410_DMASRC_MEM:
+	case DMA_TO_DEVICE:
 		/* source is memory */
 		pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
 			 __func__, devaddr, hwcfg);
arch/arm/plat-samsung/include/plat/dma-s3c24xx.h +1 -1
index 336d5ac..1982829 100644
@@ -47,7 +47,7 @@ struct s3c24xx_dma_selection {
 
 	void	(*direction)(struct s3c2410_dma_chan *chan,
 			     struct s3c24xx_dma_map *map,
-			     enum s3c2410_dmasrc dir);
+			     enum dma_data_direction dir);
 };
 
 extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
arch/arm/plat-samsung/include/plat/dma.h +3 -6
index e87c6be..b395398 100644
@@ -10,17 +10,14 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/dma-mapping.h>
+
 enum s3c2410_dma_buffresult {
 	S3C2410_RES_OK,
 	S3C2410_RES_ERR,
 	S3C2410_RES_ABORT
 };
 
-enum s3c2410_dmasrc {
-	S3C2410_DMASRC_HW,		/* source is memory */
-	S3C2410_DMASRC_MEM		/* source is hardware */
-};
-
 /* enum s3c2410_chan_op
  *
  * operation codes passed to the DMA code by the user, and also used
@@ -111,7 +108,7 @@ extern int s3c2410_dma_config(unsigned int channel, int xferunit);
 */
 
 extern int s3c2410_dma_devconfig(unsigned int channel,
-		enum s3c2410_dmasrc source, unsigned long devaddr);
+		enum dma_data_direction source, unsigned long devaddr);
 
 /* s3c2410_dma_getposition
  *
arch/arm/plat-samsung/s3c-dma-ops.c +1 -4
index b534663..76fe202 100644
@@ -47,10 +47,7 @@ static unsigned s3c_dma_request(enum dma_ch dma_ch, struct samsung_dma_info *inf
 	data->ch = dma_ch;
 	list_add_tail(&data->node, &dma_list);
 
-	if (info->direction == DMA_FROM_DEVICE)
-		s3c2410_dma_devconfig(dma_ch, S3C2410_DMASRC_HW, info->fifo);
-	else
-		s3c2410_dma_devconfig(dma_ch, S3C2410_DMASRC_MEM, info->fifo);
+	s3c2410_dma_devconfig(dma_ch, info->direction, info->fifo);
 
 	if (info->cap == DMA_CYCLIC)
 		s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
drivers/mmc/host/s3cmci.c +3 -3
index a04f87d..03cfdab 100644
@@ -913,9 +913,9 @@ request_done:
 }
 
 static void s3cmci_dma_setup(struct s3cmci_host *host,
-			     enum s3c2410_dmasrc source)
+			     enum dma_data_direction source)
 {
-	static enum s3c2410_dmasrc last_source = -1;
+	static enum dma_data_direction last_source = -1;
 	static int setup_ok;
 
 	if (last_source == source)
@@ -1087,7 +1087,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
 
 	BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
 
-	s3cmci_dma_setup(host, rw ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW);
+	s3cmci_dma_setup(host, rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 	s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
 
 	dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
Signature · 1 line
1.7.1
#16 lore raw

v3 cover To use DMA generic APIs for Samsung DMA

In reply to Kukjin Kim
Quoted 20 lines · Kukjin Kim

Following is diagram of this changes

+---------------------------------------------------------------------+
| Each drivers which uses DMA ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
+---------------------------------------------------------------------+
| S3C DMA API (such as s3c2410_dma_xxxx) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
+-------------------------------+-------------------------------------+
| DMA driver for S3C24XX ? ? ? ?| S3C PL330 DMA API driver ? ? ? ? ? ?|
| PL080 DMA driver for 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) ? ? ? ? ? |
+-------------------------------+-------------------------------------+
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ||
? ? ? ? ? ? ? (removing S3C DMA API for PL330)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ||
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \/
+---------------------------------------------------------------------+
| Each drivers which uses DMA ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
+-------------------------------+-------------------------------------+
Quoted 9 lines
| S3C DMA API(s3c2410_dma_xxx) ?| DMA generic API for PL330 ? ? ? ? ? |
+-------------------------------+-------------------------------------+
| DMA driver for S3C24XX ? ? ? ?| PL330 DMA API driver ? ? ? ? ? ? ? ?|
| PL080 DMA driver for 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) ? ? ? ? ? |
+-------------------------------+-------------------------------------+

Please share what drivers and use-cases have been tested with the patchset.

Quoted 6 lines

[PATCH V3 02/13] DMA: PL330: Update PL330 DMA API driver 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.

Please separate this patch in to at least 2 parts and explain _why_ you do what you do.

Ex, the following two snippets looks obviously wrong to me. Though I doubt any better changelog can justify that, but atleast that will help me take it seriously. This is also why I ask for test-report.

@@ -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 */

@@ -455,7 +455,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;

Please don't only add to changelogs, but also re-think about the above two changes. Hint: Read the structure definitions header file and how they are used in the pl330 core driver.

Since the other patches would be affected by what you do here, I am not reviewing them until I have either justification or revert of these.

Quoted 1 line

[PATCH V3 03/13] DMA: PL330: Add DMA capabilities

Please don't be conservative with number of patches - segregate independent changes in independent patches or you make my life miserable :(

Thnx
-jassi