[PATCH v2 1/4] DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit
This patch adds to support burst mode for dev-to-mem and mem-to-dev transmit Change-Id: I9723e49383416773699cf7735168177c8d036f30 Signed-off-by: Boojin Kim boojin@samsung.com --- drivers/dma/pl330.c | 12 +++- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 80680ee..c67f037 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1271,10 +1271,11 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { int off = 0; + enum pl330_cond cond = (pxs-r-cfg-brst_len == 1) ? SINGLE : BURST; while (cyc--) { - off += _emit_WFP(dry_run, buf[off], SINGLE, pxs-r-peri); - off += _emit_LDP(dry_run, buf[off], SINGLE, pxs-r-peri); + off += _emit_WFP(dry_run, buf[off], cond, pxs-r-peri); + off += _emit_LDP(dry_run, buf[off], cond, pxs-r-peri); off += _emit_ST(dry_run, buf[off], ALWAYS); off += _emit_FLUSHP(dry_run, buf[off], pxs-r-peri); } @@ -1286,11 +1287,12 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { int off = 0; + enum pl330_cond cond = (pxs-r-cfg-brst_len == 1) ? SINGLE : BURST; while (cyc--) { - off += _emit_WFP(dry_run, buf[off], SINGLE, pxs-r-peri); + off += _emit_WFP(dry_run, buf[off], cond, pxs-r-peri); off += _emit_LD(dry_run, buf[off], ALWAYS); - off += _emit_STP(dry_run, buf[off], SINGLE, pxs-r-peri); + off += _emit_STP(dry_run, buf[off], cond, pxs-r-peri); off += _emit_FLUSHP(dry_run, buf[off], pxs-r-peri); } @@ -2835,7 +2837,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } desc-rqcfg.brst_size = pch-burst_sz; - desc-rqcfg.brst_len = 1; + desc-rqcfg.brst_len = pch-burst_len; } /* Return the last desc in the chain */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/4] ARM: EXYNOS: support burst mode for for dev-to-mem and mem-to-dev transmit
This patch adds to support burst mode for for dev-to-mem and dev-to-mem transmit Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/plat-samsung/dma-ops.c |4 ++-- arch/arm/plat-samsung/include/plat/dma-ops.h |1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index 71d58dd..6c90c16 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -60,14 +60,14 @@ static int samsung_dmadev_config(unsigned ch, slave_config.direction = param-direction; slave_config.src_addr = param-fifo; slave_config.src_addr_width = param-width; - slave_config.src_maxburst = 1; + slave_config.src_maxburst = param-maxburst; dmaengine_slave_config(chan, slave_config); } else if (param-direction == DMA_MEM_TO_DEV) { memset(slave_config, 0, sizeof(struct dma_slave_config)); slave_config.direction = param-direction; slave_config.dst_addr = param-fifo; slave_config.dst_addr_width = param-width; - slave_config.dst_maxburst = 1; + slave_config.dst_maxburst = param-maxburst; dmaengine_slave_config(chan, slave_config); } else { pr_warn(unsupported direction\n); diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h index 1141782..383bd6d 100644 --- a/arch/arm/plat-samsung/include/plat/dma-ops.h +++ b/arch/arm/plat-samsung/include/plat/dma-ops.h @@ -35,6 +35,7 @@ struct samsung_dma_prep { struct samsung_dma_config { enum dma_transfer_direction direction; enum dma_slave_buswidth width; + u32 maxburst; dma_addr_t fifo; }; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/4] spi: s3c64xx: add dma maxburst size initialization
This patch adds dma maxburst size initialization. The maxburst should be set by MODE_CFGn.DMA_TYPE, because the pl330 dma driver supports burst mode. Signed-off-by: Hyeonkook Kim hk619@samsung.com --- drivers/spi/spi-s3c64xx.c | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index e862ab8..5e6cafe 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -287,10 +287,20 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, struct s3c64xx_spi_driver_data *sdd; struct samsung_dma_prep info; struct samsung_dma_config config; + void __iomem *regs; + unsigned int mode_cfg; if (dma-direction == DMA_DEV_TO_MEM) { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, rx_dma); + + regs = sdd-regs; + mode_cfg = readl(regs + S3C64XX_SPI_MODE_CFG); + if (mode_cfg S3C64XX_SPI_MODE_4BURST) + config.maxburst = 4; + else + config.maxburst = 1; + config.direction = sdd-rx_dma.direction; config.fifo = sdd-sfr_start + S3C64XX_SPI_RX_DATA; config.width = sdd-cur_bpw / 8; @@ -298,6 +308,14 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, } else { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, tx_dma); + + regs = sdd-regs; + mode_cfg = readl(regs + S3C64XX_SPI_MODE_CFG); + if (mode_cfg S3C64XX_SPI_MODE_4BURST) + config.maxburst = 4; + else + config.maxburst = 1; + config.direction = sdd-tx_dma.direction; config.fifo = sdd-sfr_start + S3C64XX_SPI_TX_DATA; config.width = sdd-cur_bpw / 8; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/4] ASoC: samsung: add to configure dma maxburst size
This patch adds to configure dma maxburst size. Signed-off-by: Boojin Kim boojin@samsung.com --- sound/soc/samsung/dma.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 21b7926..bd4faa0 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -172,6 +172,7 @@ static int dma_hw_params(struct snd_pcm_substream *substream, (substream-stream == SNDRV_PCM_STREAM_PLAYBACK ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); config.width = prtd-params-dma_size; + config.maxburst = 1; config.fifo = prtd-params-dma_addr; prtd-params-ch = prtd-params-ops-request( prtd-params-channel, req, rtd-cpu_dai-dev, -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] ARM: EXYNOS: support burst mode for for dev-to-mem and dev-to-mem transmit
This patch adds to support burst mode for for dev-to-mem and dev-to-mem transmit Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/plat-samsung/dma-ops.c | 10 -- arch/arm/plat-samsung/include/plat/dma-ops.h |1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index d088afa..c25e842 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -54,14 +54,20 @@ static int samsung_dmadev_config(unsigned ch, slave_config.direction = param-direction; slave_config.src_addr = param-fifo; slave_config.src_addr_width = param-width; - slave_config.src_maxburst = 1; + if (param-maxburst) + slave_config.src_maxburst = param-maxburst; + else + slave_config.src_maxburst = 1; dmaengine_slave_config(chan, slave_config); } else if (param-direction == DMA_MEM_TO_DEV) { memset(slave_config, 0, sizeof(struct dma_slave_config)); slave_config.direction = param-direction; slave_config.dst_addr = param-fifo; slave_config.dst_addr_width = param-width; - slave_config.dst_maxburst = 1; + if (param-maxburst) + slave_config.dst_maxburst = param-maxburst; + else + slave_config.dst_maxburst = 1; dmaengine_slave_config(chan, slave_config); } else { pr_warn(unsupported direction\n); diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h index f5144cd..95893c7 100644 --- a/arch/arm/plat-samsung/include/plat/dma-ops.h +++ b/arch/arm/plat-samsung/include/plat/dma-ops.h @@ -35,6 +35,7 @@ struct samsung_dma_prep { struct samsung_dma_config { enum dma_transfer_direction direction; enum dma_slave_buswidth width; + u32 maxburst; dma_addr_t fifo; }; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] ARM: EXYNOS: Remove the L2 cache latency setting for EXYNOS5
Joonyoung Shim wrote: I don't understand this. Do you mean that BL1 codes do it? I also wonder how enable L2 cache at the exynos5. Yes, the latency configuration of L2 cache is located on IROM or BL1 code. It can remove the overhead about cache reset and cache flush. And, Kernel enables L2 cache. Thanks. no longer need that in the kernel. It helps to reduce booting time (no need cache disable and cache enable). Signed-off-by: Boojin Kim boojin@samsung.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 쟞rch/arm/mach-exynos/common.c | � 25 - �1 files changed, 0 insertions(+), 25 deletions(-) diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 742edd3..0ec1a91 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -712,31 +712,6 @@ static int __init exynos4_l2x0_cache_init(void) 쟢arly_initcall(exynos4_l2x0_cache_init); �#endif -static int __init exynos5_l2_cache_init(void) -{ - � � � unsigned int val; - - � � � if (!soc_is_exynos5250()) - � � � � � � � return 0; - - � � � asm volatile(mrc p15, 0, %0, c1, c0, 0\n - � � � � � � � � � �bic %0, %0, #(1 2)\n �/* cache disable */ - � � � � � � � � � �mcr p15, 0, %0, c1, c0, 0\n - � � � � � � � � � �mrc p15, 1, %0, c9, c0, 2\n - � � � � � � � � � �: =r(val)); - - � � � val |= (1 9) | (1 5) | (2 6) | (2 0); - - � � � asm volatile(mcr p15, 1, %0, c9, c0, 2\n : : r(val)); - � � � asm volatile(mrc p15, 0, %0, c1, c0, 0\n - � � � � � � � � � �orr %0, %0, #(1 2)\n �/* cache enable */ - � � � � � � � � � �mcr p15, 0, %0, c1, c0, 0\n - � � � � � � � � � �: : r(val)); - - � � � return 0; -} -early_initcall(exynos5_l2_cache_init); - 쟳tatic int __init exynos_init(void) �{ � � � 쟰rintk(KERN_INFO EXYNOS: Initializing architecture\n); -- 1.7.1 ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- - Joonyoung Shim ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 3/3] ASoC: follow the updated samsung DMA common operations
Mark Brown wrote This patch uses config() function to configure DMA transmit options. Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com It'd be good if we could get all the older Samsung platforms moved over to dmaengine... Thanks for your ack :) And, Our engineer's preparing to move the older Samsung dma driver into dmaengine. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] ARM: SAMSUNG: Add config() function in DMA common operations
This patch adds config() that configures DMA transmit option. This function was originally included in request(). But, Some DMA client driver requires to change the configuration after request(). So, This patch picks up it from request(). Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/plat-samsung/dma-ops.c | 77 ++--- arch/arm/plat-samsung/include/plat/dma-ops.h | 20 --- arch/arm/plat-samsung/s3c-dma-ops.c | 39 +++-- 3 files changed, 77 insertions(+), 59 deletions(-) diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index eb9f4f5..51d8590 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -19,72 +19,80 @@ #include mach/dma.h static unsigned samsung_dmadev_request(enum dma_ch dma_ch, - struct samsung_dma_info *info) + struct samsung_dma_req *param) { - struct dma_chan *chan; dma_cap_mask_t mask; - struct dma_slave_config slave_config; void *filter_param; dma_cap_zero(mask); - dma_cap_set(info-cap, mask); + dma_cap_set(param-cap, mask); /* * If a dma channel property of a device node from device tree is * specified, use that as the fliter parameter. */ - filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info-dt_dmach_prop : - (void *)dma_ch; - chan = dma_request_channel(mask, pl330_filter, filter_param); + filter_param = (dma_ch == DMACH_DT_PROP) ? + (void *)param-dt_dmach_prop : (void *)dma_ch; + return (unsigned)dma_request_channel(mask, pl330_filter, filter_param); +} - if (info-direction == DMA_DEV_TO_MEM) { +static int samsung_dmadev_release(unsigned ch, + struct s3c2410_dma_client *client) +{ + dma_release_channel((struct dma_chan *)ch); + + return 0; +} + +static int samsung_dmadev_config(unsigned ch, + struct samsung_dma_config *param) +{ + struct dma_chan *chan = (struct dma_chan *)ch; + struct dma_slave_config slave_config; + + if (param-direction == DMA_DEV_TO_MEM) { memset(slave_config, 0, sizeof(struct dma_slave_config)); - slave_config.direction = info-direction; - slave_config.src_addr = info-fifo; - slave_config.src_addr_width = info-width; + slave_config.direction = param-direction; + slave_config.src_addr = param-fifo; + slave_config.src_addr_width = param-width; slave_config.src_maxburst = 1; dmaengine_slave_config(chan, slave_config); - } else if (info-direction == DMA_MEM_TO_DEV) { + } else if (param-direction == DMA_MEM_TO_DEV) { memset(slave_config, 0, sizeof(struct dma_slave_config)); - slave_config.direction = info-direction; - slave_config.dst_addr = info-fifo; - slave_config.dst_addr_width = info-width; + slave_config.direction = param-direction; + slave_config.dst_addr = param-fifo; + slave_config.dst_addr_width = param-width; slave_config.dst_maxburst = 1; dmaengine_slave_config(chan, slave_config); + } else { + printk(KERN_WARNING unsupported direction\n); + return -EINVAL; } - return (unsigned)chan; -} - -static int samsung_dmadev_release(unsigned ch, - struct s3c2410_dma_client *client) -{ - dma_release_channel((struct dma_chan *)ch); - return 0; } static int samsung_dmadev_prepare(unsigned ch, - struct samsung_dma_prep_info *info) + struct samsung_dma_prep *param) { struct scatterlist sg; struct dma_chan *chan = (struct dma_chan *)ch; struct dma_async_tx_descriptor *desc; - switch (info-cap) { + switch (param-cap) { case DMA_SLAVE: sg_init_table(sg, 1); - sg_dma_len(sg) = info-len; - sg_set_page(sg, pfn_to_page(PFN_DOWN(info-buf)), - info-len, offset_in_page(info-buf)); - sg_dma_address(sg) = info-buf; + sg_dma_len(sg) = param-len; + sg_set_page(sg, pfn_to_page(PFN_DOWN(param-buf)), + param-len, offset_in_page(param-buf)); + sg_dma_address(sg) = param-buf; desc = dmaengine_prep_slave_sg(chan, - sg, 1, info-direction, DMA_PREP_INTERRUPT); + sg, 1, param-direction, DMA_PREP_INTERRUPT); break; case DMA_CYCLIC: - desc = dmaengine_prep_dma_cyclic(chan, - info-buf, info-len, info-period, info-direction
[PATCH 2/3] spi: Add the use of DMA config operation
Config operation is separated from request operation in DMA common operation. Because spi driver can change the DMA config for every transfer. So this patch is using the separated DMA config operation. Signed-off-by: Boojin Kim boojin@samsung.com Signed-off-by: Kyoungil Kim ki0351@samsung.com --- drivers/spi/spi-s3c64xx.c | 33 +++-- 1 files changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 15f864d..f4e2341 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -262,14 +262,24 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, unsigned len, dma_addr_t buf) { struct s3c64xx_spi_driver_data *sdd; - struct samsung_dma_prep_info info; + struct samsung_dma_prep info; + struct samsung_dma_config config; - if (dma-direction == DMA_DEV_TO_MEM) + if (dma-direction == DMA_DEV_TO_MEM) { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, rx_dma); - else + config.direction = sdd-rx_dma.direction; + config.fifo = sdd-sfr_start + S3C64XX_SPI_RX_DATA; + config.width = sdd-cur_bpw / 8; + sdd-ops-config(sdd-rx_dma.ch, config); + } else { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, tx_dma); + config.direction = sdd-tx_dma.direction; + config.fifo = sdd-sfr_start + S3C64XX_SPI_TX_DATA; + config.width = sdd-cur_bpw / 8; + sdd-ops-config(sdd-tx_dma.ch, config); + } info.cap = DMA_SLAVE; info.len = len; @@ -284,20 +294,15 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) { - struct samsung_dma_info info; + struct samsung_dma_req req; sdd-ops = samsung_dma_get_ops(); - info.cap = DMA_SLAVE; - info.client = s3c64xx_spi_dma_client; - info.width = sdd-cur_bpw / 8; - - info.direction = sdd-rx_dma.direction; - info.fifo = sdd-sfr_start + S3C64XX_SPI_RX_DATA; - sdd-rx_dma.ch = sdd-ops-request(sdd-rx_dma.dmach, info); - info.direction = sdd-tx_dma.direction; - info.fifo = sdd-sfr_start + S3C64XX_SPI_TX_DATA; - sdd-tx_dma.ch = sdd-ops-request(sdd-tx_dma.dmach, info); + req.cap = DMA_SLAVE; + req.client = s3c64xx_spi_dma_client; + + sdd-rx_dma.ch = sdd-ops-request(sdd-rx_dma.dmach, req); + sdd-tx_dma.ch = sdd-ops-request(sdd-tx_dma.dmach, req); return 1; } -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] ASoC: follow the updated samsung DMA common operations
This patch uses config() function to configure DMA transmit options. Signed-off-by: Boojin Kim boojin@samsung.com --- sound/soc/samsung/dma.c | 18 ++ 1 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index ddc6cde..f3ebc38 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -74,7 +74,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream) struct runtime_data *prtd = substream-runtime-private_data; dma_addr_t pos = prtd-dma_pos; unsigned int limit; - struct samsung_dma_prep_info dma_info; + struct samsung_dma_prep dma_info; pr_debug(Entered %s\n, __func__); @@ -146,7 +146,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream, unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = snd_soc_dai_get_dma_data(rtd-cpu_dai, substream); - struct samsung_dma_info dma_info; + struct samsung_dma_req req; + struct samsung_dma_config config; pr_debug(Entered %s\n, __func__); @@ -166,16 +167,17 @@ static int dma_hw_params(struct snd_pcm_substream *substream, prtd-params-ops = samsung_dma_get_ops(); - dma_info.cap = (samsung_dma_has_circular() ? + req.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); - dma_info.client = prtd-params-client; - dma_info.direction = + req.client = prtd-params-client; + config.direction = (substream-stream == SNDRV_PCM_STREAM_PLAYBACK ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); - dma_info.width = prtd-params-dma_size; - dma_info.fifo = prtd-params-dma_addr; + config.width = prtd-params-dma_size; + config.fifo = prtd-params-dma_addr; prtd-params-ch = prtd-params-ops-request( - prtd-params-channel, dma_info); + prtd-params-channel, req); + prtd-params-ops-config(prtd-params-ch, config); } snd_pcm_set_runtime_buffer(substream, substream-dma_buffer); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] ARM: EXYNOS: Config ARM_NR_BANKS for EXYNOS SoC
This patch increases the number of banks for EXYNOS4 and EXYNOS5 to support bigger than 2GB memory on it. Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f9d7c47..877dd61 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1134,7 +1134,7 @@ source arch/arm/mm/Kconfig config ARM_NR_BANKS int - default 16 if ARCH_EP93XX + default 16 if ARCH_EP93XX || ARCH_EXYNOS default 8 config IWMMXT -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2 1/2] DMA: PL330: Merge PL330 driver into drivers/dma/
Russell King - ARM Linux wrote: Now that the PL330 code is entirely out of arch/arm, the header should no longer be in asm/hardware/pl330.h. Definitions private to the driver should be in drivers/dma/pl330.c or a header file co-located. Other definitions for interfaces to that driver (eg, platform data) should be in include/linux/amba. That can be the subject of a follow-up patch if this is already finalized. Sorry to late response. I believed my reply was sent. But, It maybe be not. Anyway.. get to the point. Pl08x also has asm/hardware/pl080.h to include hw specific information. It seems to be same purpose with asm/hardware/pl330.h Do you mean both asm/hardware/pl080.h and asm/hardware/pl330.h should be moved to include/linux/amba? ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: EXYNOS: Configure ARM_NR_BANKS for EXYNOS SoC
This patch increases the number of bank for EXYNOS4 and EXYNOS5 to support bigger than 2GB memory on it. Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f9d7c47..d646810 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1134,7 +1134,7 @@ source arch/arm/mm/Kconfig config ARM_NR_BANKS int - default 16 if ARCH_EP93XX + default 16 if ARCH_EP93XX || ARCH_EXYNOS4 || ARCH_EXYNOS5 default 8 config IWMMXT -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: EXYNOS: Configure ARM_NR_BANKS for EXYNOS4
This patch increases the number of bank for EXYNOS4 to support bigger than 2GB memory on it. Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 928cbcc..5c90dee 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1127,7 +1127,7 @@ source arch/arm/mm/Kconfig config ARM_NR_BANKS int - default 16 if ARCH_EP93XX + default 16 if ARCH_EP93XX || ARCH_EXYNOS4 default 8 config IWMMXT -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] DMA: PL330: Support MEMTOMEM transmit without barrier operation.
PL330 r1p0 version fixed the lockup error being on r0p0. This patch supports the DMA transmit without barrier operation if the revision is the next of r0p0. Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/include/asm/hardware/pl330.h |5 + drivers/dma/pl330.c | 26 +- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h index ed38e32..1f4d7cb 100644 --- a/arch/arm/include/asm/hardware/pl330.h +++ b/arch/arm/include/asm/hardware/pl330.h @@ -144,6 +144,11 @@ enum pl330_reqtype { #define CRD0xe14 #define PERIPH_ID 0xfe0 +#define PERIPH_REV_SHIFT 20 +#define PERIPH_REV_MASK0xf +#define PERIPH_REV_R0P00 +#define PERIPH_REV_R1P01 +#define PERIPH_REV_R1P12 #define PCELL_ID 0xff0 #define CR0_PERIPH_REQ_SET (1 0) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 3214ced..d87d884 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -129,6 +129,7 @@ struct pl330_reqcfg { enum pl330_dstcachectrl dcctl; enum pl330_srccachectrl scctl; enum pl330_byteswap swap; + struct pl330_config *pcfg; }; /* @@ -438,6 +439,11 @@ static inline u32 get_id(struct pl330_info *pi, u32 off) return id; } +static inline u32 get_revision(u32 periph_id) +{ + return (periph_idPERIPH_REV_SHIFT)PERIPH_REV_MASK; +} + static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], enum pl330_dst da, u16 val) { @@ -1026,12 +1032,21 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { int off = 0; + struct pl330_config *pcfg = pxs-r-cfg-pcfg; - while (cyc--) { - off += _emit_LD(dry_run, buf[off], ALWAYS); - off += _emit_RMB(dry_run, buf[off]); - off += _emit_ST(dry_run, buf[off], ALWAYS); - off += _emit_WMB(dry_run, buf[off]); + /* check lock-up free version */ + if (get_revision(pcfg-periph_id) = PERIPH_REV_R1P0) { + while (cyc--) { + off += _emit_LD(dry_run, buf[off], ALWAYS); + off += _emit_ST(dry_run, buf[off], ALWAYS); + } + } else { + while (cyc--) { + off += _emit_LD(dry_run, buf[off], ALWAYS); + off += _emit_RMB(dry_run, buf[off]); + off += _emit_ST(dry_run, buf[off], ALWAYS); + off += _emit_WMB(dry_run, buf[off]); + } } return off; @@ -2398,6 +2413,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) async_tx_ack(desc-txd); desc-req.peri = peri_id ? pch-chan.chan_id : 0; + desc-rqcfg.pcfg = pch-dmac-pif.pcfg; dma_async_tx_descriptor_init(desc-txd, pch-chan); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/2] DMA: PL330: Removes useless function
Jassi Brar wrote: Subject: Re: [PATCH 2/2] DMA: PL330: Removes useless function On Thu, Dec 8, 2011 at 1:53 PM, Kukjin Kim kgene@samsung.com wrote: From: Boojin Kim boojin@samsung.com Cc: Jassi Brar jassisinghb...@gmail.com Cc: Linus Walleij linus.wall...@linaro.org Cc: Vinod Koul vinod.k...@intel.com Signed-off-by: Boojin Kim boojin@samsung.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 47 - -- 1 files changed, 0 insertions(+), 47 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 35f0904..b917477 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1512,53 +1512,6 @@ static int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op) return ret; } -static int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus) -{ - struct pl330_thread *thrd = ch_id; - struct pl330_dmac *pl330; - struct pl330_info *pi; - void __iomem *regs; - int active; - u32 val; - - if (!pstatus || !thrd || thrd-free) - return -EINVAL; - - pl330 = thrd-dmac; - pi = pl330-pinfo; - regs = pi-base; - - /* The client should remove the DMAC and add again */ - if (pl330-state == DYING) - pstatus-dmac_halted = true; - else - pstatus-dmac_halted = false; - - val = readl(regs + FSC); - if (val (1 thrd-id)) - pstatus-faulting = true; - else - pstatus-faulting = false; - - active = _thrd_active(thrd); - - if (!active) { - /* Indicate that the thread is not running */ - pstatus-top_req = NULL; - pstatus-wait_req = NULL; - } else { - active--; - pstatus-top_req = thrd-req[active].r; - pstatus-wait_req = !IS_FREE(thrd-req[1 - active]) - ? thrd-req[1 - active].r : NULL; - } - - pstatus-src_addr = readl(regs + SA(thrd-id)); - pstatus-dst_addr = readl(regs + DA(thrd-id)); - - return 0; -} NAK. Recently Samsung ASoC regressed to update DMA pointer only at period boundaries. I am sure other platforms would like to have low audio latencies and hence need this function. ASoC doesn't use DMA HW pointer to get its position with the new pl330 driver on dmaengine. So, pl330_chan_status() isn't used anymore. It just brings a build warning. Thanks you. ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/2] DMA: PL330: Merge PL330 driver into drivers/dma/
Jassi Brar [mailto:jassisinghb...@gmail.com] wrote: Please try to maintain general order of functions and definitions/declarations in the code. Thanks for your review. I will re-summit with our comment. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
DMA: PL330: Merge PL330 drivers
In-Reply-To: PL330 driver is divided into 2 parts. First is the PL330 API driver that located on driver/dma/. Second is the low-level PL330 driver that is located on arch/arm/common/. But, It's not needed anymore to divided PL330 driver into 2 parts Low-level PL330 driver is only used for PL330 API driver on driver/dma because samsung specific S3C-PL330 driver was gone. So, This patch merges 'arch/arm/common/pl330' into 'driver/dma/pl330.c'. [PATCH 1/2] DMA: PL330: Merge PL330 drivers [PATCH 2/2] DMA: PL330: Remove an unused function -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] DMA: PL330: Remove an unused function
Signed-off-by: Boojin Kim boojin@samsung.com --- drivers/dma/pl330.c | 47 --- 1 files changed, 0 insertions(+), 47 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index f3303f0..f9b599a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1512,53 +1512,6 @@ static int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op) return ret; } -static int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus) -{ - struct pl330_thread *thrd = ch_id; - struct pl330_dmac *pl330; - struct pl330_info *pi; - void __iomem *regs; - int active; - u32 val; - - if (!pstatus || !thrd || thrd-free) - return -EINVAL; - - pl330 = thrd-dmac; - pi = pl330-pinfo; - regs = pi-base; - - /* The client should remove the DMAC and add again */ - if (pl330-state == DYING) - pstatus-dmac_halted = true; - else - pstatus-dmac_halted = false; - - val = readl(regs + FSC); - if (val (1 thrd-id)) - pstatus-faulting = true; - else - pstatus-faulting = false; - - active = _thrd_active(thrd); - - if (!active) { - /* Indicate that the thread is not running */ - pstatus-top_req = NULL; - pstatus-wait_req = NULL; - } else { - active--; - pstatus-top_req = thrd-req[active].r; - pstatus-wait_req = !IS_FREE(thrd-req[1 - active]) - ? thrd-req[1 - active].r : NULL; - } - - pstatus-src_addr = readl(regs + SA(thrd-id)); - pstatus-dst_addr = readl(regs + DA(thrd-id)); - - return 0; -} - /* Reserve an event */ static inline int _alloc_event(struct pl330_thread *thrd) { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: MM: Configure the number of banks
This patch configures NR_BANKS by machine specific configuration. NR_BANKS should be increased to support bigger than 2GB memory. Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/include/asm/setup.h |6 ++ arch/arm/mach-ep93xx/include/mach/memory.h |4 arch/arm/mach-exynos/include/mach/memory.h |4 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 915696d..b91ec39 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -192,10 +192,8 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn } /* * Memory map description */ -#ifdef CONFIG_ARCH_EP93XX -# define NR_BANKS 16 -#else -# define NR_BANKS 8 +#ifndef NR_BANKS +#define NR_BANKS 8 #endif struct membank { diff --git a/arch/arm/mach-ep93xx/include/mach/memory.h b/arch/arm/mach-ep93xx/include/mach/memory.h index c9400cf..2c0462e 100644 --- a/arch/arm/mach-ep93xx/include/mach/memory.h +++ b/arch/arm/mach-ep93xx/include/mach/memory.h @@ -19,4 +19,8 @@ #error Kconfig bug: No EP93xx PHYS_OFFSET set #endif +#if defined(CONFIG_ARCH_EP93XX) +#define NR_BANKS 16 +#endif + #endif diff --git a/arch/arm/mach-exynos/include/mach/memory.h b/arch/arm/mach-exynos/include/mach/memory.h index 374ef2c..b7e146c 100644 --- a/arch/arm/mach-exynos/include/mach/memory.h +++ b/arch/arm/mach-exynos/include/mach/memory.h @@ -15,6 +15,10 @@ #define PLAT_PHYS_OFFSET UL(0x4000) +#if defined(CONFIG_MACH_SMDKV310) +#define NR_BANKS 16 +#endif + /* Maximum of 256MiB in one bank */ #define MAX_PHYSMEM_BITS 32 #define SECTION_SIZE_BITS 28 -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/2] Add PM_RUNTIME related fixes for PL330
Tushar Behera [mailto:tushar.beh...@linaro.org] wrote: Sent: Tuesday, December 06, 2011 7:46 PM To: linux-samsung-soc@vger.kernel.org; linux-ker...@vger.kernel.org Cc: kgene@samsung.com; vinod.k...@intel.com; linaro-...@lists.linaro.org; patc...@linaro.org Subject: [PATCH 0/2] Add PM_RUNTIME related fixes for PL330 Hi, When PM_RUNTIME is enabled, PL330 probe fails because of some mismatch in pm_runtime calls. This patchset fixes those issues. This patch is based on Kukjin's for-next branch and tested on EXYNOS4 based Origen board. This patch works well when PM_RUNTIME is enabled. Looks good to me. Thanks. d3d936c Merge branch 'samsung-fixes-2' into for-next Tushar Behera (2): To Vinod Koul vinod.k...@intel.com: DMA: PL330: Remove pm_runtime_xxx calls from pl330 probe/remove To Kukjin Kim kgene@samsung.com: ARM: EXYNOS: Add apb_pclk clkdev entry for mdma1 arch/arm/mach-exynos/clock.c |1 + drivers/dma/pl330.c | 17 ++--- 2 files changed, 3 insertions(+), 15 deletions(-) -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: EXYNOS: Enable MDMA driver
This patch adds MDMA platform data and enables MDMA for DMA memcpy operation Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/mach-exynos/clock.c |8 + arch/arm/mach-exynos/dma.c | 35 arch/arm/mach-exynos/include/mach/irqs.h |2 + arch/arm/mach-exynos/include/mach/map.h|3 +- arch/arm/plat-samsung/include/plat/dma-pl330.h |8 + 5 files changed, 55 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c index 5d8d483..28e2842 100644 --- a/arch/arm/mach-exynos/clock.c +++ b/arch/arm/mach-exynos/clock.c @@ -782,6 +782,13 @@ static struct clk clk_pdma1 = { .ctrlbit= (1 1), }; +static struct clk clk_mdma1 = { + .name = dma, + .devname= dma-pl330.2, + .enable = exynos4_clk_ip_image_ctrl, + .ctrlbit= ((1 8) | (1 5) | (1 2)), +}; + struct clk *clkset_group_list[] = { [0] = clk_ext_xtal_mux, [1] = clk_xusbxti, @@ -1294,6 +1301,7 @@ static struct clksrc_clk *sysclks[] = { static struct clk *clk_cdev[] = { clk_pdma0, clk_pdma1, + clk_mdma1, }; static struct clksrc_clk *clksrc_cdev[] = { diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index b10fcd2..e89329e 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -139,6 +139,38 @@ struct amba_device exynos4_device_pdma1 = { .periphid = 0x00041330, }; +u8 mdma_peri[] = { + DMACH_MTOM_0, + DMACH_MTOM_1, + DMACH_MTOM_2, + DMACH_MTOM_3, + DMACH_MTOM_4, + DMACH_MTOM_5, + DMACH_MTOM_6, + DMACH_MTOM_7, +}; + +struct dma_pl330_platdata exynos4_mdma_pdata = { + .nr_valid_peri = ARRAY_SIZE(mdma_peri), + .peri_id = mdma_peri, +}; + +struct amba_device exynos4_device_mdma = { + .dev = { + .init_name = dma-pl330.2, + .dma_mask = dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = exynos4_mdma_pdata, + }, + .res = { + .start = EXYNOS4_PA_MDMA1, + .end = EXYNOS4_PA_MDMA1 + SZ_4K, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_MDMA1, NO_IRQ}, + .periphid = 0x00041330, +}; + static int __init exynos4_dma_init(void) { if (of_have_populated_dt()) @@ -152,6 +184,9 @@ static int __init exynos4_dma_init(void) dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask); amba_device_register(exynos4_device_pdma1, iomem_resource); + dma_cap_set(DMA_MEMCPY, exynos4_mdma_pdata.cap_mask); + amba_device_register(exynos4_device_mdma, iomem_resource); + return 0; } arch_initcall(exynos4_dma_init); diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index 713dd52..f7d73b1 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h @@ -43,6 +43,8 @@ #define IRQ_EINT15 IRQ_SPI(31) #define IRQ_EINT16_31 IRQ_SPI(32) +#define IRQ_MDMA0 IRQ_SPI(33) +#define IRQ_MDMA1 IRQ_SPI(34) #define IRQ_PDMA0 IRQ_SPI(35) #define IRQ_PDMA1 IRQ_SPI(36) #define IRQ_TIMER0_VIC IRQ_SPI(37) diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 058541d..03e2c99 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -67,7 +67,8 @@ #define EXYNOS4_PA_TWD 0x10500600 #define EXYNOS4_PA_L2CC0x10502000 -#define EXYNOS4_PA_MDMA0x1081 +#define EXYNOS4_PA_MDMA0 0x1081 +#define EXYNOS4_PA_MDMA1 0x1284 #define EXYNOS4_PA_PDMA0 0x1268 #define EXYNOS4_PA_PDMA1 0x1269 diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index c5eaad5..ecf23a8 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -82,6 +82,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, }; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2] ARM: pl330: Fix a race condition
Javi Merino wrote: On Samsung's Exynos4 platform, while testing audio playback with i2s interface, the above change causes the playback to freeze. The _thrd_active(thrd) call always returns '1' and hence _start(thrd) is not getting called. If _thrd_active(thrd) returns '1', that means there is an active transfer still running or, if it has finished, you haven't called pl330_update() to acknowledge that. pl330_update() calls _start() as soon as it can. drivers/dma/pl330.c registers the irq handler in pl330_probe(), so when the transaction finishes, pl330_update() should clear it and call _start(). If there is any outstanding transaction, it should start straight away. If there isn't, it would mark the channel as free, so _thrd_active() should return '0'. If _thrd_active() is still '1', then something has gone wrong in the way. Does this shed some light? Your patch makes the memcpy operation on dmatest.c and net DMA be frozen too as well as Samsung audio playback. With our patch, common DMA memcpy sequence may be changed. I think.. it's needed to find the other way not to bring these side effects. Cheers, Javi -- To unsubscribe from this list: send the line unsubscribe linux- samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2] ARM: pl330: Fix a race condition
Javi Merino wrote: On Samsung's Exynos4 platform, while testing audio playback with i2s interface, the above change causes the playback to freeze. The _thrd_active(thrd) call always returns '1' and hence _start(thrd) is not getting called. If _thrd_active(thrd) returns '1', that means there is an active transfer still running or, if it has finished, you haven't called pl330_update() to acknowledge that. pl330_update() calls _start() as soon as it can. drivers/dma/pl330.c registers the irq handler in pl330_probe(), so when the transaction finishes, pl330_update() should clear it and call _start(). If there is any outstanding transaction, it should start straight away. If there isn't, it would mark the channel as free, so _thrd_active() should return '0'. If _thrd_active() is still '1', then something has gone wrong in the way. Does this shed some light? Your patch makes the memcpy operation on dmatest.c and net DMA be frozen too as well as Samsung audio playback. Is the IRQ correctly registered in drivers/dma/pl330.c:pl330_probe()? Do you get interrupts when the transfer finish? Sure. IRQ works well. The only way I can think of that ee3f615819404a9438b2dd01b7a39f276d2737f2 can break break something is that you aren't calling pl330_update() at all. With our patch, common DMA memcpy sequence may be changed. Which one is our patch? I'm sorry, I'm not subscribed to any of the lists so I may have missed something. Sorry to make you confused. I mean.. With your patch, common DMA memcpy sequence may be changed. Your patch brings the side effect that freezes dma transmits. Cheers, Javi ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ASoC: SAMSUNG: Fix build error
This patch adds linux/modules.h to fix following build errors. sound/soc/codecs/wm8994.c: In function 'wm8994_readable': sound/soc/codecs/wm8994.c:58: warning: unused variable 'wm8994' sound/soc/samsung/smdk_wm8994.c:176: error: expected declaration specifiers or '...' before string constant sound/soc/samsung/smdk_wm8994.c:176: warning: data definition has no type or storage class sound/soc/samsung/smdk_wm8994.c:176: warning: type defaults to 'int' in declaration of 'MODULE_DESCRIPTION' sound/soc/samsung/smdk_wm8994.c:176: warning: function declaration isn't a prototype sound/soc/samsung/smdk_wm8994.c:177: error: expected declaration specifiers or '...' before string constant Signed-off-by: Boojin Kim boojin@samsung.com --- sound/soc/samsung/smdk_wm8994.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index f75e439..ad9ac42 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -9,6 +9,7 @@ #include ../codecs/wm8994.h #include sound/pcm_params.h +#include linux/module.h /* * Default CFG switch settings to use this driver: -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] DMA: PL330: Fix build warning
This patch adds to fix the build warning as following. drivers/dma/pl330.c: In function 'pl330_probe': drivers/dma/pl330.c:859: warning: comparison of distinct pointer types lacks a cast Signed-off-by: Boojin Kim boojin@samsung.com --- drivers/dma/pl330.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 621134f..379d928 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -856,7 +856,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) INIT_LIST_HEAD(pd-channels); /* Initialize channel parameters */ - num_chan = max(pdat ? pdat-nr_valid_peri : 0, (u8)pi-pcfg.num_chan); + num_chan = max(pdat ? (int)pdat-nr_valid_peri : 0, + (int)pi-pcfg.num_chan); pdmac-peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); for (i = 0; i num_chan; i++) { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v6 03/10] ARM: EXYNOS4: Modify platform data for pl330 driver
Thomas Abraham wrote: Dear Mr. Kim, On 10 October 2011 23:45, Thomas Abraham thomas.abra...@linaro.org wrote: With the 'struct dma_pl330_peri' removed, the platfrom data for dma driver can be simplified to a simple list of peripheral request ids. Cc: Jassi Brar jassisinghb...@gmail.com Cc: Boojin Kim boojin@samsung.com Signed-off-by: Thomas Abraham thomas.abra...@linaro.org Acked-by: Kukjin Kim kgene@samsung.com Acked-by: Grant Likely grant.lik...@secretlab.ca --- 쟞rch/arm/mach-exynos4/dma.c | �223 - -- �1 files changed, 62 insertions(+), 161 deletions(-) diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach- exynos4/dma.c index 9667c61..c3c0d17 100644 --- a/arch/arm/mach-exynos4/dma.c +++ b/arch/arm/mach-exynos4/dma.c @@ -35,95 +35,40 @@ 쟳tatic u64 dma_dmamask = DMA_BIT_MASK(32); -struct dma_pl330_peri pdma0_peri[28] = { - � � � { - � � � � � � � .peri_id = (u8)DMACH_PCM0_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_PCM0_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_PCM2_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_PCM2_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_MSM_REQ0, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_MSM_REQ2, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SPI0_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SPI0_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SPI2_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SPI2_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_I2S0S_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_I2S0_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_I2S0_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_UART0_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_UART0_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_UART2_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_UART2_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_UART4_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_UART4_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SLIMBUS0_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SLIMBUS0_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SLIMBUS2_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SLIMBUS2_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SLIMBUS4_RX, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_SLIMBUS4_TX, - � � � � � � � .rqtype = MEMTODEV, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_AC97_MICIN, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_AC97_PCMIN, - � � � � � � � .rqtype = DEVTOMEM, - � � � }, { - � � � � � � � .peri_id = (u8)DMACH_AC97_PCMOUT, - � � � � � � � .rqtype = MEMTODEV, - � � � }, +u8 pdma0_peri[] = { + � � � DMACH_PCM0_RX, + � � � DMACH_PCM0_TX, + � � � DMACH_PCM2_RX, + � � � DMACH_PCM2_TX, + � � � DMACH_MSM_REQ0, + � � � DMACH_MSM_REQ2, + � � � DMACH_SPI0_RX, + � � � DMACH_SPI0_TX, + � � � DMACH_SPI2_RX, + � � � DMACH_SPI2_TX, + � � � DMACH_I2S0S_TX, + � � � DMACH_I2S0_RX, + � � � DMACH_I2S0_TX, As you have suggested, I have rechecked the platform data for all s5p platforms in this patchset. Here, DMACH_I2S2_RX (event id 13) and DMACH_I2S2_TX (event id 14) of DMAC[0] are missing as per the exynos4210 user manual. But these where missing in the original code as well which this patch modified. If possible, could you please let me know if DMACH_I2S2_RX and DMACH_I2S2_TX are indeed event id 13 and 14 in DMAC[0]. Yes, DMACH_I2S2_RX and DMACH_I2X2_TX are missed from my patch. Can you modify it although you are inconvenient ? Thanks.. Boojin I have rechecked the other s5p platform data for dmac (s5p64x0, s5pc100, s5pv210). Apart from the typo pointed out by Anca for s5pc100, there are no other issues. Thanks, Thomas. + � � � DMACH_UART0_RX, + � � � DMACH_UART0_TX, + � � � DMACH_UART2_RX, + � � � DMACH_UART2_TX, + � � � DMACH_UART4_RX, + � � � DMACH_UART4_TX
RE: [PATCH v6 09/10] ARM: S5PC100: Modify platform data for pl330 driver
Thomas Abraham wrote: Sent: Tuesday, October 11, 2011 3:16 AM To: linux-arm-ker...@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org; kgene@samsung.com; vinod.k...@intel.com; Jassi Brar; Boojin Kim Subject: [PATCH v6 09/10] ARM: S5PC100: Modify platform data for pl330 driver With the 'struct dma_pl330_peri' removed, the platfrom data for dma driver can be simplified to a simple list of peripheral request ids. Cc: Jassi Brar jassisinghb...@gmail.com Cc: Boojin Kim boojin@samsung.com Signed-off-by: Thomas Abraham thomas.abra...@linaro.org --- arch/arm/mach-s5pc100/dma.c | 247 --- 1 files changed, 69 insertions(+), 178 deletions(-) Looks good to me. Acked-by: Boojin Kim boojin@samsung.com diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index 065a087..8dfdc76 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -35,100 +35,42 @@ static u64 dma_dmamask = DMA_BIT_MASK(32); -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v6 04/10] DMA: PL330: Add device tree support
Thomas Abraham wrote: Sent: Tuesday, October 11, 2011 3:16 AM To: linux-arm-ker...@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org; kgene@samsung.com; vinod.k...@intel.com; Jassi Brar; Boojin Kim Subject: [PATCH v6 04/10] DMA: PL330: Add device tree support For PL330 dma controllers instantiated from device tree, the channel lookup is based on phandle of the dma controller and dma request id specified by the client node. During probe, the private data of each channel of the controller is set to point to the device node of the dma controller. The 'chan_id' of the each channel is used as the dma request id. Client driver requesting dma channels specify the phandle of the dma controller and the request id. The pl330 filter function converts the phandle to the device node pointer and matches that with channel's private data. If a match is found, the request id from the client node and the 'chan_id' of the channel is matched. A channel is found if both the values match. Cc: Jassi Brar jassisinghb...@gmail.com Cc: Boojin Kim boojin@samsung.com Signed-off-by: Thomas Abraham thomas.abra...@linaro.org Reviewed-by: Rob Herring rob.herr...@calxeda.com Acked-by: Jassi Brar jassisinghb...@gmail.com Acked-by: Grant Likely grant.lik...@secretlab.ca --- Looks good to me. Acked-by: Boojin Kim boojin@samsung.com -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v8 04/16] DMA: PL330: Remove the start operation for handling DMA_TERMINATE_ALL command
Jassi Brar wrote: Subject: Re: [PATCH v8 04/16] DMA: PL330: Remove the start operation for handling DMA_TERMINATE_ALL command On 7 September 2011 12:53, Kukjin Kim kgene@samsung.com wrote: Jassi Brar wrote: On 6 September 2011 17:57, Russell King - ARM Linux li...@arm.linux.org.uk wrote: On Tue, Sep 06, 2011 at 05:52:19PM +0530, Jassi Brar wrote: On Fri, Sep 2, 2011 at 6:14 AM, Boojin Kim boojin@samsung.com wrote: Origianl code carries out the start operation after flush operation. But start operation is not required for DMA_TERMINATE_ALL command. So, This patch removes the unnecessary start operation and only carries out the flush oeration for handling DMA_TERMINATE_ALL command. Not exactly. The 'start' is impotent when called from this path because there is nothing left queued after the call to 'flush'. pl330_tasklet() is called because that is a common function that does the house-keeping acc to what's presently in 'work' and 'done' lists. Though as a side-effect, your patch does avoid doing callbacks on submitted xfers during DMA_TERMINATE_ALL - which may or may not be the right thing to do. It is defined that DMA_TERMINATE_ALL does not call the callbacks: 1. int dmaengine_terminate_all(struct dma_chan *chan) � This causes all activity for the DMA channel to be stopped, and may � discard data in the DMA FIFO which hasn't been fully transferred. � No callback functions will be called for any incomplete transfers. Ok, thanks for the info. Boojin Kim, please re-write the changelog to state only preventing callbacks during DMA_TERMINATE_ALL as the reason. As above, we don't need callback as well start operation in DMA_TERMIANTE_ALL command and her patch just removed them for DMA_TERMINATE_ALL here. So current git message seems to have proper behavior of patch. Nopes. No modification to current code is needed if only the following is to be the reason. { Origianl code carries out the start operation after flush operation. But start operation is not required for DMA_TERMINATE_ALL command. So, This patch removes the unnecessary start operation and only carries out the flush oeration for handling DMA_TERMINATE_ALL command. } The patch, however, has unintended good effect of preventing callbacks from DMA_TERMINATE_ALL. The only valid reason, and which is no way implied by the changelog. According to dmaengine document, dmaengine_terminate_all() is used to pause or stop the channel. So, dmaengine_terminate_all() doesn뭪 need to have the start operation and callback calling. This patch is originally aimed at removing unnecessary operations including the start operation and callback call for dmaengine_terminate_all(). And I think my message pretty expresses the purpose of this patch. Thanks, Boojin kim -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 04/16] DMA: PL330: Remove the start operation for handling DMA_TERMINATE_ALL command
Origianl code carries out the start operation after flush operation. But start operation is not required for DMA_TERMINATE_ALL command. So, This patch removes the unnecessary start operation and only carries out the flush oeration for handling DMA_TERMINATE_ALL command. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index e7f9d1d..59943ec 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -262,10 +262,11 @@ 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; + LIST_HEAD(list); switch (cmd) { case DMA_TERMINATE_ALL: @@ -275,12 +276,14 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); /* Mark all desc done */ - list_for_each_entry(desc, pch-work_list, node) + 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); - - pl330_tasklet((unsigned long) pch); break; case DMA_SLAVE_CONFIG: slave_config = (struct dma_slave_config *)arg; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 02/16] 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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/Kconfig|3 ++- drivers/dma/pl330.c| 14 +- include/linux/amba/pl330.h |6 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 2e3b3d3..ab8f469 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL config PL330_DMA tristate DMA API Driver for PL330 select DMA_ENGINE - depends on PL330 + 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 diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0b99af1..d5829c7 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -18,6 +18,7 @@ #include linux/amba/bus.h #include linux/amba/pl330.h #include linux/pm_runtime.h +#include linux/scatterlist.h #define NR_DEFAULT_DESC16 @@ -69,6 +70,10 @@ struct dma_pl330_chan { * NULL if the channel is available to be acquired. */ void *pl330_chid; + + /* For D-to-M and M-to-D channels */ + int burst_sz; /* the peripheral fifo width */ + dma_addr_t fifo_addr; }; struct dma_pl330_dmac { @@ -456,7 +461,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) if (peri) { desc-req.rqtype = peri-rqtype; - desc-req.peri = peri-peri_id; + desc-req.peri = pch-chan.chan_id; } else { desc-req.rqtype = MEMTOMEM; desc-req.peri = 0; @@ -582,7 +587,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 || !peri)) @@ -598,8 +603,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } - addr = peri-fifo_addr; - burst_size = peri-burst_sz; + addr = pch-fifo_addr; first = NULL; @@ -647,7 +651,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 = pch-burst_sz; desc-rqcfg.brst_len = 1; } diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h index cbee7de..d12f077 100644 --- a/include/linux/amba/pl330.h +++ b/include/linux/amba/pl330.h @@ -19,12 +19,8 @@ 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 */ - int burst_sz; /* in power of 2 */ - dma_addr_t fifo_addr; }; struct dma_pl330_platdata { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 03/16] DMA: PL330: Support DMA_SLAVE_CONFIG command
Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 49 + 1 files changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index d5829c7..e7f9d1d 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -73,6 +73,7 @@ struct dma_pl330_chan { /* For D-to-M and M-to-D channels */ int burst_sz; /* the peripheral fifo width */ + int burst_len; /* the number of burst */ dma_addr_t fifo_addr; }; @@ -263,23 +264,47 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned struct dma_pl330_chan *pch = to_pchan(chan); struct dma_pl330_desc *desc; unsigned long flags; + struct dma_pl330_dmac *pdmac = pch-dmac; + struct dma_slave_config *slave_config; - /* 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); - /* FLUSH the PL330 Channel thread */ - pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); - - /* Mark all desc done */ - list_for_each_entry(desc, pch-work_list, node) - desc-status = DONE; + /* Mark all desc done */ + list_for_each_entry(desc, pch-work_list, node) + desc-status = DONE; - spin_unlock_irqrestore(pch-lock, flags); + spin_unlock_irqrestore(pch-lock, flags); - pl330_tasklet((unsigned long) pch); + pl330_tasklet((unsigned long) pch); + break; + case DMA_SLAVE_CONFIG: + slave_config = (struct dma_slave_config *)arg; + + if (slave_config-direction == DMA_TO_DEVICE) { + if (slave_config-dst_addr) + pch-fifo_addr = slave_config-dst_addr; + if (slave_config-dst_addr_width) + pch-burst_sz = __ffs(slave_config-dst_addr_width); + if (slave_config-dst_maxburst) + pch-burst_len = slave_config-dst_maxburst; + } else if (slave_config-direction == DMA_FROM_DEVICE) { + if (slave_config-src_addr) + pch-fifo_addr = slave_config-src_addr; + if (slave_config-src_addr_width) + pch-burst_sz = __ffs(slave_config-src_addr_width); + if (slave_config-src_maxburst) + pch-burst_len = slave_config-src_maxburst; + } + break; + default: + dev_err(pch-dmac-pif.dev, Not supported command.\n); + return -ENXIO; + } return 0; } -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 01/16] DMA: PL330: Add support runtime PM for PL330 DMAC
Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Jassi Brar jassisinghb...@gmail.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 75 +- 1 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 00eee59..0b99af1 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -17,6 +17,7 @@ #include linux/interrupt.h #include linux/amba/bus.h #include linux/amba/pl330.h +#include linux/pm_runtime.h #define NR_DEFAULT_DESC16 @@ -83,6 +84,8 @@ struct dma_pl330_dmac { /* Peripheral channels connected to this DMAC */ struct dma_pl330_chan *peripherals; /* keep at end */ + + struct clk *clk; }; struct dma_pl330_desc { @@ -696,6 +699,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); @@ -771,8 +798,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, @@ -833,6 +858,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; @@ -846,10 +878,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, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 09/16] ARM: S5PV210: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-s5pv210/Kconfig|2 +- arch/arm/mach-s5pv210/clock.c| 10 +- arch/arm/mach-s5pv210/dma.c | 316 +++--- arch/arm/mach-s5pv210/include/mach/dma.h |2 +- 4 files changed, 214 insertions(+), 116 deletions(-) diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 69dd87c..d960090 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -11,7 +11,7 @@ if ARCH_S5PV210 config CPU_S5PV210 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV select S5P_EXT_INT select S5P_HRT select S5PV210_PM if PM diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 52a8e60..d35726a 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -203,6 +203,11 @@ static struct clk clk_pcmcdclk2 = { .name = pcmcdclk, }; +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, @@ -289,13 +294,13 @@ static struct clk_ops clk_fout_apll_ops = { static struct clk init_clocks_off[] = { { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit= (1 3), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, @@ -1161,5 +1166,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(); } diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index 497d343..f79d0b0 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5pv210/dma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh jassi.b...@samsung.com * @@ -17,151 +21,239 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h #include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5pv210_pdma0_resource[] = { - [0] = { - .start = S5PV210_PA_PDMA0, - .end= S5PV210_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[28] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART3_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART3_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = DMACH_MAX, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S1_TX, + .rqtype = MEMTODEV
[PATCH v8 13/16] spi/s3c64xx: Add support DMA engine API
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Acked-by: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi-s3c64xx.c | 141 ++--- 1 files changed, 69 insertions(+), 72 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 595dacc..24f4903 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -171,6 +171,9 @@ struct s3c64xx_spi_driver_data { unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; + unsignedrx_ch; + unsignedtx_ch; + struct samsung_dma_ops *ops; }; static struct s3c2410_dma_client s3c64xx_spi_dma_client = { @@ -226,6 +229,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) @@ -233,6 +268,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); @@ -258,10 +294,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: @@ -293,10 +333,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, writel(((xfer-len * 8 / sdd-cur_bpw) 0x) | 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); } } @@ -482,46 +526,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
[PATCH v8 08/16] ARM: EXYNOS4: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-exynos4/Kconfig |2 +- arch/arm/mach-exynos4/clock.c | 11 ++- arch/arm/mach-exynos4/dma.c | 299 ++--- 3 files changed, 198 insertions(+), 114 deletions(-) diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index 0c77ab9..9f00cf3 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -11,7 +11,7 @@ if ARCH_EXYNOS4 config CPU_EXYNOS4210 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV help Enable EXYNOS4210 CPU support diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index 851dea0..fee2dd8 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -43,6 +43,11 @@ static struct clk clk_sclk_usbphy1 = { .name = sclk_usbphy1, }; +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); @@ -454,12 +459,12 @@ static struct clk init_clocks_off[] = { .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 10), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 0), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 1), @@ -1210,5 +1215,7 @@ void __init exynos4_register_clocks(void) s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c24xx_register_clock(dummy_apb_pclk); + s3c_pwmclk_init(); } diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c index 564bb53..d57d662 100644 --- a/arch/arm/mach-exynos4/dma.c +++ b/arch/arm/mach-exynos4/dma.c @@ -21,151 +21,228 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h #include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource exynos4_pdma0_resource[] = { - [0] = { - .start = EXYNOS4_PA_PDMA0, - .end= EXYNOS4_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[28] = { + { + .peri_id = (u8)DMACH_PCM0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_PCM0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_PCM2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_PCM2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_MSM_REQ0, + }, { + .peri_id = (u8)DMACH_MSM_REQ2, + }, { + .peri_id = (u8)DMACH_SPI0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_SPI0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_SPI2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_SPI2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART4_RX
[PATCH v8 10/16] ARM: S5PC100: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-s5pc100/Kconfig|2 +- arch/arm/mach-s5pc100/clock.c| 11 +- arch/arm/mach-s5pc100/dma.c | 323 +++-- arch/arm/mach-s5pc100/include/mach/dma.h |2 +- 4 files changed, 222 insertions(+), 116 deletions(-) diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig index e8a33c4..e538a4c 100644 --- a/arch/arm/mach-s5pc100/Kconfig +++ b/arch/arm/mach-s5pc100/Kconfig @@ -10,7 +10,7 @@ if ARCH_S5PC100 config CPU_S5PC100 bool select S5P_EXT_INT - select S3C_PL330_DMA + select SAMSUNG_DMADEV help Enable S5PC100 CPU support diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index ff5cbb3..6527c05 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = { .name = otg_phy, }; +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, @@ -454,13 +459,13 @@ static struct clk init_clocks_off[] = { .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 2), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 1), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, @@ -1276,5 +1281,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(); } diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index bf4cd0f..ef803e9 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5pc100/dma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh jassi.b...@samsung.com * @@ -17,150 +21,245 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h +#include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5pc100_pdma0_resource[] = { - [0] = { - .start = S5PC100_PA_PDMA0, - .end= S5PC100_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[30] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART3_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART3_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = DMACH_IRDA, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S1_TX
[PATCH v8 05/16] DMA: PL330: Add DMA_CYCLIC capability
This patch adds DMA_CYCLIC capability that is used for audio driver. DMA driver activated with it reuses the dma requests that were submitted through tx_submit(). Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 84 ++- 1 files changed, 83 insertions(+), 1 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 59943ec..621134f 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -75,6 +75,9 @@ struct dma_pl330_chan { int burst_sz; /* the peripheral fifo width */ int burst_len; /* the number of burst */ dma_addr_t fifo_addr; + + /* for cyclic capability */ + bool cyclic; }; struct dma_pl330_dmac { @@ -161,6 +164,31 @@ static inline void free_desc_list(struct list_head *list) spin_unlock_irqrestore(pdmac-pool_lock, flags); } +static inline void handle_cyclic_desc_list(struct list_head *list) +{ + struct dma_pl330_desc *desc; + struct dma_pl330_chan *pch; + unsigned long flags; + + if (list_empty(list)) + return; + + list_for_each_entry(desc, list, node) { + dma_async_tx_callback callback; + + /* Change status to reload it */ + desc-status = PREP; + pch = desc-pchan; + callback = desc-txd.callback; + if (callback) + callback(desc-txd.callback_param); + } + + spin_lock_irqsave(pch-lock, flags); + list_splice_tail_init(list, pch-work_list); + spin_unlock_irqrestore(pch-lock, flags); +} + static inline void fill_queue(struct dma_pl330_chan *pch) { struct dma_pl330_desc *desc; @@ -214,7 +242,10 @@ static void pl330_tasklet(unsigned long data) spin_unlock_irqrestore(pch-lock, flags); - free_desc_list(list); + if (pch-cyclic) + handle_cyclic_desc_list(list); + else + free_desc_list(list); } static void dma_pl330_rqcb(void *token, enum pl330_op_err err) @@ -245,6 +276,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) spin_lock_irqsave(pch-lock, flags); pch-completed = chan-cookie = 1; + pch-cyclic = false; pch-pl330_chid = pl330_request_channel(pdmac-pif); if (!pch-pl330_chid) { @@ -324,6 +356,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan) pl330_release_channel(pch-pl330_chid); pch-pl330_chid = NULL; + if (pch-cyclic) + list_splice_tail_init(pch-work_list, pch-dmac-desc_pool); + spin_unlock_irqrestore(pch-lock, flags); } @@ -560,6 +595,51 @@ 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); + dma_addr_t dst; + dma_addr_t src; + + 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 = pch-fifo_addr; + break; + case DMA_FROM_DEVICE: + desc-rqcfg.src_inc = 0; + desc-rqcfg.dst_inc = 1; + src = pch-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 = pch-burst_sz; + desc-rqcfg.brst_len = 1; + + pch-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) @@ -791,6 +871,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); @@ -819,6 +900,7 @@ pl330_probe(struct
[PATCH v8 07/16] ARM: SAMSUNG: Add common DMA operations
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(). Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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| 131 +++ arch/arm/plat-samsung/include/plat/dma-ops.h | 63 +++ arch/arm/plat-samsung/include/plat/dma-pl330.h |4 + arch/arm/plat-samsung/include/plat/dma.h |1 + arch/arm/plat-samsung/s3c-dma-ops.c| 133 8 files changed, 347 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 diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index b2b2a5b..e61a91f 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 0x10 /* 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(128) /* use this to specifiy hardware ch no */ /* we have 4 dma channels */ diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 0a5d926..49c3a53 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -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 diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 853764b..e2ee0b8 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -63,9 +63,11 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.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_SAMSUNG_DMADEV) += dma-ops.o + +obj-$(CONFIG_S3C_PL330_DMA)+= s3c-pl330.o s3c-dma-ops.o # PM support diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c new file mode 100644 index 000..6e3d9ab --- /dev/null +++ b/arch/arm/plat-samsung/dma-ops.c @@ -0,0 +1,131 @@ +/* linux/arch/arm/plat-samsung/dma-ops.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung DMA Operations + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/amba/pl330.h +#include linux/scatterlist.h + +#include mach/dma.h + +static inline bool pl330_filter(struct dma_chan *chan, void *param) +{ + struct dma_pl330_peri *peri = chan-private; + return peri-peri_id == (unsigned)param; +} + +static unsigned samsung_dmadev_request(enum dma_ch dma_ch, + struct samsung_dma_info *info) +{ + struct dma_chan *chan; + dma_cap_mask_t mask; + struct dma_slave_config slave_config; + + dma_cap_zero(mask); + dma_cap_set(info-cap, mask); + + chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); + + if (info-direction == DMA_FROM_DEVICE) { + memset(slave_config, 0, sizeof(struct dma_slave_config)); + slave_config.direction = info-direction; + slave_config.src_addr = info-fifo; + slave_config.src_addr_width = info-width; + slave_config.src_maxburst = 1; + dmaengine_slave_config(chan, slave_config); + } else if (info-direction == DMA_TO_DEVICE) { + memset
[PATCH v8 15/16] ASoC: Samsung: Update DMA interface
This patch adds to support the DMA PL330 driver that uses DMA generic API. Samsung sound driver uses DMA generic API if architecture supports it. Otherwise, use samsung specific S3C-PL330 API driver to transfer PCM data. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Jassi Brar jassisinghb...@gmail.com Cc: Liam Girdwood l...@ti.com Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com [kgene@samsung.com: removed useless variable] Signed-off-by: Kukjin Kim kgene@samsung.com --- 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| 146 ++-- sound/soc/samsung/dma.h|4 +- 6 files changed, 78 insertions(+), 96 deletions(-) diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index e61a91f..4e485ba 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 */ diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 49c3a53..74fdf25 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -58,7 +58,7 @@ enum dma_ch { DMACH_MAX /* the end */ }; -static __inline__ bool s3c_dma_has_circular(void) +static inline bool samsung_dma_has_circular(void) { return true; } diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 9a1dadb..2e55e59 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -89,7 +89,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; } diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index f97110e..b4f9b00 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -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; } diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 9465588..851346f 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -54,7 +54,6 @@ struct runtime_data { spinlock_t lock; int state; unsigned int dma_loaded; - unsigned int dma_limit; unsigned int dma_period; dma_addr_t dma_start; dma_addr_t dma_pos; @@ -62,77 +61,79 @@ struct runtime_data { struct s3c_dma_params *params; }; +static void audio_buffdone(void *data); + /* dma_enqueue * * place a dma buffer onto the queue for the dma system * to handle. -*/ + */ static void dma_enqueue(struct snd_pcm_substream *substream) { struct runtime_data *prtd = substream-runtime-private_data; dma_addr_t pos = prtd-dma_pos; unsigned int limit; - int ret; + struct samsung_dma_prep_info dma_info; pr_debug(Entered %s\n, __func__); - if (s3c_dma_has_circular()) - limit = (prtd-dma_end - prtd-dma_start) / prtd-dma_period; - else - limit = prtd-dma_limit; + limit = (prtd-dma_end - prtd-dma_start) / prtd-dma_period; pr_debug(%s: loaded %d, limit %d\n, __func__, prtd-dma_loaded, limit); - while (prtd-dma_loaded limit) { - unsigned long len = prtd-dma_period; + dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); + dma_info.direction = + (substream-stream
[PATCH v8 12/16] ARM: SAMSUNG: Remove S3C-PL330-DMA driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Cc: Jassi Brar jassisinghb...@gmail.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/plat-samsung/Kconfig |6 - arch/arm/plat-samsung/Makefile |2 - arch/arm/plat-samsung/include/plat/dma-pl330.h | 10 +- .../plat-samsung/include/plat/s3c-pl330-pdata.h| 32 - arch/arm/plat-samsung/s3c-pl330.c | 1244 5 files changed, 6 insertions(+), 1288 deletions(-) delete mode 100644 arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h delete mode 100644 arch/arm/plat-samsung/s3c-pl330.c diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index e6f01ab..0a3eec6 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -300,12 +300,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 SAMSUNG_DMADEV bool select DMADEVICES diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index e2ee0b8..9075849 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -67,8 +67,6 @@ obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o -obj-$(CONFIG_S3C_PL330_DMA)+= s3c-pl330.o s3c-dma-ops.o - # PM support obj-$(CONFIG_PM) += pm.o diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 2916920..9a1dadb 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -11,9 +11,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. @@ -88,6 +85,10 @@ enum dma_ch { DMACH_MAX, }; +struct s3c2410_dma_client { + char*name; +}; + static inline bool s3c_dma_has_circular(void) { return true; @@ -97,6 +98,7 @@ static inline bool samsung_dma_is_dmadev(void) { return true; } -#include plat/dma.h + +#include plat/dma-ops.h #endif /* __DMA_PL330_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h deleted file mode 100644 index 64fdf66..000 --- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +++ /dev/null @@ -1,32 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh jassi.b...@samsung.com - * - * 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 */ diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c deleted file mode 100644 index f85638c..000 --- a/arch/arm/plat-samsung/s3c-pl330.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* linux/arch/arm/plat-samsung/s3c-pl330.c - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh jassi.b...@samsung.com - * - * 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. - */ - -#include linux/init.h -#include linux/module.h -#include linux/interrupt.h -#include linux/io.h -#include linux/slab.h -#include linux/platform_device.h -#include linux/clk.h -#include linux/err.h - -#include asm/hardware/pl330.h - -#include plat/s3c-pl330-pdata.h - -/** - * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC. - * @busy_chan: Number of channels currently busy. - * @peri: List of IDs of peripherals this DMAC can work with. - * @node: To attach to the global list of DMACs
[PATCH v8 00/16] To use DMA generic APIs for Samsung DMA
This patchset adds support DMA generic APIs for samsung DMA. The changes from V7 is following: - Divides patch file. : The 03 patch on V7 patchset is divided into the 03 and 04 patch on V8 patchset. The O3 patch is only for DMA_SLAVE_CONFIG command. The 04 patch is only for DMA_TERMINATE_ALL command. - Code clean-up : Remove unnecessary code on 05 patch. [PATCH v8 01/16] DMA: PL330: Add support runtime PM for PL330 DMAC [PATCH v8 02/16] DMA: PL330: Update PL330 DMA API driver [PATCH v8 03/16] DMA: PL330: Support DMA_SLAVE_CONFIG command [PATCH v8 04/16] DMA: PL330: Remove the start operation for handling DMA_TERMINATE_ALL command [PATCH v8 05/16] DMA: PL330: Add DMA_CYCLIC capability [PATCH v8 06/16] ARM: SAMSUNG: Update to use PL330-DMA driver [PATCH v8 07/16] ARM: SAMSUNG: Add common DMA operations [PATCH v8 08/16] ARM: EXYNOS4: Use generic DMA PL330 driver [PATCH v8 09/16] ARM: S5PV210: Use generic DMA PL330 driver [PATCH v8 10/16] ARM: S5PC100: Use generic DMA PL330 driver [PATCH v8 11/16] ARM: S5P64X0: Use generic DMA PL330 driver [PATCH v8 12/16] ARM: SAMSUNG: Remove S3C-PL330-DMA driver [PATCH v8 13/16] spi/s3c64xx: Add support DMA engine API [PATCH v8 14/16] spi/s3c64xx: Merge dma control code [PATCH v8 15/16] ASoC: Samsung: Update DMA interface [PATCH v8 16/16] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 11/16] ARM: S5P64X0: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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 | 273 -- arch/arm/mach-s5p64x0/include/mach/dma.h |2 +- 5 files changed, 201 insertions(+), 96 deletions(-) diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig index 65c7518..9527ed2 100644 --- a/arch/arm/mach-s5p64x0/Kconfig +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -9,14 +9,14 @@ if ARCH_S5P64X0 config CPU_S5P6440 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV select S5P_HRT help Enable S5P6440 CPU support config CPU_S5P6450 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV select S5P_HRT help Enable S5P6450 CPU support diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index 0e9cd30..c1f548f 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -146,7 +146,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 8), }, { - .name = pdma, + .name = dma, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), @@ -499,6 +499,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; @@ -581,5 +586,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(); } diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index d9dc16c..3d9b609 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -179,7 +179,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 3), }, { - .name = pdma, + .name = dma, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), @@ -553,6 +553,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; @@ -632,5 +637,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(); } diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index d7ad944..aebf3fc 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -21,128 +21,219 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h + +#include asm/irq.h #include mach/map.h #include mach/irqs.h #include mach/regs-clock.h +#include mach/dma.h #include plat/devs.h -#include plat/s3c-pl330-pdata.h +#include plat/irqs.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5p64x0_pdma_resource[] = { - [0] = { - .start = S5P64X0_PA_PDMA, - .end= S5P64X0_PA_PDMA + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_DMA0, - .end= IRQ_DMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri s5p6440_pdma_peri[22] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV
[PATCH v8 16/16] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction
This patch removes the samsung specific enum type 's3c2410_dmasrc' and uses 'dma_data_direction' instead. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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(-) diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index 4e485ba..ae8e482 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 longdev_addr; unsigned longload_timeout; diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 7abecfc..b4fc3ba 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c @@ -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]; diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 204bfaf..67c97fa 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -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(enum dma_ch 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(enum dma_ch 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; diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 74fdf25..fe1a98c 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -99,7 +99,7 @@ struct s3c2410_dma_chan { unsigned charperipheral; unsigned int flags; - enum s3c2410_dmasrc source; + enum dma_data_direction source; dma_addr_t dev_addr; diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 539bd0e..53754bc 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -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(enum dma_ch channel
[PATCH v8 14/16] spi/s3c64xx: Merge dma control code
This patch modifies to merge the dma control code. Original s3c64xx spi driver has each dma control code for rx and tx channel. This patch merges these dma control codes into one. With this patch, a dma setup function and callback function handle for both rx and tx channel. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi-s3c64xx.c | 140 1 files changed, 76 insertions(+), 64 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 24f4903..019a716 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -131,6 +131,12 @@ #define RXBUSY(12) #define TXBUSY(13) +struct s3c64xx_spi_dma_data { + unsignedch; + enum dma_data_direction direction; + enum dma_ch dmach; +}; + /** * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. * @clk: Pointer to the spi clock. @@ -164,15 +170,13 @@ struct s3c64xx_spi_driver_data { struct work_struct work; struct list_headqueue; spinlock_t lock; - enum dma_ch rx_dmach; - enum dma_ch tx_dmach; unsigned long sfr_start; struct completion xfer_completion; unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; - unsignedrx_ch; - unsignedtx_ch; + struct s3c64xx_spi_dma_data rx_dma; + struct s3c64xx_spi_dma_data tx_dma; struct samsung_dma_ops *ops; }; @@ -229,36 +233,76 @@ 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) +static void s3c64xx_spi_dmacb(void *data) { - struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; + struct s3c64xx_spi_driver_data *sdd; + struct s3c64xx_spi_dma_data *dma = data; unsigned long flags; + if (dma-direction == DMA_FROM_DEVICE) + sdd = container_of(data, + struct s3c64xx_spi_driver_data, rx_dma); + else + sdd = container_of(data, + struct s3c64xx_spi_driver_data, tx_dma); + spin_lock_irqsave(sdd-lock, flags); - sdd-state = ~RXBUSY; - /* If the other done */ - if (!(sdd-state TXBUSY)) - complete(sdd-xfer_completion); + if (dma-direction == DMA_FROM_DEVICE) { + sdd-state = ~RXBUSY; + if (!(sdd-state TXBUSY)) + complete(sdd-xfer_completion); + } else { + sdd-state = ~TXBUSY; + if (!(sdd-state RXBUSY)) + complete(sdd-xfer_completion); + } spin_unlock_irqrestore(sdd-lock, flags); } -static void s3c64xx_spi_dma_txcb(void *data) +static void prepare_dma(struct s3c64xx_spi_dma_data *dma, + unsigned len, dma_addr_t buf) { - struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; - unsigned long flags; + struct s3c64xx_spi_driver_data *sdd; + struct samsung_dma_prep_info info; - spin_lock_irqsave(sdd-lock, flags); + if (dma-direction == DMA_FROM_DEVICE) + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, rx_dma); + else + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, tx_dma); - sdd-state = ~TXBUSY; - /* If the other done */ - if (!(sdd-state RXBUSY)) - complete(sdd-xfer_completion); + info.cap = DMA_SLAVE; + info.len = len; + info.fp = s3c64xx_spi_dmacb; + info.fp_param = dma; + info.direction = dma-direction; + info.buf = buf; + + sdd-ops-prepare(dma-ch, info); + sdd-ops-trigger(dma-ch); +} - spin_unlock_irqrestore(sdd-lock, flags); +static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) +{ + struct samsung_dma_info info; + + sdd-ops = samsung_dma_get_ops(); + + info.cap = DMA_SLAVE; + info.client = s3c64xx_spi_dma_client; + info.width = sdd-cur_bpw / 8; + + info.direction = sdd-rx_dma.direction; + info.fifo = sdd-sfr_start + S3C64XX_SPI_RX_DATA; + sdd-rx_dma.ch = sdd-ops-request(sdd-rx_dma.dmach, info); + info.direction = sdd-tx_dma.direction; + info.fifo = sdd-sfr_start + S3C64XX_SPI_TX_DATA; + sdd-tx_dma.ch
[PATCH v8 06/16] ARM: SAMSUNG: Update to use PL330-DMA driver
This patch adds to support PL330-DMA driver on DMADEVICE for S5P SoCs. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-exynos4/include/mach/dma.h |4 ++-- arch/arm/mach-s5p64x0/include/mach/dma.h |2 +- arch/arm/mach-s5pc100/include/mach/dma.h |2 +- arch/arm/mach-s5pv210/include/mach/dma.h |2 +- arch/arm/plat-samsung/Kconfig |9 + .../include/plat/{s3c-dma-pl330.h = dma-pl330.h} |8 .../plat-samsung/include/plat/s3c-pl330-pdata.h|2 +- 7 files changed, 19 insertions(+), 10 deletions(-) rename arch/arm/plat-samsung/include/plat/{s3c-dma-pl330.h = dma-pl330.h} (93%) diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos4/include/mach/dma.h index 81209eb..201842a 100644 --- a/arch/arm/mach-exynos4/include/mach/dma.h +++ b/arch/arm/mach-exynos4/include/mach/dma.h @@ -20,7 +20,7 @@ #ifndef __MACH_DMA_H #define __MACH_DMA_H -/* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +/* This platform uses the common DMA API driver for PL330 */ +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h index 81209eb..1beae2c 100644 --- a/arch/arm/mach-s5p64x0/include/mach/dma.h +++ b/arch/arm/mach-s5p64x0/include/mach/dma.h @@ -21,6 +21,6 @@ #define __MACH_DMA_H /* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5pc100/include/mach/dma.h b/arch/arm/mach-s5pc100/include/mach/dma.h index 81209eb..1beae2c 100644 --- a/arch/arm/mach-s5pc100/include/mach/dma.h +++ b/arch/arm/mach-s5pc100/include/mach/dma.h @@ -21,6 +21,6 @@ #define __MACH_DMA_H /* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h index 81209eb..1beae2c 100644 --- a/arch/arm/mach-s5pv210/include/mach/dma.h +++ b/arch/arm/mach-s5pv210/include/mach/dma.h @@ -21,6 +21,6 @@ #define __MACH_DMA_H /* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index b3e1065..e6f01ab 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -306,6 +306,15 @@ config S3C_PL330_DMA help S3C DMA API Driver for PL330 DMAC. +config SAMSUNG_DMADEV + bool + select DMADEVICES + select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \ + CPU_S5P6450 || CPU_S5P6440) + select ARM_AMBA + help + Use DMA device engine for PL330 DMAC. + comment Power management config SAMSUNG_PM_DEBUG diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h similarity index 93% 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..0a5dade 100644 --- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -8,8 +8,8 @@ * (at your option) any later version. */ -#ifndef__S3C_DMA_PL330_H_ -#define__S3C_DMA_PL330_H_ +#ifndef __DMA_PL330_H_ +#define __DMA_PL330_H_ __FILE__ #define S3C2410_DMAF_AUTOSTART (1 0) #define S3C2410_DMAF_CIRCULAR (1 1) @@ -20,7 +20,7 @@ * 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 { @@ -95,4 +95,4 @@ static inline bool s3c_dma_has_circular(void) #include plat/dma.h -#endif /* __S3C_DMA_PL330_H_ */ +#endif /* __DMA_PL330_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h index bf5e2a9..64fdf66 100644 --- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h @@ -12,7 +12,7 @@ #ifndef __S3C_PL330_PDATA_H #define __S3C_PL330_PDATA_H -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h /* * Every PL330 DMAC has max 32 peripheral interfaces, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More
[PATCH v7 08/15] ARM: S5PV210: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-s5pv210/Kconfig|2 +- arch/arm/mach-s5pv210/clock.c| 10 +- arch/arm/mach-s5pv210/dma.c | 316 +++--- arch/arm/mach-s5pv210/include/mach/dma.h |2 +- 4 files changed, 214 insertions(+), 116 deletions(-) diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 69dd87c..d960090 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -11,7 +11,7 @@ if ARCH_S5PV210 config CPU_S5PV210 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV select S5P_EXT_INT select S5P_HRT select S5PV210_PM if PM diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 52a8e60..d35726a 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -203,6 +203,11 @@ static struct clk clk_pcmcdclk2 = { .name = pcmcdclk, }; +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, @@ -289,13 +294,13 @@ static struct clk_ops clk_fout_apll_ops = { static struct clk init_clocks_off[] = { { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit= (1 3), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, @@ -1161,5 +1166,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(); } diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index 497d343..f79d0b0 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5pv210/dma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh jassi.b...@samsung.com * @@ -17,151 +21,239 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h #include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5pv210_pdma0_resource[] = { - [0] = { - .start = S5PV210_PA_PDMA0, - .end= S5PV210_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[28] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART3_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART3_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = DMACH_MAX, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S1_TX, + .rqtype = MEMTODEV
[PATCH v7 06/15] ARM: SAMSUNG: Add common DMA operations
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(). Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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| 131 +++ arch/arm/plat-samsung/include/plat/dma-ops.h | 63 +++ arch/arm/plat-samsung/include/plat/dma-pl330.h |4 + arch/arm/plat-samsung/include/plat/dma.h |1 + arch/arm/plat-samsung/s3c-dma-ops.c| 133 8 files changed, 347 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 diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index b2b2a5b..e61a91f 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 0x10 /* 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(128) /* use this to specifiy hardware ch no */ /* we have 4 dma channels */ diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 0a5d926..49c3a53 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -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 diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 853764b..e2ee0b8 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -63,9 +63,11 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.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_SAMSUNG_DMADEV) += dma-ops.o + +obj-$(CONFIG_S3C_PL330_DMA)+= s3c-pl330.o s3c-dma-ops.o # PM support diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c new file mode 100644 index 000..6e3d9ab --- /dev/null +++ b/arch/arm/plat-samsung/dma-ops.c @@ -0,0 +1,131 @@ +/* linux/arch/arm/plat-samsung/dma-ops.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung DMA Operations + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/amba/pl330.h +#include linux/scatterlist.h + +#include mach/dma.h + +static inline bool pl330_filter(struct dma_chan *chan, void *param) +{ + struct dma_pl330_peri *peri = chan-private; + return peri-peri_id == (unsigned)param; +} + +static unsigned samsung_dmadev_request(enum dma_ch dma_ch, + struct samsung_dma_info *info) +{ + struct dma_chan *chan; + dma_cap_mask_t mask; + struct dma_slave_config slave_config; + + dma_cap_zero(mask); + dma_cap_set(info-cap, mask); + + chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); + + if (info-direction == DMA_FROM_DEVICE) { + memset(slave_config, 0, sizeof(struct dma_slave_config)); + slave_config.direction = info-direction; + slave_config.src_addr = info-fifo; + slave_config.src_addr_width = info-width; + slave_config.src_maxburst = 1; + dmaengine_slave_config(chan, slave_config); + } else if (info-direction == DMA_TO_DEVICE) { + memset
[PATCH v7 02/15] 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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/Kconfig|3 ++- drivers/dma/pl330.c| 14 +- include/linux/amba/pl330.h |6 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 2e3b3d3..ab8f469 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL config PL330_DMA tristate DMA API Driver for PL330 select DMA_ENGINE - depends on PL330 + 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 diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0b99af1..d5829c7 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -18,6 +18,7 @@ #include linux/amba/bus.h #include linux/amba/pl330.h #include linux/pm_runtime.h +#include linux/scatterlist.h #define NR_DEFAULT_DESC16 @@ -69,6 +70,10 @@ struct dma_pl330_chan { * NULL if the channel is available to be acquired. */ void *pl330_chid; + + /* For D-to-M and M-to-D channels */ + int burst_sz; /* the peripheral fifo width */ + dma_addr_t fifo_addr; }; struct dma_pl330_dmac { @@ -456,7 +461,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) if (peri) { desc-req.rqtype = peri-rqtype; - desc-req.peri = peri-peri_id; + desc-req.peri = pch-chan.chan_id; } else { desc-req.rqtype = MEMTOMEM; desc-req.peri = 0; @@ -582,7 +587,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 || !peri)) @@ -598,8 +603,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } - addr = peri-fifo_addr; - burst_size = peri-burst_sz; + addr = pch-fifo_addr; first = NULL; @@ -647,7 +651,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 = pch-burst_sz; desc-rqcfg.brst_len = 1; } diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h index cbee7de..d12f077 100644 --- a/include/linux/amba/pl330.h +++ b/include/linux/amba/pl330.h @@ -19,12 +19,8 @@ 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 */ - int burst_sz; /* in power of 2 */ - dma_addr_t fifo_addr; }; struct dma_pl330_platdata { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC
Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Jassi Brar jassisinghb...@gmail.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 75 +- 1 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 00eee59..0b99af1 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -17,6 +17,7 @@ #include linux/interrupt.h #include linux/amba/bus.h #include linux/amba/pl330.h +#include linux/pm_runtime.h #define NR_DEFAULT_DESC16 @@ -83,6 +84,8 @@ struct dma_pl330_dmac { /* Peripheral channels connected to this DMAC */ struct dma_pl330_chan *peripherals; /* keep at end */ + + struct clk *clk; }; struct dma_pl330_desc { @@ -696,6 +699,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); @@ -771,8 +798,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, @@ -833,6 +858,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; @@ -846,10 +878,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, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 04/15] DMA: PL330: Add DMA_CYCLIC capability
This patch adds DMA_CYCLIC capability that is used for audio driver. DMA driver activated with it reuses the dma requests that were submitted through tx_submit(). Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 88 +- 1 files changed, 86 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 59943ec..95976cf 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -75,6 +75,9 @@ struct dma_pl330_chan { int burst_sz; /* the peripheral fifo width */ int burst_len; /* the number of burst */ dma_addr_t fifo_addr; + + /* for cyclic capability */ + bool cyclic; }; struct dma_pl330_dmac { @@ -161,6 +164,31 @@ static inline void free_desc_list(struct list_head *list) spin_unlock_irqrestore(pdmac-pool_lock, flags); } +static inline void handle_cyclic_desc_list(struct list_head *list) +{ + struct dma_pl330_desc *desc; + struct dma_pl330_chan *pch; + unsigned long flags; + + if (list_empty(list)) + return; + + list_for_each_entry(desc, list, node) { + dma_async_tx_callback callback; + + /* Change status to reload it */ + desc-status = PREP; + pch = desc-pchan; + callback = desc-txd.callback; + if (callback) + callback(desc-txd.callback_param); + } + + spin_lock_irqsave(pch-lock, flags); + list_splice_tail_init(list, pch-work_list); + spin_unlock_irqrestore(pch-lock, flags); +} + static inline void fill_queue(struct dma_pl330_chan *pch) { struct dma_pl330_desc *desc; @@ -214,7 +242,10 @@ static void pl330_tasklet(unsigned long data) spin_unlock_irqrestore(pch-lock, flags); - free_desc_list(list); + if (pch-cyclic) + handle_cyclic_desc_list(list); + else + free_desc_list(list); } static void dma_pl330_rqcb(void *token, enum pl330_op_err err) @@ -245,6 +276,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) spin_lock_irqsave(pch-lock, flags); pch-completed = chan-cookie = 1; + pch-cyclic = false; pch-pl330_chid = pl330_request_channel(pdmac-pif); if (!pch-pl330_chid) { @@ -324,6 +356,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan) pl330_release_channel(pch-pl330_chid); pch-pl330_chid = NULL; + if (pch-cyclic) + list_splice_tail_init(pch-work_list, pch-dmac-desc_pool); + spin_unlock_irqrestore(pch-lock, flags); } @@ -347,7 +382,9 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, static void pl330_issue_pending(struct dma_chan *chan) { - pl330_tasklet((unsigned long) to_pchan(chan)); + struct dma_pl330_chan *pch = to_pchan(chan); + + pl330_tasklet((unsigned long) pch); } /* @@ -560,6 +597,51 @@ 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); + dma_addr_t dst; + dma_addr_t src; + + 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 = pch-fifo_addr; + break; + case DMA_FROM_DEVICE: + desc-rqcfg.src_inc = 0; + desc-rqcfg.dst_inc = 1; + src = pch-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 = pch-burst_sz; + desc-rqcfg.brst_len = 1; + + pch-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) @@ -791,6 +873,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) case MEMTODEV: case DEVTOMEM
[PATCH v7 07/15] ARM: EXYNOS4: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-exynos4/Kconfig |2 +- arch/arm/mach-exynos4/clock.c | 11 ++- arch/arm/mach-exynos4/dma.c | 299 ++--- 3 files changed, 198 insertions(+), 114 deletions(-) diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index 0c77ab9..9f00cf3 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -11,7 +11,7 @@ if ARCH_EXYNOS4 config CPU_EXYNOS4210 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV help Enable EXYNOS4210 CPU support diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index 851dea0..fee2dd8 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -43,6 +43,11 @@ static struct clk clk_sclk_usbphy1 = { .name = sclk_usbphy1, }; +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); @@ -454,12 +459,12 @@ static struct clk init_clocks_off[] = { .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 10), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 0), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 1), @@ -1210,5 +1215,7 @@ void __init exynos4_register_clocks(void) s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c24xx_register_clock(dummy_apb_pclk); + s3c_pwmclk_init(); } diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c index 564bb53..d57d662 100644 --- a/arch/arm/mach-exynos4/dma.c +++ b/arch/arm/mach-exynos4/dma.c @@ -21,151 +21,228 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h #include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource exynos4_pdma0_resource[] = { - [0] = { - .start = EXYNOS4_PA_PDMA0, - .end= EXYNOS4_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[28] = { + { + .peri_id = (u8)DMACH_PCM0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_PCM0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_PCM2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_PCM2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_MSM_REQ0, + }, { + .peri_id = (u8)DMACH_MSM_REQ2, + }, { + .peri_id = (u8)DMACH_SPI0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_SPI0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_SPI2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_SPI2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART4_RX
To use DMA generic APIs for Samsung DMA
Changes from V7 are following: - [PATCH v7 03/15]: Change commit message - [PATCH v7 04/15]: Change the data type of 'cyclic' variable from 'enum' to 'bool'. It removes the redundant status. - [PATCH v7 05/15]: Change the build configuration name of samsung DMA from 'SAMSUNG_DMA_PL330' to 'SAMSUNG_DMADEV' in order to remove the PL330 dependency on it. [PATCH v7 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC [PATCH v7 02/15] DMA: PL330: Update PL330 DMA API driver [PATCH v7 03/15] DMA: PL330: Modify device_control() [PATCH v7 04/15] DMA: PL330: Add DMA_CYCLIC capability [PATCH v7 05/15] ARM: SAMSUNG: Update to use PL330-DMA driver [PATCH v7 06/15] ARM: SAMSUNG: Add common DMA operations [PATCH v7 07/15] ARM: EXYNOS4: Use generic DMA PL330 driver [PATCH v7 08/15] ARM: S5PV210: Use generic DMA PL330 driver [PATCH v7 09/15] ARM: S5PC100: Use generic DMA PL330 driver [PATCH v7 10/15] ARM: S5P64X0: Use generic DMA PL330 driver [PATCH v7 11/15] ARM: SAMSUNG: Remove S3C-PL330-DMA driver [PATCH v7 12/15] spi/s3c64xx: Add support DMA engine API [PATCH v7 13/15] spi/s3c64xx: Merge dma control code [PATCH v7 14/15] ASoC: Samsung: Update DMA interface [PATCH v7 15/15] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 03/15] DMA: PL330: Modify device_control()
This patch modifies device_control() to support both DMA_TERMINATE_ALL and DMA_SLAVE_CONFIG command. First, modify the flush control for DMA_TERMINATE_ALL command. Second, add the slave configuration control for DMA_SLAVE_CONFIG command. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 56 ++ 1 files changed, 42 insertions(+), 14 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index d5829c7..59943ec 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -73,6 +73,7 @@ struct dma_pl330_chan { /* For D-to-M and M-to-D channels */ int burst_sz; /* the peripheral fifo width */ + int burst_len; /* the number of burst */ dma_addr_t fifo_addr; }; @@ -261,25 +262,52 @@ 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; + LIST_HEAD(list); - /* Only supports DMA_TERMINATE_ALL */ - if (cmd != DMA_TERMINATE_ALL) - return -ENXIO; - - spin_lock_irqsave(pch-lock, flags); - - /* FLUSH the PL330 Channel thread */ - pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); + switch (cmd) { + case DMA_TERMINATE_ALL: + spin_lock_irqsave(pch-lock, flags); - /* Mark all desc done */ - list_for_each_entry(desc, pch-work_list, node) - desc-status = DONE; + /* FLUSH the PL330 Channel thread */ + pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); - spin_unlock_irqrestore(pch-lock, flags); + /* Mark all desc done */ + list_for_each_entry_safe(desc, _dt, pch-work_list , node) { + desc-status = DONE; + pch-completed = desc-txd.cookie; + list_move_tail(desc-node, list); + } - pl330_tasklet((unsigned long) pch); + list_splice_tail_init(list, pdmac-desc_pool); + spin_unlock_irqrestore(pch-lock, flags); + break; + case DMA_SLAVE_CONFIG: + slave_config = (struct dma_slave_config *)arg; + + if (slave_config-direction == DMA_TO_DEVICE) { + if (slave_config-dst_addr) + pch-fifo_addr = slave_config-dst_addr; + if (slave_config-dst_addr_width) + pch-burst_sz = __ffs(slave_config-dst_addr_width); + if (slave_config-dst_maxburst) + pch-burst_len = slave_config-dst_maxburst; + } else if (slave_config-direction == DMA_FROM_DEVICE) { + if (slave_config-src_addr) + pch-fifo_addr = slave_config-src_addr; + if (slave_config-src_addr_width) + pch-burst_sz = __ffs(slave_config-src_addr_width); + if (slave_config-src_maxburst) + pch-burst_len = slave_config-src_maxburst; + } + break; + default: + dev_err(pch-dmac-pif.dev, Not supported command.\n); + return -ENXIO; + } return 0; } -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 09/15] ARM: S5PC100: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-s5pc100/Kconfig|2 +- arch/arm/mach-s5pc100/clock.c| 11 +- arch/arm/mach-s5pc100/dma.c | 323 +++-- arch/arm/mach-s5pc100/include/mach/dma.h |2 +- 4 files changed, 222 insertions(+), 116 deletions(-) diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig index e8a33c4..e538a4c 100644 --- a/arch/arm/mach-s5pc100/Kconfig +++ b/arch/arm/mach-s5pc100/Kconfig @@ -10,7 +10,7 @@ if ARCH_S5PC100 config CPU_S5PC100 bool select S5P_EXT_INT - select S3C_PL330_DMA + select SAMSUNG_DMADEV help Enable S5PC100 CPU support diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index ff5cbb3..6527c05 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = { .name = otg_phy, }; +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, @@ -454,13 +459,13 @@ static struct clk init_clocks_off[] = { .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 2), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 1), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, @@ -1276,5 +1281,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(); } diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index bf4cd0f..ef803e9 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5pc100/dma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh jassi.b...@samsung.com * @@ -17,150 +21,245 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h +#include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5pc100_pdma0_resource[] = { - [0] = { - .start = S5PC100_PA_PDMA0, - .end= S5PC100_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[30] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART3_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART3_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = DMACH_IRDA, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S1_TX
[PATCH v7 12/15] spi/s3c64xx: Add support DMA engine API
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Acked-by: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi-s3c64xx.c | 141 ++--- 1 files changed, 69 insertions(+), 72 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 595dacc..24f4903 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -171,6 +171,9 @@ struct s3c64xx_spi_driver_data { unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; + unsignedrx_ch; + unsignedtx_ch; + struct samsung_dma_ops *ops; }; static struct s3c2410_dma_client s3c64xx_spi_dma_client = { @@ -226,6 +229,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) @@ -233,6 +268,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); @@ -258,10 +294,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: @@ -293,10 +333,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, writel(((xfer-len * 8 / sdd-cur_bpw) 0x) | 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); } } @@ -482,46 +526,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
[PATCH v7 15/15] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction
This patch removes the samsung specific enum type 's3c2410_dmasrc' and uses 'dma_data_direction' instead. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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(-) diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index 4e485ba..ae8e482 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 longdev_addr; unsigned longload_timeout; diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 7abecfc..b4fc3ba 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c @@ -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]; diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 204bfaf..67c97fa 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -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(enum dma_ch 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(enum dma_ch 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; diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 74fdf25..fe1a98c 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -99,7 +99,7 @@ struct s3c2410_dma_chan { unsigned charperipheral; unsigned int flags; - enum s3c2410_dmasrc source; + enum dma_data_direction source; dma_addr_t dev_addr; diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 539bd0e..53754bc 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -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(enum dma_ch channel
[PATCH v7 10/15] ARM: S5P64X0: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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 | 273 -- arch/arm/mach-s5p64x0/include/mach/dma.h |2 +- 5 files changed, 201 insertions(+), 96 deletions(-) diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig index 65c7518..9527ed2 100644 --- a/arch/arm/mach-s5p64x0/Kconfig +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -9,14 +9,14 @@ if ARCH_S5P64X0 config CPU_S5P6440 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV select S5P_HRT help Enable S5P6440 CPU support config CPU_S5P6450 bool - select S3C_PL330_DMA + select SAMSUNG_DMADEV select S5P_HRT help Enable S5P6450 CPU support diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index 0e9cd30..c1f548f 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -146,7 +146,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 8), }, { - .name = pdma, + .name = dma, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), @@ -499,6 +499,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; @@ -581,5 +586,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(); } diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index d9dc16c..3d9b609 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -179,7 +179,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 3), }, { - .name = pdma, + .name = dma, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), @@ -553,6 +553,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; @@ -632,5 +637,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(); } diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index d7ad944..aebf3fc 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -21,128 +21,219 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h + +#include asm/irq.h #include mach/map.h #include mach/irqs.h #include mach/regs-clock.h +#include mach/dma.h #include plat/devs.h -#include plat/s3c-pl330-pdata.h +#include plat/irqs.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5p64x0_pdma_resource[] = { - [0] = { - .start = S5P64X0_PA_PDMA, - .end= S5P64X0_PA_PDMA + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_DMA0, - .end= IRQ_DMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri s5p6440_pdma_peri[22] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV
[PATCH v7 13/15] spi/s3c64xx: Merge dma control code
This patch modifies to merge the dma control code. Original s3c64xx spi driver has each dma control code for rx and tx channel. This patch merges these dma control codes into one. With this patch, a dma setup function and callback function handle for both rx and tx channel. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi-s3c64xx.c | 140 1 files changed, 76 insertions(+), 64 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 24f4903..019a716 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -131,6 +131,12 @@ #define RXBUSY(12) #define TXBUSY(13) +struct s3c64xx_spi_dma_data { + unsignedch; + enum dma_data_direction direction; + enum dma_ch dmach; +}; + /** * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. * @clk: Pointer to the spi clock. @@ -164,15 +170,13 @@ struct s3c64xx_spi_driver_data { struct work_struct work; struct list_headqueue; spinlock_t lock; - enum dma_ch rx_dmach; - enum dma_ch tx_dmach; unsigned long sfr_start; struct completion xfer_completion; unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; - unsignedrx_ch; - unsignedtx_ch; + struct s3c64xx_spi_dma_data rx_dma; + struct s3c64xx_spi_dma_data tx_dma; struct samsung_dma_ops *ops; }; @@ -229,36 +233,76 @@ 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) +static void s3c64xx_spi_dmacb(void *data) { - struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; + struct s3c64xx_spi_driver_data *sdd; + struct s3c64xx_spi_dma_data *dma = data; unsigned long flags; + if (dma-direction == DMA_FROM_DEVICE) + sdd = container_of(data, + struct s3c64xx_spi_driver_data, rx_dma); + else + sdd = container_of(data, + struct s3c64xx_spi_driver_data, tx_dma); + spin_lock_irqsave(sdd-lock, flags); - sdd-state = ~RXBUSY; - /* If the other done */ - if (!(sdd-state TXBUSY)) - complete(sdd-xfer_completion); + if (dma-direction == DMA_FROM_DEVICE) { + sdd-state = ~RXBUSY; + if (!(sdd-state TXBUSY)) + complete(sdd-xfer_completion); + } else { + sdd-state = ~TXBUSY; + if (!(sdd-state RXBUSY)) + complete(sdd-xfer_completion); + } spin_unlock_irqrestore(sdd-lock, flags); } -static void s3c64xx_spi_dma_txcb(void *data) +static void prepare_dma(struct s3c64xx_spi_dma_data *dma, + unsigned len, dma_addr_t buf) { - struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; - unsigned long flags; + struct s3c64xx_spi_driver_data *sdd; + struct samsung_dma_prep_info info; - spin_lock_irqsave(sdd-lock, flags); + if (dma-direction == DMA_FROM_DEVICE) + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, rx_dma); + else + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, tx_dma); - sdd-state = ~TXBUSY; - /* If the other done */ - if (!(sdd-state RXBUSY)) - complete(sdd-xfer_completion); + info.cap = DMA_SLAVE; + info.len = len; + info.fp = s3c64xx_spi_dmacb; + info.fp_param = dma; + info.direction = dma-direction; + info.buf = buf; + + sdd-ops-prepare(dma-ch, info); + sdd-ops-trigger(dma-ch); +} - spin_unlock_irqrestore(sdd-lock, flags); +static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) +{ + struct samsung_dma_info info; + + sdd-ops = samsung_dma_get_ops(); + + info.cap = DMA_SLAVE; + info.client = s3c64xx_spi_dma_client; + info.width = sdd-cur_bpw / 8; + + info.direction = sdd-rx_dma.direction; + info.fifo = sdd-sfr_start + S3C64XX_SPI_RX_DATA; + sdd-rx_dma.ch = sdd-ops-request(sdd-rx_dma.dmach, info); + info.direction = sdd-tx_dma.direction; + info.fifo = sdd-sfr_start + S3C64XX_SPI_TX_DATA; + sdd-tx_dma.ch
[PATCH v7 14/15] ASoC: Samsung: Update DMA interface
This patch adds to support the DMA PL330 driver that uses DMA generic API. Samsung sound driver uses DMA generic API if architecture supports it. Otherwise, use samsung specific S3C-PL330 API driver to transfer PCM data. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Jassi Brar jassisinghb...@gmail.com Cc: Liam Girdwood l...@ti.com Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com [kgene@samsung.com: removed useless variable] Signed-off-by: Kukjin Kim kgene@samsung.com --- 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| 146 ++-- sound/soc/samsung/dma.h|4 +- 6 files changed, 78 insertions(+), 96 deletions(-) diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index e61a91f..4e485ba 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 */ diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 49c3a53..74fdf25 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -58,7 +58,7 @@ enum dma_ch { DMACH_MAX /* the end */ }; -static __inline__ bool s3c_dma_has_circular(void) +static inline bool samsung_dma_has_circular(void) { return true; } diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 9a1dadb..2e55e59 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -89,7 +89,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; } diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index f97110e..b4f9b00 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -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; } diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 9465588..851346f 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -54,7 +54,6 @@ struct runtime_data { spinlock_t lock; int state; unsigned int dma_loaded; - unsigned int dma_limit; unsigned int dma_period; dma_addr_t dma_start; dma_addr_t dma_pos; @@ -62,77 +61,79 @@ struct runtime_data { struct s3c_dma_params *params; }; +static void audio_buffdone(void *data); + /* dma_enqueue * * place a dma buffer onto the queue for the dma system * to handle. -*/ + */ static void dma_enqueue(struct snd_pcm_substream *substream) { struct runtime_data *prtd = substream-runtime-private_data; dma_addr_t pos = prtd-dma_pos; unsigned int limit; - int ret; + struct samsung_dma_prep_info dma_info; pr_debug(Entered %s\n, __func__); - if (s3c_dma_has_circular()) - limit = (prtd-dma_end - prtd-dma_start) / prtd-dma_period; - else - limit = prtd-dma_limit; + limit = (prtd-dma_end - prtd-dma_start) / prtd-dma_period; pr_debug(%s: loaded %d, limit %d\n, __func__, prtd-dma_loaded, limit); - while (prtd-dma_loaded limit) { - unsigned long len = prtd-dma_period; + dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); + dma_info.direction = + (substream-stream
[PATCH v7 11/15] ARM: SAMSUNG: Remove S3C-PL330-DMA driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Cc: Jassi Brar jassisinghb...@gmail.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/plat-samsung/Kconfig |6 - arch/arm/plat-samsung/Makefile |2 - arch/arm/plat-samsung/include/plat/dma-pl330.h | 10 +- .../plat-samsung/include/plat/s3c-pl330-pdata.h| 32 - arch/arm/plat-samsung/s3c-pl330.c | 1244 5 files changed, 6 insertions(+), 1288 deletions(-) delete mode 100644 arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h delete mode 100644 arch/arm/plat-samsung/s3c-pl330.c diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index e6f01ab..0a3eec6 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -300,12 +300,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 SAMSUNG_DMADEV bool select DMADEVICES diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index e2ee0b8..9075849 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -67,8 +67,6 @@ obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o -obj-$(CONFIG_S3C_PL330_DMA)+= s3c-pl330.o s3c-dma-ops.o - # PM support obj-$(CONFIG_PM) += pm.o diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 2916920..9a1dadb 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -11,9 +11,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. @@ -88,6 +85,10 @@ enum dma_ch { DMACH_MAX, }; +struct s3c2410_dma_client { + char*name; +}; + static inline bool s3c_dma_has_circular(void) { return true; @@ -97,6 +98,7 @@ static inline bool samsung_dma_is_dmadev(void) { return true; } -#include plat/dma.h + +#include plat/dma-ops.h #endif /* __DMA_PL330_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h deleted file mode 100644 index 64fdf66..000 --- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +++ /dev/null @@ -1,32 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh jassi.b...@samsung.com - * - * 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 */ diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c deleted file mode 100644 index f85638c..000 --- a/arch/arm/plat-samsung/s3c-pl330.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* linux/arch/arm/plat-samsung/s3c-pl330.c - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh jassi.b...@samsung.com - * - * 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. - */ - -#include linux/init.h -#include linux/module.h -#include linux/interrupt.h -#include linux/io.h -#include linux/slab.h -#include linux/platform_device.h -#include linux/clk.h -#include linux/err.h - -#include asm/hardware/pl330.h - -#include plat/s3c-pl330-pdata.h - -/** - * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC. - * @busy_chan: Number of channels currently busy. - * @peri: List of IDs of peripherals this DMAC can work with. - * @node: To attach to the global list of DMACs
RE: [PATCH v6 04/15] DMA: PL330: Add DMA_CYCLIC capability
Jassi Brar [mailto:jassisinghb...@gmail.com] Sent: Tuesday, August 23, 2011 2:42 PM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Kukjin Kim; Dan Williams; Mark Brown; Grant Likely; Russell King Subject: Re: [PATCH v6 04/15] DMA: PL330: Add DMA_CYCLIC capability On Mon, Aug 22, 2011 at 5:33 PM, Boojin Kim boojin@samsung.com wrote: +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); + dma_addr_t dst; + dma_addr_t src; + + 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 = pch-fifo_addr; + break; + case DMA_FROM_DEVICE: + desc-rqcfg.src_inc = 0; + desc-rqcfg.dst_inc = 1; + src = pch-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 = pch-burst_sz; + desc-rqcfg.brst_len = 1; + + if (!pch-cyclic) + pch-cyclic = CYCLIC_PREP; The need for check here seems suspicious. Is it really needed? If not, please remove it. It's required because Cyclic operation is passed from CYCLIC_PREP to CYCLIC_TRIGGER. I don't see why you need to differentiate between PREP and TRIGGER in cyclic mode. I think, you should simply have 'bool cyclic' instead of enum. On cyclic mode, Pl330_tasklet() operation is changed according to the value of 'cyclic'. In case of CYCLIC_PREP, Pl330_tasklet()operation is same with normal operation. In case of CYCLIC_TRIGGER, pl330_tasklet()reloads the done data into work_list. So, 'Cyclic' needs two status(CYCLIC_PREP and CYCLIC_TRIGGER) to distinguish the operation on pl330_tasklet(). The sequence is following. device_prep_dma_cyclic() - set CYCLIC_PREP - device_issue_pending() - Pl330_tasklet() with CYCLIC_PREP - set CYCLIC_TRIGGER - PL330 IRQ - Pl330_tasklet() with CYCLIC_TRIGGER. Thanks Boojin -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v6 04/15] DMA: PL330: Add DMA_CYCLIC capability
Jassi Brar wrote: On Tue, Aug 23, 2011 at 12:38 PM, Boojin Kim boojin@samsung.com wrote: Jassi Brar [mailto:jassisinghb...@gmail.com] Sent: Tuesday, August 23, 2011 2:42 PM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Kukjin Kim; Dan Williams; Mark Brown; Grant Likely; Russell King Subject: Re: [PATCH v6 04/15] DMA: PL330: Add DMA_CYCLIC capability On Mon, Aug 22, 2011 at 5:33 PM, Boojin Kim boojin@samsung.com wrote: +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); + dma_addr_t dst; + dma_addr_t src; + + 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 = pch-fifo_addr; + break; + case DMA_FROM_DEVICE: + desc-rqcfg.src_inc = 0; + desc-rqcfg.dst_inc = 1; + src = pch-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 = pch-burst_sz; + desc-rqcfg.brst_len = 1; + + if (!pch-cyclic) + pch-cyclic = CYCLIC_PREP; The need for check here seems suspicious. Is it really needed? If not, please remove it. It's required because Cyclic operation is passed from CYCLIC_PREP to CYCLIC_TRIGGER. I don't see why you need to differentiate between PREP and TRIGGER in cyclic mode. I think, you should simply have 'bool cyclic' instead of enum. On cyclic mode, Pl330_tasklet() operation is changed according to the value of 'cyclic'. In case of CYCLIC_PREP, Pl330_tasklet()operation is same with normal operation. By 'normal' you mean non-cyclic, right? That doesn't seem correct to do. Once the desc has been marked cyclic by device_prep_dma_cyclic(), you shouldn't treat it like a non-cyclic anymore. The sequence is following. device_prep_dma_cyclic() - set CYCLIC_PREP - device_issue_pending() - Pl330_tasklet() with CYCLIC_PREP - set CYCLIC_TRIGGER - PL330 IRQ - Pl330_tasklet() with CYCLIC_TRIGGER. device_issue_pending() -Pl330_tasklet() with CYCLIC_PREP is no different from device_issue_pending() -Pl330_tasklet() with CYCLIC_TRIGGER because the list of 'done' xfers would be null yet. Okay, You're right. CYCLIC_PREP is a redundancy status. I will address your comment. Thanks Boojin Kim -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/3] DMA: PL330: Infer transfer direction from transfer request instead of platform data
Thomas Abraham wrote: Sent: Tuesday, August 23, 2011 7:00 AM To: linux-arm-ker...@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org; kgene@samsung.com; vinod.k...@intel.com; Jassi Brar; Boojin Kim Subject: [PATCH 1/3] DMA: PL330: Infer transfer direction from transfer request instead of platform data The transfer direction for a channel can be inferred from the transfer request and the need for specifying transfer direction in platfrom data can be eliminated. So the structure definition 'struct dma_pl330_peri' is no longer required. With the 'struct dma_pl330_peri' removed, the dma controller transfer capabilities cannot be inferred any longer. Hence, the dma controller capabilities is specified using platforme data. Cc: Jassi Brar jassisinghb...@gmail.com Cc: Boojin Kim boojin@samsung.com Signed-off-by: Thomas Abraham thomas.abra...@linaro.org --- drivers/dma/pl330.c| 56 -- -- include/linux/amba/pl330.h | 14 +++ 2 files changed, 14 insertions(+), 56 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 3a0baac..6592b9a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -507,7 +507,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac) static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) { struct dma_pl330_dmac *pdmac = pch-dmac; - struct dma_pl330_peri *peri = pch-chan.private; + u8 *peri_id = pch-chan.private; struct dma_pl330_desc *desc; /* Pluck one desc from the pool of DMAC */ @@ -531,14 +531,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) desc-pchan = pch; desc-txd.cookie = 0; async_tx_ack(desc-txd); - - if (peri) { - desc-req.rqtype = peri-rqtype; - desc-req.peri = pch-chan.chan_id; - } else { - desc-req.rqtype = MEMTOMEM; - desc-req.peri = 0; - } + desc-req.peri = (peri_id) ? pch-chan.chan_id : 0; dma_async_tx_descriptor_init(desc-txd, pch-chan); @@ -625,12 +618,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( case DMA_TO_DEVICE: desc-rqcfg.src_inc = 1; desc-rqcfg.dst_inc = 0; + desc-req.rqtype = MEMTODEV; src = dma_addr; dst = pch-fifo_addr; break; case DMA_FROM_DEVICE: desc-rqcfg.src_inc = 0; desc-rqcfg.dst_inc = 1; + desc-req.rqtype = DEVTOMEM; src = pch-fifo_addr; dst = dma_addr; break; @@ -657,16 +652,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, { struct dma_pl330_desc *desc; struct dma_pl330_chan *pch = to_pchan(chan); - struct dma_pl330_peri *peri = chan-private; struct pl330_info *pi; int burst; if (unlikely(!pch || !len)) return NULL; - if (peri peri-rqtype != MEMTOMEM) - return NULL; - pi = pch-dmac-pif; desc = __pl330_prep_dma_memcpy(pch, dst, src, len); @@ -675,6 +666,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, desc-rqcfg.src_inc = 1; desc-rqcfg.dst_inc = 1; + desc-req.rqtype = MEMTOMEM; /* Select max possible burst size */ burst = pi-pcfg.data_bus_width / 8; @@ -703,25 +695,14 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, { struct dma_pl330_desc *first, *desc = NULL; struct dma_pl330_chan *pch = to_pchan(chan); - struct dma_pl330_peri *peri = chan-private; struct scatterlist *sg; unsigned long flags; int i; dma_addr_t addr; - if (unlikely(!pch || !sgl || !sg_len || !peri)) + if (unlikely(!pch || !sgl || !sg_len)) return NULL; - /* Make sure the direction is consistent */ - if ((direction == DMA_TO_DEVICE - peri-rqtype != MEMTODEV) || - (direction == DMA_FROM_DEVICE - peri-rqtype != DEVTOMEM)) { - dev_err(pch-dmac-pif.dev, %s:%d Invalid Direction\n, - __func__, __LINE__); - return NULL; - } - addr = pch-fifo_addr; first = NULL; @@ -761,11 +742,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (direction == DMA_TO_DEVICE) { desc-rqcfg.src_inc = 1; desc-rqcfg.dst_inc = 0; + desc-req.rqtype = MEMTODEV; fill_px(desc-px, addr, sg_dma_address(sg), sg_dma_len(sg)); } else { desc-rqcfg.src_inc = 0; desc-rqcfg.dst_inc = 1; + desc-req.rqtype = DEVTOMEM; fill_px(desc
RE: [PATCH v6 03/15] DMA: PL330: Support DMA_SLAVE_CONFIG command
Jassi Brar wrote: Sent: Monday, August 22, 2011 7:14 PM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Kukjin Kim; Dan Williams; Mark Brown; Grant Likely; Russell King Subject: Re: [PATCH v6 03/15] DMA: PL330: Support DMA_SLAVE_CONFIG command On Fri, Aug 19, 2011 at 2:24 PM, Boojin Kim boojin@samsung.com wrote: Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 56 ++--- - 1 files changed, 42 insertions(+), 14 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index d5829c7..59943ec 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -73,6 +73,7 @@ struct dma_pl330_chan { /* For D-to-M and M-to-D channels */ int burst_sz; /* the peripheral fifo width */ + int burst_len; /* the number of burst */ dma_addr_t fifo_addr; }; @@ -261,25 +262,52 @@ 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; + LIST_HEAD(list); - /* Only supports DMA_TERMINATE_ALL */ - if (cmd != DMA_TERMINATE_ALL) - return -ENXIO; - - spin_lock_irqsave(pch-lock, flags); - - /* FLUSH the PL330 Channel thread */ - pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); + switch (cmd) { + case DMA_TERMINATE_ALL: + spin_lock_irqsave(pch-lock, flags); - /* Mark all desc done */ - list_for_each_entry(desc, pch-work_list, node) - desc-status = DONE; + /* FLUSH the PL330 Channel thread */ + pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); - spin_unlock_irqrestore(pch-lock, flags); + /* Mark all desc done */ + list_for_each_entry_safe(desc, _dt, pch-work_list , node) { + desc-status = DONE; + pch-completed = desc-txd.cookie; + list_move_tail(desc-node, list); + } - pl330_tasklet((unsigned long) pch); + list_splice_tail_init(list, pdmac-desc_pool); + spin_unlock_irqrestore(pch-lock, flags); + break; + case DMA_SLAVE_CONFIG: + slave_config = (struct dma_slave_config *)arg; + + if (slave_config-direction == DMA_TO_DEVICE) { + if (slave_config-dst_addr) + pch-fifo_addr = slave_config-dst_addr; + if (slave_config-dst_addr_width) + pch-burst_sz = __ffs(slave_config- dst_addr_width); + if (slave_config-dst_maxburst) + pch-burst_len = slave_config- dst_maxburst; + } else if (slave_config-direction == DMA_FROM_DEVICE) { + if (slave_config-src_addr) + pch-fifo_addr = slave_config-src_addr; + if (slave_config-src_addr_width) + pch-burst_sz = __ffs(slave_config- src_addr_width); + if (slave_config-src_maxburst) + pch-burst_len = slave_config- src_maxburst; + } + break; + default: + dev_err(pch-dmac-pif.dev, Not supported command.\n); + return -ENXIO; + } Apart from the alleged purpose Support DMA_SLAVE_CONFIG command this patch also modifies the behavior of DMA_TERMINATE_ALL. If the change is intended, please split it into two patches and explain the reason. Otherwise, restore the behavior. I will address your comment. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v6 04/15] DMA: PL330: Add DMA_CYCLIC capability
Jassi Brar wrote: @@ -324,6 +362,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan) pl330_release_channel(pch-pl330_chid); pch-pl330_chid = NULL; + if (pch-cyclic) + list_splice_tail_init(pch-work_list, pch-dmac- desc_pool); 'cyclic' member is 'enum cyclic_mode', please observe the rule and compare it only against the enum values. I will address your comment. +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); + dma_addr_t dst; + dma_addr_t src; + + 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 = pch-fifo_addr; + break; + case DMA_FROM_DEVICE: + desc-rqcfg.src_inc = 0; + desc-rqcfg.dst_inc = 1; + src = pch-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 = pch-burst_sz; + desc-rqcfg.brst_len = 1; + + if (!pch-cyclic) + pch-cyclic = CYCLIC_PREP; The need for check here seems suspicious. Is it really needed? If not, please remove it. It's required because Cyclic operation is passed from CYCLIC_PREP to CYCLIC_TRIGGER. Thanks Boojin -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 03/15] DMA: PL330: Support DMA_SLAVE_CONFIG command
Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 56 ++ 1 files changed, 42 insertions(+), 14 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index d5829c7..59943ec 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -73,6 +73,7 @@ struct dma_pl330_chan { /* For D-to-M and M-to-D channels */ int burst_sz; /* the peripheral fifo width */ + int burst_len; /* the number of burst */ dma_addr_t fifo_addr; }; @@ -261,25 +262,52 @@ 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; + LIST_HEAD(list); - /* Only supports DMA_TERMINATE_ALL */ - if (cmd != DMA_TERMINATE_ALL) - return -ENXIO; - - spin_lock_irqsave(pch-lock, flags); - - /* FLUSH the PL330 Channel thread */ - pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); + switch (cmd) { + case DMA_TERMINATE_ALL: + spin_lock_irqsave(pch-lock, flags); - /* Mark all desc done */ - list_for_each_entry(desc, pch-work_list, node) - desc-status = DONE; + /* FLUSH the PL330 Channel thread */ + pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); - spin_unlock_irqrestore(pch-lock, flags); + /* Mark all desc done */ + list_for_each_entry_safe(desc, _dt, pch-work_list , node) { + desc-status = DONE; + pch-completed = desc-txd.cookie; + list_move_tail(desc-node, list); + } - pl330_tasklet((unsigned long) pch); + list_splice_tail_init(list, pdmac-desc_pool); + spin_unlock_irqrestore(pch-lock, flags); + break; + case DMA_SLAVE_CONFIG: + slave_config = (struct dma_slave_config *)arg; + + if (slave_config-direction == DMA_TO_DEVICE) { + if (slave_config-dst_addr) + pch-fifo_addr = slave_config-dst_addr; + if (slave_config-dst_addr_width) + pch-burst_sz = __ffs(slave_config-dst_addr_width); + if (slave_config-dst_maxburst) + pch-burst_len = slave_config-dst_maxburst; + } else if (slave_config-direction == DMA_FROM_DEVICE) { + if (slave_config-src_addr) + pch-fifo_addr = slave_config-src_addr; + if (slave_config-src_addr_width) + pch-burst_sz = __ffs(slave_config-src_addr_width); + if (slave_config-src_maxburst) + pch-burst_len = slave_config-src_maxburst; + } + break; + default: + dev_err(pch-dmac-pif.dev, Not supported command.\n); + return -ENXIO; + } return 0; } -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 02/15] 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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/Kconfig|3 ++- drivers/dma/pl330.c| 14 +- include/linux/amba/pl330.h |6 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 2e3b3d3..ab8f469 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL config PL330_DMA tristate DMA API Driver for PL330 select DMA_ENGINE - depends on PL330 + 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 diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0b99af1..d5829c7 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -18,6 +18,7 @@ #include linux/amba/bus.h #include linux/amba/pl330.h #include linux/pm_runtime.h +#include linux/scatterlist.h #define NR_DEFAULT_DESC16 @@ -69,6 +70,10 @@ struct dma_pl330_chan { * NULL if the channel is available to be acquired. */ void *pl330_chid; + + /* For D-to-M and M-to-D channels */ + int burst_sz; /* the peripheral fifo width */ + dma_addr_t fifo_addr; }; struct dma_pl330_dmac { @@ -456,7 +461,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) if (peri) { desc-req.rqtype = peri-rqtype; - desc-req.peri = peri-peri_id; + desc-req.peri = pch-chan.chan_id; } else { desc-req.rqtype = MEMTOMEM; desc-req.peri = 0; @@ -582,7 +587,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 || !peri)) @@ -598,8 +603,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } - addr = peri-fifo_addr; - burst_size = peri-burst_sz; + addr = pch-fifo_addr; first = NULL; @@ -647,7 +651,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 = pch-burst_sz; desc-rqcfg.brst_len = 1; } diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h index cbee7de..d12f077 100644 --- a/include/linux/amba/pl330.h +++ b/include/linux/amba/pl330.h @@ -19,12 +19,8 @@ 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 */ - int burst_sz; /* in power of 2 */ - dma_addr_t fifo_addr; }; struct dma_pl330_platdata { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 05/15] ARM: SAMSUNG: Update to use PL330-DMA driver
This patch adds to support PL330-DMA driver on DMADEVICE for S5P SoCs. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-exynos4/include/mach/dma.h |4 ++-- arch/arm/mach-s5p64x0/include/mach/dma.h |2 +- arch/arm/mach-s5pc100/include/mach/dma.h |2 +- arch/arm/mach-s5pv210/include/mach/dma.h |2 +- arch/arm/plat-samsung/Kconfig |8 .../include/plat/{s3c-dma-pl330.h = dma-pl330.h} |8 .../plat-samsung/include/plat/s3c-pl330-pdata.h|2 +- 7 files changed, 18 insertions(+), 10 deletions(-) rename arch/arm/plat-samsung/include/plat/{s3c-dma-pl330.h = dma-pl330.h} (93%) diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos4/include/mach/dma.h index 81209eb..201842a 100644 --- a/arch/arm/mach-exynos4/include/mach/dma.h +++ b/arch/arm/mach-exynos4/include/mach/dma.h @@ -20,7 +20,7 @@ #ifndef __MACH_DMA_H #define __MACH_DMA_H -/* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +/* This platform uses the common DMA API driver for PL330 */ +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h index 81209eb..1beae2c 100644 --- a/arch/arm/mach-s5p64x0/include/mach/dma.h +++ b/arch/arm/mach-s5p64x0/include/mach/dma.h @@ -21,6 +21,6 @@ #define __MACH_DMA_H /* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5pc100/include/mach/dma.h b/arch/arm/mach-s5pc100/include/mach/dma.h index 81209eb..1beae2c 100644 --- a/arch/arm/mach-s5pc100/include/mach/dma.h +++ b/arch/arm/mach-s5pc100/include/mach/dma.h @@ -21,6 +21,6 @@ #define __MACH_DMA_H /* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h index 81209eb..1beae2c 100644 --- a/arch/arm/mach-s5pv210/include/mach/dma.h +++ b/arch/arm/mach-s5pv210/include/mach/dma.h @@ -21,6 +21,6 @@ #define __MACH_DMA_H /* This platform uses the common S3C DMA API driver for PL330 */ -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h #endif /* __MACH_DMA_H */ diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index b3e1065..d38cef4 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -306,6 +306,14 @@ config S3C_PL330_DMA help S3C DMA API Driver for PL330 DMAC. +config SAMSUNG_DMA_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 diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h similarity index 93% 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..0a5dade 100644 --- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -8,8 +8,8 @@ * (at your option) any later version. */ -#ifndef__S3C_DMA_PL330_H_ -#define__S3C_DMA_PL330_H_ +#ifndef __DMA_PL330_H_ +#define __DMA_PL330_H_ __FILE__ #define S3C2410_DMAF_AUTOSTART (1 0) #define S3C2410_DMAF_CIRCULAR (1 1) @@ -20,7 +20,7 @@ * 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 { @@ -95,4 +95,4 @@ static inline bool s3c_dma_has_circular(void) #include plat/dma.h -#endif /* __S3C_DMA_PL330_H_ */ +#endif /* __DMA_PL330_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h index bf5e2a9..64fdf66 100644 --- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h @@ -12,7 +12,7 @@ #ifndef __S3C_PL330_PDATA_H #define __S3C_PL330_PDATA_H -#include plat/s3c-dma-pl330.h +#include plat/dma-pl330.h /* * Every PL330 DMAC has max 32 peripheral interfaces, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC
Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Jassi Brar jassisinghb...@gmail.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 75 +- 1 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 00eee59..0b99af1 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -17,6 +17,7 @@ #include linux/interrupt.h #include linux/amba/bus.h #include linux/amba/pl330.h +#include linux/pm_runtime.h #define NR_DEFAULT_DESC16 @@ -83,6 +84,8 @@ struct dma_pl330_dmac { /* Peripheral channels connected to this DMAC */ struct dma_pl330_chan *peripherals; /* keep at end */ + + struct clk *clk; }; struct dma_pl330_desc { @@ -696,6 +699,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); @@ -771,8 +798,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, @@ -833,6 +858,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; @@ -846,10 +878,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, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 07/15] ARM: EXYNOS4: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-exynos4/Kconfig |2 +- arch/arm/mach-exynos4/clock.c | 11 ++- arch/arm/mach-exynos4/dma.c | 299 ++--- 3 files changed, 198 insertions(+), 114 deletions(-) diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index 0c77ab9..c5de830 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -11,7 +11,7 @@ if ARCH_EXYNOS4 config CPU_EXYNOS4210 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 help Enable EXYNOS4210 CPU support diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index 851dea0..fee2dd8 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -43,6 +43,11 @@ static struct clk clk_sclk_usbphy1 = { .name = sclk_usbphy1, }; +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); @@ -454,12 +459,12 @@ static struct clk init_clocks_off[] = { .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 10), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 0), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 1), @@ -1210,5 +1215,7 @@ void __init exynos4_register_clocks(void) s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c24xx_register_clock(dummy_apb_pclk); + s3c_pwmclk_init(); } diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c index 564bb53..d57d662 100644 --- a/arch/arm/mach-exynos4/dma.c +++ b/arch/arm/mach-exynos4/dma.c @@ -21,151 +21,228 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h #include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource exynos4_pdma0_resource[] = { - [0] = { - .start = EXYNOS4_PA_PDMA0, - .end= EXYNOS4_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[28] = { + { + .peri_id = (u8)DMACH_PCM0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_PCM0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_PCM2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_PCM2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_MSM_REQ0, + }, { + .peri_id = (u8)DMACH_MSM_REQ2, + }, { + .peri_id = (u8)DMACH_SPI0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_SPI0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_SPI2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_SPI2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART4_RX
[PATCH v6 06/15] ARM: SAMSUNG: Add common DMA operations
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(). Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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| 131 +++ arch/arm/plat-samsung/include/plat/dma-ops.h | 63 +++ arch/arm/plat-samsung/include/plat/dma-pl330.h |4 + arch/arm/plat-samsung/include/plat/dma.h |1 + arch/arm/plat-samsung/s3c-dma-ops.c| 133 8 files changed, 347 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 diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index b2b2a5b..e61a91f 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 0x10 /* 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(128) /* use this to specifiy hardware ch no */ /* we have 4 dma channels */ diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 0a5d926..49c3a53 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -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 diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 853764b..11dd766 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -63,9 +63,11 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.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_SAMSUNG_DMA_PL330)+= dma-ops.o + +obj-$(CONFIG_S3C_PL330_DMA)+= s3c-pl330.o s3c-dma-ops.o # PM support diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c new file mode 100644 index 000..6e3d9ab --- /dev/null +++ b/arch/arm/plat-samsung/dma-ops.c @@ -0,0 +1,131 @@ +/* linux/arch/arm/plat-samsung/dma-ops.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung DMA Operations + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/amba/pl330.h +#include linux/scatterlist.h + +#include mach/dma.h + +static inline bool pl330_filter(struct dma_chan *chan, void *param) +{ + struct dma_pl330_peri *peri = chan-private; + return peri-peri_id == (unsigned)param; +} + +static unsigned samsung_dmadev_request(enum dma_ch dma_ch, + struct samsung_dma_info *info) +{ + struct dma_chan *chan; + dma_cap_mask_t mask; + struct dma_slave_config slave_config; + + dma_cap_zero(mask); + dma_cap_set(info-cap, mask); + + chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); + + if (info-direction == DMA_FROM_DEVICE) { + memset(slave_config, 0, sizeof(struct dma_slave_config)); + slave_config.direction = info-direction; + slave_config.src_addr = info-fifo; + slave_config.src_addr_width = info-width; + slave_config.src_maxburst = 1; + dmaengine_slave_config(chan, slave_config); + } else if (info-direction == DMA_TO_DEVICE
[PATCH v6 08/15] ARM: S5PV210: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-s5pv210/Kconfig|2 +- arch/arm/mach-s5pv210/clock.c| 10 +- arch/arm/mach-s5pv210/dma.c | 316 +++--- arch/arm/mach-s5pv210/include/mach/dma.h |2 +- 4 files changed, 214 insertions(+), 116 deletions(-) diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 69dd87c..fd4a433 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -11,7 +11,7 @@ if ARCH_S5PV210 config CPU_S5PV210 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_EXT_INT select S5P_HRT select S5PV210_PM if PM diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 52a8e60..d35726a 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -203,6 +203,11 @@ static struct clk clk_pcmcdclk2 = { .name = pcmcdclk, }; +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, @@ -289,13 +294,13 @@ static struct clk_ops clk_fout_apll_ops = { static struct clk init_clocks_off[] = { { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit= (1 3), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, @@ -1161,5 +1166,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(); } diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index 497d343..f79d0b0 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5pv210/dma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh jassi.b...@samsung.com * @@ -17,151 +21,239 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h #include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5pv210_pdma0_resource[] = { - [0] = { - .start = S5PV210_PA_PDMA0, - .end= S5PV210_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[28] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART3_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART3_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = DMACH_MAX, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S1_TX, + .rqtype = MEMTODEV
[PATCH v6 09/15] ARM: S5PC100: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-s5pc100/Kconfig|2 +- arch/arm/mach-s5pc100/clock.c| 11 +- arch/arm/mach-s5pc100/dma.c | 323 +++-- arch/arm/mach-s5pc100/include/mach/dma.h |2 +- 4 files changed, 222 insertions(+), 116 deletions(-) diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig index e8a33c4..80471a0 100644 --- a/arch/arm/mach-s5pc100/Kconfig +++ b/arch/arm/mach-s5pc100/Kconfig @@ -10,7 +10,7 @@ if ARCH_S5PC100 config CPU_S5PC100 bool select S5P_EXT_INT - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 help Enable S5PC100 CPU support diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index ff5cbb3..6527c05 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = { .name = otg_phy, }; +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, @@ -454,13 +459,13 @@ static struct clk init_clocks_off[] = { .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 2), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.1, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 1), }, { - .name = pdma, + .name = dma, .devname= s3c-pl330.0, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, @@ -1276,5 +1281,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(); } diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index bf4cd0f..ef803e9 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5pc100/dma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh jassi.b...@samsung.com * @@ -17,150 +21,245 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h +#include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5pc100_pdma0_resource[] = { - [0] = { - .start = S5PC100_PA_PDMA0, - .end= S5PC100_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[30] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART3_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART3_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = DMACH_IRDA, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S1_TX
[PATCH v6 15/15] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction
This patch removes the samsung specific enum type 's3c2410_dmasrc' and uses 'dma_data_direction' instead. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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(-) diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index 4e485ba..ae8e482 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 longdev_addr; unsigned longload_timeout; diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 7abecfc..b4fc3ba 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c @@ -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]; diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 204bfaf..67c97fa 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -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(enum dma_ch 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(enum dma_ch 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; diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 74fdf25..fe1a98c 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -99,7 +99,7 @@ struct s3c2410_dma_chan { unsigned charperipheral; unsigned int flags; - enum s3c2410_dmasrc source; + enum dma_data_direction source; dma_addr_t dev_addr; diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 539bd0e..240233a 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -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(enum dma_ch channel
[PATCH v6 12/15] spi/s3c64xx: Add support DMA engine API
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Acked-by: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi-s3c64xx.c | 141 ++--- 1 files changed, 69 insertions(+), 72 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 595dacc..24f4903 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -171,6 +171,9 @@ struct s3c64xx_spi_driver_data { unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; + unsignedrx_ch; + unsignedtx_ch; + struct samsung_dma_ops *ops; }; static struct s3c2410_dma_client s3c64xx_spi_dma_client = { @@ -226,6 +229,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) @@ -233,6 +268,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); @@ -258,10 +294,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: @@ -293,10 +333,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, writel(((xfer-len * 8 / sdd-cur_bpw) 0x) | 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); } } @@ -482,46 +526,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
[PATCH v6 13/15] spi/s3c64xx: Merge dma control code
This patch modifies to merge the dma control code. Original s3c64xx spi driver has each dma control code for rx and tx channel. This patch merges these dma control codes into one. With this patch, a dma setup function and callback function handle for both rx and tx channel. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi-s3c64xx.c | 140 1 files changed, 76 insertions(+), 64 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 24f4903..019a716 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -131,6 +131,12 @@ #define RXBUSY(12) #define TXBUSY(13) +struct s3c64xx_spi_dma_data { + unsignedch; + enum dma_data_direction direction; + enum dma_ch dmach; +}; + /** * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. * @clk: Pointer to the spi clock. @@ -164,15 +170,13 @@ struct s3c64xx_spi_driver_data { struct work_struct work; struct list_headqueue; spinlock_t lock; - enum dma_ch rx_dmach; - enum dma_ch tx_dmach; unsigned long sfr_start; struct completion xfer_completion; unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; - unsignedrx_ch; - unsignedtx_ch; + struct s3c64xx_spi_dma_data rx_dma; + struct s3c64xx_spi_dma_data tx_dma; struct samsung_dma_ops *ops; }; @@ -229,36 +233,76 @@ 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) +static void s3c64xx_spi_dmacb(void *data) { - struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; + struct s3c64xx_spi_driver_data *sdd; + struct s3c64xx_spi_dma_data *dma = data; unsigned long flags; + if (dma-direction == DMA_FROM_DEVICE) + sdd = container_of(data, + struct s3c64xx_spi_driver_data, rx_dma); + else + sdd = container_of(data, + struct s3c64xx_spi_driver_data, tx_dma); + spin_lock_irqsave(sdd-lock, flags); - sdd-state = ~RXBUSY; - /* If the other done */ - if (!(sdd-state TXBUSY)) - complete(sdd-xfer_completion); + if (dma-direction == DMA_FROM_DEVICE) { + sdd-state = ~RXBUSY; + if (!(sdd-state TXBUSY)) + complete(sdd-xfer_completion); + } else { + sdd-state = ~TXBUSY; + if (!(sdd-state RXBUSY)) + complete(sdd-xfer_completion); + } spin_unlock_irqrestore(sdd-lock, flags); } -static void s3c64xx_spi_dma_txcb(void *data) +static void prepare_dma(struct s3c64xx_spi_dma_data *dma, + unsigned len, dma_addr_t buf) { - struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; - unsigned long flags; + struct s3c64xx_spi_driver_data *sdd; + struct samsung_dma_prep_info info; - spin_lock_irqsave(sdd-lock, flags); + if (dma-direction == DMA_FROM_DEVICE) + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, rx_dma); + else + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, tx_dma); - sdd-state = ~TXBUSY; - /* If the other done */ - if (!(sdd-state RXBUSY)) - complete(sdd-xfer_completion); + info.cap = DMA_SLAVE; + info.len = len; + info.fp = s3c64xx_spi_dmacb; + info.fp_param = dma; + info.direction = dma-direction; + info.buf = buf; + + sdd-ops-prepare(dma-ch, info); + sdd-ops-trigger(dma-ch); +} - spin_unlock_irqrestore(sdd-lock, flags); +static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) +{ + struct samsung_dma_info info; + + sdd-ops = samsung_dma_get_ops(); + + info.cap = DMA_SLAVE; + info.client = s3c64xx_spi_dma_client; + info.width = sdd-cur_bpw / 8; + + info.direction = sdd-rx_dma.direction; + info.fifo = sdd-sfr_start + S3C64XX_SPI_RX_DATA; + sdd-rx_dma.ch = sdd-ops-request(sdd-rx_dma.dmach, info); + info.direction = sdd-tx_dma.direction; + info.fifo = sdd-sfr_start + S3C64XX_SPI_TX_DATA; + sdd-tx_dma.ch
[PATCH v6 10/15] ARM: S5P64X0: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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 | 273 -- arch/arm/mach-s5p64x0/include/mach/dma.h |2 +- 5 files changed, 201 insertions(+), 96 deletions(-) diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig index 65c7518..d9b6540 100644 --- a/arch/arm/mach-s5p64x0/Kconfig +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -9,14 +9,14 @@ if ARCH_S5P64X0 config CPU_S5P6440 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_HRT help Enable S5P6440 CPU support config CPU_S5P6450 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_HRT help Enable S5P6450 CPU support diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index 0e9cd30..c1f548f 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -146,7 +146,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 8), }, { - .name = pdma, + .name = dma, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), @@ -499,6 +499,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; @@ -581,5 +586,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(); } diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index d9dc16c..3d9b609 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -179,7 +179,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 3), }, { - .name = pdma, + .name = dma, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), @@ -553,6 +553,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; @@ -632,5 +637,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(); } diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index d7ad944..aebf3fc 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -21,128 +21,219 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h + +#include asm/irq.h #include mach/map.h #include mach/irqs.h #include mach/regs-clock.h +#include mach/dma.h #include plat/devs.h -#include plat/s3c-pl330-pdata.h +#include plat/irqs.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5p64x0_pdma_resource[] = { - [0] = { - .start = S5P64X0_PA_PDMA, - .end= S5P64X0_PA_PDMA + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_DMA0, - .end= IRQ_DMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri s5p6440_pdma_peri[22] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype
[PATCH v6 14/15] ASoC: Samsung: Update DMA interface
This patch adds to support the DMA PL330 driver that uses DMA generic API. Samsung sound driver uses DMA generic API if architecture supports it. Otherwise, use samsung specific S3C-PL330 API driver to transfer PCM data. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Vinod Koul vinod.k...@intel.com Cc: Jassi Brar jassisinghb...@gmail.com Cc: Liam Girdwood l...@ti.com Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com [kgene@samsung.com: removed useless variable] Signed-off-by: Kukjin Kim kgene@samsung.com --- 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| 146 ++-- sound/soc/samsung/dma.h|4 +- 6 files changed, 78 insertions(+), 96 deletions(-) diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index e61a91f..4e485ba 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -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 */ diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 49c3a53..74fdf25 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -58,7 +58,7 @@ enum dma_ch { DMACH_MAX /* the end */ }; -static __inline__ bool s3c_dma_has_circular(void) +static inline bool samsung_dma_has_circular(void) { return true; } diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 9a1dadb..2e55e59 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -89,7 +89,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; } diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index f97110e..b4f9b00 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -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; } diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 9465588..851346f 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -54,7 +54,6 @@ struct runtime_data { spinlock_t lock; int state; unsigned int dma_loaded; - unsigned int dma_limit; unsigned int dma_period; dma_addr_t dma_start; dma_addr_t dma_pos; @@ -62,77 +61,79 @@ struct runtime_data { struct s3c_dma_params *params; }; +static void audio_buffdone(void *data); + /* dma_enqueue * * place a dma buffer onto the queue for the dma system * to handle. -*/ + */ static void dma_enqueue(struct snd_pcm_substream *substream) { struct runtime_data *prtd = substream-runtime-private_data; dma_addr_t pos = prtd-dma_pos; unsigned int limit; - int ret; + struct samsung_dma_prep_info dma_info; pr_debug(Entered %s\n, __func__); - if (s3c_dma_has_circular()) - limit = (prtd-dma_end - prtd-dma_start) / prtd-dma_period; - else - limit = prtd-dma_limit; + limit = (prtd-dma_end - prtd-dma_start) / prtd-dma_period; pr_debug(%s: loaded %d, limit %d\n, __func__, prtd-dma_loaded, limit); - while (prtd-dma_loaded limit) { - unsigned long len = prtd-dma_period; + dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); + dma_info.direction = + (substream-stream
[PATCH] ARM: S5P64X0: Add the devname for DMA clock
This patch adds devname for DMA clock. NOTE: This patch should be added after merging new pl330 driver on dmaengine. Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/mach-s5p64x0/clock-s5p6440.c |1 + arch/arm/mach-s5p64x0/clock-s5p6450.c |1 + 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index c1f548f..c54c65d 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -147,6 +147,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 8), }, { .name = dma, + .devname= dma-pl330, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 3d9b609..2d04abf 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -180,6 +180,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 3), }, { .name = dma, + .devname= dma-pl330, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] ARM: SAMSUNG: Modify the devname for pl330 clock
Vladimir Zapolskiy wrote: Hi, looks like it contains my series as a subset. As I replied on your patches, yes, I know that. I sent it before see your patch. Do you add the missing about s5p64x0 in your patch? If not, I will split up this patch to get missing about s5p64x0 in your patch. Thanks Boojin Kim. -- With best wishes, Vladimir On 17.08.2011 03:26, Boojin Kim wrote: This patch modified the devname for pl330 clock from 's3c-pl330' to 'dma-pl330' to support new pl330 driver on dmaengine. NOTE: This patch sould be added after merging new pl330 driver on dmaengine. Signed-off-by: Boojin Kimboojin@samsung.com --- arch/arm/mach-exynos4/clock.c |4 ++-- arch/arm/mach-s5p64x0/clock-s5p6440.c |1 + arch/arm/mach-s5p64x0/clock-s5p6450.c |1 + arch/arm/mach-s5pc100/clock.c |4 ++-- arch/arm/mach-s5pv210/clock.c |4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach- exynos4/clock.c index fee2dd8..04c997a 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -460,12 +460,12 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 10), }, { .name = dma, - .devname= s3c-pl330.0, + .devname= dma-pl330.0, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 0), }, { .name = dma, - .devname= s3c-pl330.1, + .devname= dma-pl330.1, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 1), }, { diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach- s5p64x0/clock-s5p6440.c index c1f548f..c54c65d 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -147,6 +147,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 8), }, { .name = dma, + .devname= dma-pl330, .parent =clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach- s5p64x0/clock-s5p6450.c index 3d9b609..2d04abf 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -180,6 +180,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 3), }, { .name = dma, + .devname= dma-pl330, .parent =clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach- s5pc100/clock.c index 6527c05..8d47709 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -460,13 +460,13 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 2), }, { .name = dma, - .devname= s3c-pl330.1, + .devname= dma-pl330.1, .parent =clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 1), }, { .name = dma, - .devname= s3c-pl330.0, + .devname= dma-pl330.0, .parent =clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 0), diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach- s5pv210/clock.c index d35726a..239aaad 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -295,13 +295,13 @@ static struct clk_ops clk_fout_apll_ops = { static struct clk init_clocks_off[] = { { .name = dma, - .devname= s3c-pl330.0, + .devname= dma-pl330.0, .parent =clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit= (1 3), }, { .name = dma, - .devname= s3c-pl330.1, + .devname= dma-pl330.1, .parent =clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit= (1 4), -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: SAMSUNG: Modify the devname for pl330 clock
This patch modified the devname for pl330 clock from 's3c-pl330' to 'dma-pl330' to support new pl330 driver on dmaengine. NOTE: This patch sould be added after merging new pl330 driver on dmaengine. Signed-off-by: Boojin Kim boojin@samsung.com --- arch/arm/mach-exynos4/clock.c |4 ++-- arch/arm/mach-s5p64x0/clock-s5p6440.c |1 + arch/arm/mach-s5p64x0/clock-s5p6450.c |1 + arch/arm/mach-s5pc100/clock.c |4 ++-- arch/arm/mach-s5pv210/clock.c |4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index fee2dd8..04c997a 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -460,12 +460,12 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 10), }, { .name = dma, - .devname= s3c-pl330.0, + .devname= dma-pl330.0, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 0), }, { .name = dma, - .devname= s3c-pl330.1, + .devname= dma-pl330.1, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 1), }, { diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index c1f548f..c54c65d 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -147,6 +147,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 8), }, { .name = dma, + .devname= dma-pl330, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 3d9b609..2d04abf 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -180,6 +180,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 3), }, { .name = dma, + .devname= dma-pl330, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 6527c05..8d47709 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -460,13 +460,13 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 2), }, { .name = dma, - .devname= s3c-pl330.1, + .devname= dma-pl330.1, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 1), }, { .name = dma, - .devname= s3c-pl330.0, + .devname= dma-pl330.0, .parent = clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit= (1 0), diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index d35726a..239aaad 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -295,13 +295,13 @@ static struct clk_ops clk_fout_apll_ops = { static struct clk init_clocks_off[] = { { .name = dma, - .devname= s3c-pl330.0, + .devname= dma-pl330.0, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit= (1 3), }, { .name = dma, - .devname= s3c-pl330.1, + .devname= dma-pl330.1, .parent = clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit= (1 4), -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/3] ARM: EXYNOS4: use dma-pl330 device name for clock
Vladimir Zapolskiy wrote: Sent: Wednesday, August 17, 2011 6:31 AM To: Kukjin Kim Cc: linux-samsung-soc@vger.kernel.org; linux-arm- ker...@lists.infradead.org; Vladimir Zapolskiy; Boojin Kim Subject: [PATCH 1/3] ARM: EXYNOS4: use dma-pl330 device name for clock This change replaces s3c-pl330.x clock device names with dma-pl330.x, otherwise there won't be a correspondence between clock device name and amba device name, thus clocks can't be enabled. Fixes runtime errors on clk_get() from drivers/dma/pl330.c: dma-pl330 dma-pl330.0: Cannot get operation clock. dma-pl330: probe of dma-pl330.0 failed with error -22 Signed-off-by: Vladimir Zapolskiy v...@mleia.com Cc: Boojin Kim boojin@samsung.com --- arch/arm/mach-exynos4/clock.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach- exynos4/clock.c index fee2dd8..04c997a 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -460,12 +460,12 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 10), }, { .name = dma, - .devname= s3c-pl330.0, + .devname= dma-pl330.0, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 0), }, { .name = dma, - .devname= s3c-pl330.1, + .devname= dma-pl330.1, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit= (1 1), }, { -- 1.7.5.1 I checked this patch just now. This patch looks good to me. but this missed regarding s5p64x0 dma-pl330 clock. So, need to following. diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index c1f548f..c54c65d 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -147,6 +147,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 8), }, { .name = dma, + .devname= dma-pl330, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 3d9b609..2d04abf 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -180,6 +180,7 @@ static struct clk init_clocks_off[] = { .ctrlbit= (1 3), }, { .name = dma, + .devname= dma-pl330, .parent = clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl, .ctrlbit= (1 12), Ohters, looks ok to me Acked-by: Boojin Kim boojin@samsung.com -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 12/15] spi/s3c64xx: Add support DMA engine API
Jassi Brar Wrote: Sent: Tuesday, August 09, 2011 2:48 AM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Mark Brown; Grant Likely; Russell King Subject: Re: [PATCH 12/15] spi/s3c64xx: Add support DMA engine API On Wed, Jul 27, 2011 at 11:01 AM, Boojin Kim boojin@samsung.com wrote: This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs. Signed-off-by: Boojin Kim boojin@samsung.com Acked-by: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi_s3c64xx.c | 141 ++- -- 1 files changed, 69 insertions(+), 72 deletions(-) diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c index 8945e20..a4cf76a 100644 --- a/drivers/spi/spi_s3c64xx.c +++ b/drivers/spi/spi_s3c64xx.c @@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data { unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; + unsignedrx_ch; + unsignedtx_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; void* doesn't need typecasting (same for all such occurances) IIRC someone already pointed it out? I'm sorry for late response. (I was in vacation.) This comment was reflected on 13/15 patch. + 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) 0x) | 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
RE: [PATCH 14/15] ASoC: Samsung: Update DMA interface
Jassi Brar Wrote: Sent: Tuesday, August 09, 2011 4:28 AM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Mark Brown; Grant Likely; Russell King; Liam Girdwood Subject: Re: [PATCH 14/15] ASoC: Samsung: Update DMA interface On Wed, Jul 27, 2011 at 11:01 AM, Boojin Kim boojin@samsung.com wrote: static void dma_enqueue(struct snd_pcm_substream *substream) { struct runtime_data *prtd = substream-runtime-private_data; dma_addr_t pos = prtd-dma_pos; unsigned int limit; - int ret; + struct samsung_dma_prep_info dma_info; pr_debug(Entered %s\n, __func__); - if (s3c_dma_has_circular()) - limit = (prtd-dma_end - prtd-dma_start) / prtd- dma_period; - else - limit = prtd-dma_limit; + limit = (prtd-dma_end - prtd-dma_start) / prtd-dma_period; 'dma_limit' is rendered useless, so you might want to remove it from 'struct runtime_data' as well. You're right. I will remove it in next cleanup patch pr_debug(%s: loaded %d, limit %d\n, __func__, prtd-dma_loaded, limit); - while (prtd-dma_loaded limit) { - unsigned long len = prtd-dma_period; + dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); + dma_info.direction = + (substream-stream == SNDRV_PCM_STREAM_PLAYBACK + ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + dma_info.fp = audio_buffdone; + dma_info.fp_param = substream; + dma_info.period = prtd-dma_period; + dma_info.len = prtd-dma_period*limit; + while (prtd-dma_loaded limit) { pr_debug(dma_loaded: %d\n, prtd-dma_loaded); - if ((pos + len) prtd-dma_end) { - len = prtd-dma_end - pos; - pr_debug(%s: corrected dma len %ld\n, __func__, len); + if ((pos + dma_info.period) prtd-dma_end) { + dma_info.period = prtd-dma_end - pos; + pr_debug(%s: corrected dma len %ld\n, + __func__, dma_info.period); } - ret = s3c2410_dma_enqueue(prtd-params-channel, - substream, pos, len); + dma_info.buf = pos; + prtd-params-ops-prepare(prtd-params-ch, dma_info); - if (ret == 0) { - prtd-dma_loaded++; - pos += prtd-dma_period; - if (pos = prtd-dma_end) - pos = prtd-dma_start; - } else - break; + prtd-dma_loaded++; + pos += prtd-dma_period; + if (pos = prtd-dma_end) + pos = prtd-dma_start; } prtd-dma_pos = pos; } -static void audio_buffdone(struct s3c2410_dma_chan *channel, - void *dev_id, int size, - enum s3c2410_dma_buffresult result) +static void audio_buffdone(void *data) { - struct snd_pcm_substream *substream = dev_id; - struct runtime_data *prtd; + struct snd_pcm_substream *substream = data; + struct runtime_data *prtd = substream-runtime-private_data; pr_debug(Entered %s\n, __func__); - if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) - return; - - prtd = substream-runtime-private_data; + if (prtd-state ST_RUNNING) { + prtd-dma_pos += prtd-dma_period; + if (prtd-dma_pos = prtd-dma_end) + prtd-dma_pos = prtd-dma_start; - if (substream) - snd_pcm_period_elapsed(substream); + if (substream) + snd_pcm_period_elapsed(substream); - spin_lock(prtd-lock); - if (prtd-state ST_RUNNING !s3c_dma_has_circular()) { - prtd-dma_loaded--; - dma_enqueue(substream); + spin_lock(prtd-lock); + if (!samsung_dma_has_circular()) { + prtd-dma_loaded--; + dma_enqueue(substream); + } + spin_unlock(prtd-lock); } - - spin_unlock(prtd-lock); } Since we set integer-constraint on number of periods, you could also discard bothering fractional boundaries. That would make things a lot simpler. @@ -265,14 +250,14 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: prtd-state |= ST_RUNNING; - s3c2410_dma_ctrl(prtd-params-channel
RE: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations
Jassi Brar wrote: Sent: Wednesday, July 27, 2011 4:58 PM To: Boojin Kim Cc: Kukjin Kim; Vinod Koul; Mark Brown; Grant Likely; linux-samsung- s...@vger.kernel.org; Dan Williams; linux-arm- ker...@lists.infradead.org Subject: Re: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations On Wed, Jul 27, 2011 at 10:47 AM, Boojin Kim boojin@samsung.com wrote: Jassi Brar wrote: Sent: Wednesday, July 27, 2011 10:34 AM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Grant Likely; Mark Brown Subject: Re: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations On Tue, Jul 26, 2011 at 3:05 PM, Boojin Kim boojin@samsung.com wrote: Jassi Brar Wrote: Sent: Monday, July 25, 2011 8:52 PM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Grant Likely; Mark Brown Subject: Re: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations On Mon, Jul 25, 2011 at 6:58 AM, Boojin Kim boojin@samsung.com wrote: + +static bool pl330_filter(struct dma_chan *chan, void *param) +{ + struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan- private; + unsigned dma_ch = (unsigned)param; + + if (peri-peri_id != dma_ch) + return false; + + return true; +} This is what I meant... if we keep chan_id for paltform assigned IDs, these filter functions could simply become static bool pl330_filter(struct dma_chan *chan, void *param) { return chan-chan_id == param } And ideally in the long run, we could just drop the filter callback and add expected channel ID to the request_channel call. The chan_id is set by dmaengine. So, We don't use it to hold the user specific Id. Not for long. See https://lkml.org/lkml/2011/7/26/245 + +static inline int s3c_dma_trigger(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START); +} + +static inline int s3c_dma_started(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED); +} + +static inline int s3c_dma_flush(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH); +} + +static inline int s3c_dma_stop(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP); +} + +static struct samsung_dma_ops s3c_dma_ops = { + .request= s3c_dma_request, + .release= s3c_dma_release, + .prepare= s3c_dma_prepare, + .trigger= s3c_dma_trigger, + .started= s3c_dma_started, + .flush = s3c_dma_flush, + .stop = s3c_dma_stop, These last 4 should be gnereallized into one callback with OP argument. I don't have any idea about it. Can you explain it in more detail? static int s3c_dma_control(unsigned ch, enum s3c2410_chan_op/*or similar*/ op) { return s3c2410_dma_ctrl(ch, op); } static struct samsung_dma_ops s3c_dma_ops = { .request= s3c_dma_request, .release= s3c_dma_release, .prepare= s3c_dma_prepare, .control= s3c_dma_control, 'Struct samsung_dma_ops' is used for both 'S3C-DMA-OPS' for 's3c dma' and 'DMA-OPS' for 'dmaengine'. If I modify Struct samsung_dma_ops as your guide, It gives un- expectable effect to DMA-OPS. Actually, We don't want the client with 'DMA-OPS' uses 'enum s3c2410_chan_op' operation anymore. enum s3c2410_chan_op /* or similar */ note 'or similar' Defining a callback for each value of the argument doesn't make sense. Yes, The command may not be 'enum s3c2410_chan_op'. But it's very similar with 'enum s3c2410_chan_op'. So, It brings same result that I sad. Actually, I quietly agree with your comment. If the 'struct samsung_dma_ops' is only used for 's3c-dma-ops', I would address your comment. But, 'struct samsung_dma_ops' is used for all Samsung dma clients. I aim that 'struct samsung_dma_ops' provide the DMA clients with 'dmaengine' friendly DMA interface without any other command. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 14/14] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction
Grant Likely Wrote: Likely Sent: Tuesday, July 26, 2011 6:16 AM To: Jassi Brar Cc: Boojin Kim; linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Mark Brown Subject: Re: [PATCH V4 14/14] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction On Mon, Jul 25, 2011 at 05:38:37PM +0530, Jassi Brar wrote: On Mon, Jul 25, 2011 at 6:58 AM, Boojin Kim boojin@samsung.com wrote: This patch removes the samsung specific enum type 's3c2410_dmasrc' and uses 'dma_data_direction' instead. Signed-off-by: Boojin Kim boojin@samsung.com Signed-off-by: Kukjin Kim kgene@samsung.com Acked-by: Jassi Brar jassisinghb...@gmail.com If this patch was first in the patchset, probably it could have been already merged. Indeed. If you move this to the front when you post the next version then it can be merged right away. I tried to move it ahead. But It made some conflicts. So, I pushed as it is on V5 release. Sorry.. I would have noticed it before I release V5. Acked-by: Grant Likely grant.lik...@secretlab.ca -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 12/14] spi/s3c64xx: Add support DMA engine API
Vinod Koul Wrote: Sent: Monday, July 25, 2011 8:17 PM To: Boojin Kim Cc: vinod.k...@intel.com; linux-arm-ker...@lists.infradead.org; linux- samsung-...@vger.kernel.org; Kukjin Kim; Jassi Brar; Grant Likely; Mark Brown; Dan Williams Subject: Re: [PATCH V4 12/14] spi/s3c64xx: Add support DMA engine API On Mon, 2011-07-25 at 10:28 +0900, Boojin Kim wrote: This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs. Signed-off-by: Boojin Kim boojin@samsung.com Cc: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi_s3c64xx.c | 141 ++- -- 1 files changed, 69 insertions(+), 72 deletions(-) diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c index 8945e20..a4cf76a 100644 --- a/drivers/spi/spi_s3c64xx.c +++ b/drivers/spi/spi_s3c64xx.c @@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data { unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; + unsignedrx_ch; + unsignedtx_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); +} I don't see much diff in these two functions and you should be able to use a generic one which takes care of both TX and RX, does your callback data know if the channel is for TX or RX? If not then a helper to do above should take care well and making code simpler I'm very agree with you. But, I think it isn't deeply related to this patch series. So, I wish to make and submit it after this patch series is finished. + 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) 0x) | 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
RE: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations
Jassi Brar Wrote: Sent: Monday, July 25, 2011 8:52 PM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Grant Likely; Mark Brown Subject: Re: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations On Mon, Jul 25, 2011 at 6:58 AM, Boojin Kim boojin@samsung.com wrote: + +static bool pl330_filter(struct dma_chan *chan, void *param) +{ + struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan- private; + unsigned dma_ch = (unsigned)param; + + if (peri-peri_id != dma_ch) + return false; + + return true; +} This is what I meant... if we keep chan_id for paltform assigned IDs, these filter functions could simply become static bool pl330_filter(struct dma_chan *chan, void *param) { return chan-chan_id == param } And ideally in the long run, we could just drop the filter callback and add expected channel ID to the request_channel call. The chan_id is set by dmaengine. So, We don't use it to hold the user specific Id. + +static inline int s3c_dma_trigger(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START); +} + +static inline int s3c_dma_started(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED); +} + +static inline int s3c_dma_flush(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH); +} + +static inline int s3c_dma_stop(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP); +} + +static struct samsung_dma_ops s3c_dma_ops = { + .request= s3c_dma_request, + .release= s3c_dma_release, + .prepare= s3c_dma_prepare, + .trigger= s3c_dma_trigger, + .started= s3c_dma_started, + .flush = s3c_dma_flush, + .stop = s3c_dma_stop, These last 4 should be gnereallized into one callback with OP argument. I don't have any idea about it. Can you explain it in more detail? -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 04/14] DMA: PL330: Add DMA_CYCLIC capability
Jassi Brar Wrote: Sent: Monday, July 25, 2011 8:24 PM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Grant Likely; Mark Brown Subject: Re: [PATCH V4 04/14] DMA: PL330: Add DMA_CYCLIC capability On Mon, Jul 25, 2011 at 6:58 AM, Boojin Kim boojin@samsung.com wrote: This patch adds DMA_CYCLIC capability that is used for audio driver. DMA driver with DMA_CYCLIC capability reuses the dma requests that were submitted through tx_submit(). Signed-off-by: Boojin Kim boojin@samsung.com --- drivers/dma/pl330.c | 111 +++ 1 files changed, 111 insertions(+), 0 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 880f010..121c75a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -69,6 +69,11 @@ 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; + + bool cyclic; }; We already have a tasklet_struct member here. This 'cyclic' flag can indicate if we are doing cyclic or serial transfers. So, this cyclic_task seems unnecessary. I will change cyclic operation base on your comment. Cyclic_task will be removed. +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) { + 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); +} Please merge this with pl330_tasklet and use 'cyclic' flag to differentiate. @@ -227,6 +267,9 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err) spin_unlock_irqrestore(pch-lock, flags); + if (pch-cyclic_task) + tasklet_schedule(pch-cyclic_task); + else tasklet_schedule(pch-task); A tab here please, and check for 'cyclic' flag. @@ -316,6 +359,15 @@ static void pl330_free_chan_resources(struct dma_chan *chan) pl330_release_channel(pch-pl330_chid); pch-pl330_chid = NULL; + if (pch-cyclic) { + pch-cyclic = false; + list_splice_tail_init(pch-work_list, pch-dmac- desc_pool); + if (pch-cyclic_task) { + tasklet_kill(pch-cyclic_task); + pch-cyclic_task = NULL; + } + } + spin_unlock_irqrestore(pch-lock, flags); } To be explicit, please initialize 'cyclic' flag to false in pl330_alloc_chan_resources I will address your comment. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 03/14] DMA: PL330: Support DMA_SLAVE_CONFIG command
Vinod Koul Wrote: Sent: Monday, July 25, 2011 10:48 PM To: Boojin Kim Cc: vinod.k...@intel.com; linux-arm-ker...@lists.infradead.org; linux- samsung-...@vger.kernel.org; 'Kukjin Kim'; 'Jassi Brar'; 'Grant Likely'; 'Mark Brown'; 'Dan Williams' Subject: RE: [PATCH V4 03/14] DMA: PL330: Support DMA_SLAVE_CONFIG command On Mon, 2011-07-25 at 21:51 +0900, Boojin Kim wrote: Vinod Koul Wrote: Sent: Monday, July 25, 2011 7:27 PM To: Boojin Kim Cc: vinod.k...@intel.com; linux-arm-ker...@lists.infradead.org; linux- samsung-...@vger.kernel.org; Kukjin Kim; Jassi Brar; Grant Likely; Mark Brown; Dan Williams Subject: Re: [PATCH V4 03/14] DMA: PL330: Support DMA_SLAVE_CONFIG command On Mon, 2011-07-25 at 10:28 +0900, Boojin Kim wrote: This patch adds support DMA_SLAVE_CONFIG command. Signed-off-by: Boojin Kim boojin@samsung.com --- drivers/dma/pl330.c | 53 + - 1 files changed, 39 insertions(+), 14 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 586ab39..880f010 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -256,25 +256,50 @@ 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; - - spin_lock_irqsave(pch-lock, flags); - - /* FLUSH the PL330 Channel thread */ - pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); + switch (cmd) { + case DMA_TERMINATE_ALL: + spin_lock_irqsave(pch-lock, flags); - /* Mark all desc done */ - list_for_each_entry(desc, pch-work_list, node) - desc-status = DONE; + /* FLUSH the PL330 Channel thread */ + pl330_chan_ctrl(pch-pl330_chid, PL330_OP_FLUSH); - spin_unlock_irqrestore(pch-lock, flags); + /* Mark all desc done */ + list_for_each_entry_safe(desc, _dt, pch- work_list , node) { + desc-status = DONE; + pch-completed = desc-txd.cookie; + list_move_tail(desc-node, list); + } - pl330_tasklet((unsigned long) pch); + list_splice_tail_init(list, pdmac-desc_pool); + spin_unlock_irqrestore(pch-lock, flags); + break; + case DMA_SLAVE_CONFIG: + slave_config = (struct dma_slave_config *)arg; + peri = pch-chan.private; + + if (slave_config-direction == DMA_TO_DEVICE) { + if (slave_config-dst_addr) + peri-fifo_addr = slave_config- dst_addr; + if (slave_config-dst_addr_width) + peri-burst_sz = __ffs(slave_config- dst_addr_width); This doesn't sound right, why can't you use xxx_maxburst field instead? Can you explain the problem in more detail? Do you mean that 'xxx_maxburst' takes place of 'xxx_addr_width' or __ffs() isn't proper here? Additionally, I will modify this code to consider '_maxburst' field. __ffs is okay and sensible. I meant you should use proper fields for passing info, which in this case would be dst_maxburst for specifying destination burst sizes I think the naming seems to make confusion. 'Peri-burst_sz' on this code means the width of fifo in bytes of the peri. It's same with the meaning 'xxx_addr_width'. So, I think it's proper usage. 'peri-burst_sz' is passed to PL330 HW. PL330 HW wants to get the power of 2 based the fifo width for it. For example, If fifo width is 8 bytes, PL330 HW should get '3' for it. And I will modify code to consider xxx_maxburst. -- ~Vinod Koul Intel Corp. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 12/14] spi/s3c64xx: Add support DMA engine API
Vinod Koul Wrote: Sent: Tuesday, July 26, 2011 7:15 PM To: Boojin Kim Cc: vinod.k...@intel.com; 'Kukjin Kim'; 'Jassi Brar'; 'Grant Likely'; linux-samsung-soc@vger.kernel.org; 'Mark Brown'; 'Dan Williams'; linux-arm-ker...@lists.infradead.org Subject: RE: [PATCH V4 12/14] spi/s3c64xx: Add support DMA engine API On Tue, 2011-07-26 at 18:31 +0900, Boojin Kim wrote: Vinod Koul Wrote: Sent: Monday, July 25, 2011 8:17 PM To: Boojin Kim Cc: vinod.k...@intel.com; linux-arm-ker...@lists.infradead.org; linux- samsung-...@vger.kernel.org; Kukjin Kim; Jassi Brar; Grant Likely; Mark Brown; Dan Williams Subject: Re: [PATCH V4 12/14] spi/s3c64xx: Add support DMA engine API On Mon, 2011-07-25 at 10:28 +0900, Boojin Kim wrote: This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs. Signed-off-by: Boojin Kim boojin@samsung.com Cc: Grant Likely grant.lik...@secretlab.ca Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/spi/spi_s3c64xx.c | 141 ++- -- 1 files changed, 69 insertions(+), 72 deletions(-) diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c index 8945e20..a4cf76a 100644 --- a/drivers/spi/spi_s3c64xx.c +++ b/drivers/spi/spi_s3c64xx.c @@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data { unsignedstate; unsignedcur_mode, cur_bpw; unsignedcur_speed; + unsignedrx_ch; + unsignedtx_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); +} I don't see much diff in these two functions and you should be able to use a generic one which takes care of both TX and RX, does your callback data know if the channel is for TX or RX? If not then a helper to do above should take care well and making code simpler I'm very agree with you. But, I think it isn't deeply related to this patch series. So, I wish to make and submit it after this patch series is finished. Since you are reworking this driver would make sense to do now, it doesn't sound to be a big change. Ok. I will follow your request. I will make new patch for it and send it with V5 patchset. -- ~Vinod Koul Intel Corp. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations
Jassi Brar wrote: Sent: Wednesday, July 27, 2011 10:34 AM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Grant Likely; Mark Brown Subject: Re: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations On Tue, Jul 26, 2011 at 3:05 PM, Boojin Kim boojin@samsung.com wrote: Jassi Brar Wrote: Sent: Monday, July 25, 2011 8:52 PM To: Boojin Kim Cc: linux-arm-ker...@lists.infradead.org; linux-samsung- s...@vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Grant Likely; Mark Brown Subject: Re: [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations On Mon, Jul 25, 2011 at 6:58 AM, Boojin Kim boojin@samsung.com wrote: + +static bool pl330_filter(struct dma_chan *chan, void *param) +{ + struct dma_pl330_peri *peri = (struct dma_pl330_peri *)chan- private; + unsigned dma_ch = (unsigned)param; + + if (peri-peri_id != dma_ch) + return false; + + return true; +} This is what I meant... if we keep chan_id for paltform assigned IDs, these filter functions could simply become static bool pl330_filter(struct dma_chan *chan, void *param) { return chan-chan_id == param } And ideally in the long run, we could just drop the filter callback and add expected channel ID to the request_channel call. The chan_id is set by dmaengine. So, We don't use it to hold the user specific Id. Not for long. See https://lkml.org/lkml/2011/7/26/245 + +static inline int s3c_dma_trigger(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START); +} + +static inline int s3c_dma_started(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED); +} + +static inline int s3c_dma_flush(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH); +} + +static inline int s3c_dma_stop(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP); +} + +static struct samsung_dma_ops s3c_dma_ops = { + .request= s3c_dma_request, + .release= s3c_dma_release, + .prepare= s3c_dma_prepare, + .trigger= s3c_dma_trigger, + .started= s3c_dma_started, + .flush = s3c_dma_flush, + .stop = s3c_dma_stop, These last 4 should be gnereallized into one callback with OP argument. I don't have any idea about it. Can you explain it in more detail? static int s3c_dma_control(unsigned ch, enum s3c2410_chan_op/*or similar*/ op) { return s3c2410_dma_ctrl(ch, op); } static struct samsung_dma_ops s3c_dma_ops = { .request= s3c_dma_request, .release= s3c_dma_release, .prepare= s3c_dma_prepare, .control= s3c_dma_control, 'Struct samsung_dma_ops' is used for both 'S3C-DMA-OPS' for 's3c dma' and 'DMA-OPS' for 'dmaengine'. If I modify Struct samsung_dma_ops as your guide, It gives un-expectable effect to DMA-OPS. Actually, We don't want the client with 'DMA-OPS' uses 'enum s3c2410_chan_op' operation anymore. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC
Signed-off-by: Boojin Kim boojin@samsung.com Cc: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 75 +- 1 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 6abe1ec..b7ecf47 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -17,6 +17,7 @@ #include linux/interrupt.h #include linux/amba/bus.h #include linux/amba/pl330.h +#include linux/pm_runtime.h #define NR_DEFAULT_DESC16 @@ -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 { @@ -696,6 +699,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 +790,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 +850,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 +870,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, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/15] ARM: S5P64X0: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Signed-off-by: Kukjin Kim kgene@samsung.com --- 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 | 273 -- arch/arm/mach-s5p64x0/include/mach/dma.h |2 +- 5 files changed, 201 insertions(+), 96 deletions(-) diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig index 017af4c..bbf3487 100644 --- a/arch/arm/mach-s5p64x0/Kconfig +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -9,14 +9,14 @@ if ARCH_S5P64X0 config CPU_S5P6440 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_HRT help Enable S5P6440 CPU support config CPU_S5P6450 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_HRT help Enable S5P6450 CPU support diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index 9f12c2e..5f7ad9e 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -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(); } diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 4eec457..62d4707 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -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(); } diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index d7ad944..aebf3fc 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -21,128 +21,219 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h + +#include asm/irq.h #include mach/map.h #include mach/irqs.h #include mach/regs-clock.h +#include mach/dma.h #include plat/devs.h -#include plat/s3c-pl330-pdata.h +#include plat/irqs.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5p64x0_pdma_resource[] = { - [0] = { - .start = S5P64X0_PA_PDMA, - .end= S5P64X0_PA_PDMA + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_DMA0, - .end= IRQ_DMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri s5p6440_pdma_peri[22] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM
[PATCH V5 00/15] To use DMA generic APIs for Samsung DMA
This patchset adds support DMA generic APIs for Samsung DMA. The changes from V4 are following: - Change DMA cyclic capability operation on '04 patch' - Remove cyclic_task - Initialize 'cyclic' variable on channel request. - Change pl330 data structure on '02, 07, 08, 09, 10 patches' - Move 'fifo_addr' and 'burst_sz' variables from 'struct dma_pl330_peri' to 'struct dma_pl330_chan' - Change some names on '02, 05 patch' - Change DMADEV_PL330 configuration to SAMSUNG_DMA_PL330 - Add comment for 'burst_sz' variable - Consider 'xxx_maxburst' on '03, 06 patch' - Modify pl330_filter() function on '06 patch' - Merge DMA control code on SPI driver on '13 patch' [PATCH V5 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC [PATCH V5 02/15] DMA: PL330: Update PL330 DMA API driver [PATCH V5 03/15] DMA: PL330: Support DMA_SLAVE_CONFIG command [PATCH V5 04/15] DMA: PL330: Add DMA_CYCLIC capability [PATCH V5 05/15] ARM: SAMSUNG: Update to use PL330-DMA driver [PATCH V5 06/15] ARM: SAMSUNG: Add common DMA operations [PATCH V5 07/15] ARM: EXYNOS4: Use generic DMA PL330 driver [PATCH V5 08/15] ARM: S5PV210: Use generic DMA PL330 driver [PATCH V5 09/15] ARM: S5PC100: Use generic DMA PL330 driver [PATCH V5 10/15] ARM: S5P64X0: Use generic DMA PL330 driver [PATCH V5 11/15] ARM: SAMSUNG: Remove S3C-PL330-DMA driver [PATCH V5 12/15] spi/s3c64xx: Add support DMA engine API [PATCH V5 13/15] spi/s3c64xx: Merge dma control code [PATCH V5 14/15] ASoC: Samsung: Update DMA interface [PATCH V5 15/15] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/15] 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. Signed-off-by: Boojin Kim boojin@samsung.com Cc: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/Kconfig|3 ++- drivers/dma/pl330.c| 13 - include/linux/amba/pl330.h |6 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 25cf327..569cb14 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL config PL330_DMA tristate DMA API Driver for PL330 select DMA_ENGINE - depends on PL330 + 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 diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index b7ecf47..5a10df9 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -69,6 +69,10 @@ struct dma_pl330_chan { * NULL if the channel is available to be acquired. */ void *pl330_chid; + + /* For D-to-M and M-to-D channels */ + int burst_sz; /* the peripheral fifo width */ + dma_addr_t fifo_addr; }; struct dma_pl330_dmac { @@ -455,7 +459,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 +581,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)) @@ -593,8 +597,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } - addr = peri-fifo_addr; - burst_size = peri-burst_sz; + addr = pch-fifo_addr; first = NULL; @@ -642,7 +645,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 = pch-burst_sz; desc-rqcfg.brst_len = 1; } diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h index cbee7de..d12f077 100644 --- a/include/linux/amba/pl330.h +++ b/include/linux/amba/pl330.h @@ -19,12 +19,8 @@ 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 */ - int burst_sz; /* in power of 2 */ - dma_addr_t fifo_addr; }; struct dma_pl330_platdata { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/15] ARM: S5PV210: Use generic DMA PL330 driver
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. Signed-off-by: Boojin Kim boojin@samsung.com Signed-off-by: Kukjin Kim kgene@samsung.com --- arch/arm/mach-s5pv210/Kconfig|2 +- arch/arm/mach-s5pv210/clock.c| 16 +- arch/arm/mach-s5pv210/dma.c | 316 +++--- arch/arm/mach-s5pv210/include/mach/dma.h |2 +- 4 files changed, 214 insertions(+), 122 deletions(-) diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 37b5a97..855d4b4 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -11,7 +11,7 @@ if ARCH_S5PV210 config CPU_S5PV210 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_EXT_INT select S5P_HRT select S5PV210_PM if PM diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 2d59949..dbe7285 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -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(); } diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index 497d343..f79d0b0 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5pv210/dma.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh jassi.b...@samsung.com * @@ -17,151 +21,239 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include linux/platform_device.h #include linux/dma-mapping.h +#include linux/amba/bus.h +#include linux/amba/pl330.h +#include asm/irq.h #include plat/devs.h #include plat/irqs.h #include mach/map.h #include mach/irqs.h - -#include plat/s3c-pl330-pdata.h +#include mach/dma.h static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5pv210_pdma0_resource[] = { - [0] = { - .start = S5PV210_PA_PDMA0, - .end= S5PV210_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PDMA0, - .end= IRQ_PDMA0, - .flags = IORESOURCE_IRQ, +struct dma_pl330_peri pdma0_peri[28] = { + { + .peri_id = (u8)DMACH_UART0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART1_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART1_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART2_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART2_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_UART3_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_UART3_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = DMACH_MAX, + }, { + .peri_id = (u8)DMACH_I2S0_RX, + .rqtype = DEVTOMEM, + }, { + .peri_id = (u8)DMACH_I2S0_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S0S_TX, + .rqtype = MEMTODEV, + }, { + .peri_id = (u8)DMACH_I2S1_RX, + .rqtype = DEVTOMEM
[PATCH 04/15] DMA: PL330: Add DMA_CYCLIC capability
This patch adds DMA_CYCLIC capability that is used for audio driver. DMA driver activated with it reuses the dma requests that were submitted through tx_submit(). Signed-off-by: Boojin Kim boojin@samsung.com Cc: Vinod Koul vinod.k...@intel.com Cc: Dan Williams dan.j.willi...@intel.com Signed-off-by: Kukjin Kim kgene@samsung.com --- drivers/dma/pl330.c | 97 +- 1 files changed, 95 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index a4c4b62..996b2e9 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -42,6 +42,12 @@ enum desc_status { DONE, }; +enum cyclic_mode { + NO_CYCLIC, + CYCLIC_PREP, + CYCLIC_TRIGGER, +}; + struct dma_pl330_chan { /* Schedule desc completion */ struct tasklet_struct task; @@ -74,6 +80,9 @@ struct dma_pl330_chan { int burst_sz; /* the peripheral fifo width */ int burst_len; /* the number of burst */ dma_addr_t fifo_addr; + + /* for cyclic capability */ + enum cyclic_mode cyclic; }; struct dma_pl330_dmac { @@ -160,6 +169,31 @@ static inline void free_desc_list(struct list_head *list) spin_unlock_irqrestore(pdmac-pool_lock, flags); } +static inline void handle_cyclic_desc_list(struct list_head *list) +{ + struct dma_pl330_desc *desc; + struct dma_pl330_chan *pch; + unsigned long flags; + + if (list_empty(list)) + return; + + list_for_each_entry(desc, list, node) { + dma_async_tx_callback callback; + + /* Change status to reload it */ + desc-status = PREP; + pch = desc-pchan; + callback = desc-txd.callback; + if (callback) + callback(desc-txd.callback_param); + } + + spin_lock_irqsave(pch-lock, flags); + list_splice_tail_init(list, pch-work_list); + spin_unlock_irqrestore(pch-lock, flags); +} + static inline void fill_queue(struct dma_pl330_chan *pch) { struct dma_pl330_desc *desc; @@ -213,7 +247,10 @@ static void pl330_tasklet(unsigned long data) spin_unlock_irqrestore(pch-lock, flags); - free_desc_list(list); + if (pch-cyclic == CYCLIC_TRIGGER) + handle_cyclic_desc_list(list); + else + free_desc_list(list); } static void dma_pl330_rqcb(void *token, enum pl330_op_err err) @@ -244,6 +281,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) spin_lock_irqsave(pch-lock, flags); pch-completed = chan-cookie = 1; + pch-cyclic = NO_CYCLIC; pch-pl330_chid = pl330_request_channel(pdmac-pif); if (!pch-pl330_chid) { @@ -323,6 +361,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan) pl330_release_channel(pch-pl330_chid); pch-pl330_chid = NULL; + if (pch-cyclic) + list_splice_tail_init(pch-work_list, pch-dmac-desc_pool); + spin_unlock_irqrestore(pch-lock, flags); } @@ -346,7 +387,11 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, static void pl330_issue_pending(struct dma_chan *chan) { - pl330_tasklet((unsigned long) to_pchan(chan)); + struct dma_pl330_chan *pch = to_pchan(chan); + pl330_tasklet((unsigned long) pch); + + if (pch-cyclic == CYCLIC_PREP) + pch-cyclic = CYCLIC_TRIGGER; } /* @@ -554,6 +599,52 @@ 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); + dma_addr_t dst; + dma_addr_t src; + + 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 = pch-fifo_addr; + break; + case DMA_FROM_DEVICE: + desc-rqcfg.src_inc = 0; + desc-rqcfg.dst_inc = 1; + src = pch-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 = pch-burst_sz; + desc-rqcfg.brst_len = 1; + + if (!pch-cyclic) + pch-cyclic = CYCLIC_PREP; + + fill_px(desc-px, dst, src, period_len); + + return desc-txd