To use DMA generic APIs for Samsung DMA
Subsystems (9)
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
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
@@ -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
PATCH v3 2/13 DMA: PL330: Update PL330 DMA API driver
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
@@ -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
PATCH v3 3/13 DMA: PL330: Add DMA capabilities
In reply to Kukjin KimFrom: 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
@@ -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
PATCH v3 4/13 ARM: SAMSUNG: Update to use PL330-DMA driver
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v3 5/13 ARM: SAMSUNG: Add common DMA operations
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v3 6/13 ARM: EXYNOS4: Use generic DMA PL330 driver
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
PATCH v3 7/13 ARM: S5PV210: Use generic DMA PL330 driver
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
PATCH v3 8/13 ARM: S5PC100: Use generic DMA PL330 driver
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
PATCH v3 9/13 ARM: S5P64X0: Use generic DMA PL330 driver
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
@@ -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
PATCH v3 10/13 ARM: SAMSUNG: Remove S3C-PL330-DMA driver
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v3 11/13 spi/s3c64xx: Add support DMA engine API
In reply to Kukjin KimFrom: 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
@@ -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
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.
Signed-off-by Boojin Kim <[email protected]>Cc Grant Likely <[email protected]>Signed-off-by Kukjin Kim <[email protected]>
Quoted 222 lines
--- drivers/spi/spi_s3c64xx.c | 141 ++++++++++++++++++++++----------------------- 1 files changed, 69 insertions(+), 72 deletions(-)drivers/spi/spi_s3c64xx.c +69
-72@@ -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
PATCH v3 12/13 ASoC: Samsung: Update DMA interface
In reply to Kukjin KimFrom: 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.
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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.
PATCH v3 13/13 ARM: SAMSUNG: Remove Samsung specific enum type for dma direction
In reply to Kukjin KimFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
v3 cover To use DMA generic APIs for Samsung DMA
In reply to Kukjin KimQuoted 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