From c2c665fd41b5544cce3be4d972e9c9bde9e29060 Mon Sep 17 00:00:00 2001 From: Narayanan Date: Tue, 13 Sep 2011 17:00:22 +0530 Subject: dma40: Resetting priority bit for logical channels This patch will set the SSCFG/SDCFG bit[7] PRI only for physical channel requests with high priority. For logical channels, this bit will be zero. ST-Ericsson ID: 361435 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: I1afb5c039387f9f9295c73e9dee92dc87bb15aeb Signed-off-by: Narayanan G Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30839 Reviewed-by: Rabin VINCENT Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/31929 --- drivers/dma/ste_dma40_ll.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index cad9e1daedf..450079e2c12 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -102,16 +102,18 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + /* Set the priority bit to high for the physical channel */ + if (cfg->high_priority) { + src |= 1 << D40_SREG_CFG_PRI_POS; + dst |= 1 << D40_SREG_CFG_PRI_POS; + } + } else { /* Logical channel */ dst |= 1 << D40_SREG_CFG_LOG_GIM_POS; src |= 1 << D40_SREG_CFG_LOG_GIM_POS; } - if (cfg->high_priority) { - src |= 1 << D40_SREG_CFG_PRI_POS; - dst |= 1 << D40_SREG_CFG_PRI_POS; - } if (cfg->src_info.big_endian) src |= 1 << D40_SREG_CFG_LBE_POS; -- cgit v1.2.3 From 29700821e3b9a1d7e1069aad9bfa811b8533b334 Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Wed, 28 Sep 2011 09:32:20 +0200 Subject: dmaengine/ste_dma40: use writel_relaxed for lcxa lcpa and lcla are written often and the cache_sync() overhead in writel is costly, especially for wlan where every single network packet (in RX mode) corresponds to a separate DMA transfer. ST-Ericsson Linux next: TESTED ST-Ericsson ID: 357764 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I8339704de95f2355d22681ac4bd542795770fa89 Signed-off-by: Per Forlin Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33009 Reviewed-by: Narayanan GOPALAKRISHNAN Reviewed-by: QABUILD Reviewed-by: Rabin VINCENT --- drivers/dma/ste_dma40_ll.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 450079e2c12..d47d1fa36b9 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -333,10 +333,10 @@ void d40_log_lli_lcpa_write(struct d40_log_lli_full *lcpa, { d40_log_lli_link(lli_dst, lli_src, next, flags); - writel(lli_src->lcsp02, &lcpa[0].lcsp0); - writel(lli_src->lcsp13, &lcpa[0].lcsp1); - writel(lli_dst->lcsp02, &lcpa[0].lcsp2); - writel(lli_dst->lcsp13, &lcpa[0].lcsp3); + writel_relaxed(lli_src->lcsp02, &lcpa[0].lcsp0); + writel_relaxed(lli_src->lcsp13, &lcpa[0].lcsp1); + writel_relaxed(lli_dst->lcsp02, &lcpa[0].lcsp2); + writel_relaxed(lli_dst->lcsp13, &lcpa[0].lcsp3); } void d40_log_lli_lcla_write(struct d40_log_lli *lcla, @@ -346,10 +346,10 @@ void d40_log_lli_lcla_write(struct d40_log_lli *lcla, { d40_log_lli_link(lli_dst, lli_src, next, flags); - writel(lli_src->lcsp02, &lcla[0].lcsp02); - writel(lli_src->lcsp13, &lcla[0].lcsp13); - writel(lli_dst->lcsp02, &lcla[1].lcsp02); - writel(lli_dst->lcsp13, &lcla[1].lcsp13); + writel_relaxed(lli_src->lcsp02, &lcla[0].lcsp02); + writel_relaxed(lli_src->lcsp13, &lcla[0].lcsp13); + writel_relaxed(lli_dst->lcsp02, &lcla[1].lcsp02); + writel_relaxed(lli_dst->lcsp13, &lcla[1].lcsp13); } static void d40_log_fill_lli(struct d40_log_lli *lli, -- cgit v1.2.3 From 48d61af58c9c4257bb68425be44f1b40bed6c2a8 Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Tue, 18 Oct 2011 18:39:47 +0200 Subject: dmaengine/ste_dma40: set dma max seg to 0xffff Maximum DMA seg size is (0xffff x data_width). If max seg size is not set it deafults to 64k. This results in failure if transferring 64k in byte mode. Large seg sizes may be supported by splitting large transfer. ---------------- commit d49278e3351b34870cbffffc5067348a318e7b06 Author: Per Forlin Date: Mon Dec 20 18:31:38 2010 +0100 dmaengine: dma40: Add support to split up large elements ---------------- This patch has been rejected or lost on kernel 3.0. It exists on mainline kernel 3.0. ST-Ericsson ID: 363565 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: I7c0bf09df04cb20da2164c5c40f3a0ae73e65289 Signed-off-by: Per Forlin Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34405 Reviewed-by: QATOOLS Reviewed-by: Linus WALLEIJ --- drivers/dma/ste_dma40.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 2ed1ac3513f..751c876f373 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -345,6 +345,7 @@ struct d40_base { int irq; int num_phy_chans; int num_log_chans; + struct device_dma_parameters dma_parms; struct dma_device dma_both; struct dma_device dma_slave; struct dma_device dma_memcpy; @@ -3358,6 +3359,13 @@ static int __init d40_probe(struct platform_device *pdev) if (err) goto failure; + base->dev->dma_parms = &base->dma_parms; + err = dma_set_max_seg_size(base->dev, 0xffff); + if (err) { + d40_err(&pdev->dev, "Failed to set dma max seg size\n"); + goto failure; + } + d40_hw_init(base); dev_info(base->dev, "initialized\n"); -- cgit v1.2.3 From ff4005a408d67e9b5a1aa781d2ca916ef763fe91 Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Thu, 13 Oct 2011 12:11:36 +0200 Subject: dmaengine/ste_dma40: limit burst size to 16 The client is not aware of the maximum burst size in the dma driver. If the size exceeds 16 set max to 16. ST-Ericsson ID: 363565 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: I298b779db3d42944f2fcc9688fe519f640cca99d Signed-off-by: Per Forlin Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34361 Reviewed-by: QATOOLS Reviewed-by: QABUILD Reviewed-by: Linus WALLEIJ --- drivers/dma/ste_dma40.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 751c876f373..6312131149c 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2578,6 +2578,14 @@ static int d40_set_runtime_config(struct dma_chan *chan, return -EINVAL; } + if (src_maxburst > 16) { + src_maxburst = 16; + dst_maxburst = src_maxburst * src_addr_width / dst_addr_width; + } else if (dst_maxburst > 16) { + dst_maxburst = 16; + src_maxburst = dst_maxburst * dst_addr_width / src_addr_width; + } + ret = dma40_config_to_halfchannel(d40c, &cfg->src_info, src_addr_width, src_maxburst); -- cgit v1.2.3 From 746fe9c108ae7cc79da9ccf1437b97db98444516 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Tue, 17 Jan 2012 17:40:40 +0100 Subject: dma40: Add the needed functions for STE audio support Come from commit "dma40: update" Author: Rabin Vincent Signed-off-by: Philippe Langlais --- arch/arm/plat-nomadik/include/plat/ste_dma40.h | 28 +++++++++++++++ drivers/dma/ste_dma40.c | 50 ++++++++++++++++++++++++++ drivers/dma/ste_dma40_ll.h | 4 +++ 3 files changed, 82 insertions(+) diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h index 9ff93b06568..2a8631842c9 100644 --- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -162,6 +162,24 @@ struct stedma40_platform_data { #ifdef CONFIG_STE_DMA40 +/* + * stedma40_get_src_addr - get current source address + * @chan: the DMA channel + * + * Returns the physical address of the current source element to be read by the + * DMA. + */ +dma_addr_t stedma40_get_src_addr(struct dma_chan *chan); + +/* + * stedma40_get_dst_addr - get current destination address + * @chan: the DMA channel + * + * Returns the physical address of the current destination element to be + * written by the DMA. + */ +dma_addr_t stedma40_get_dst_addr(struct dma_chan *chan); + /** * stedma40_filter() - Provides stedma40_chan_cfg to the * ste_dma40 dma driver via the dmaengine framework. @@ -204,6 +222,16 @@ dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, } #else +dma_addr_t stedma40_get_src_addr(struct dma_chan *chan) +{ + return NULL; +} + +dma_addr_t stedma40_get_dst_addr(struct dma_chan *chan) +{ + return NULL; +} + static inline bool stedma40_filter(struct dma_chan *chan, void *data) { return false; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 6312131149c..1c20b4ebc8b 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2648,6 +2648,56 @@ static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, return -ENXIO; } +dma_addr_t stedma40_get_src_addr(struct dma_chan *chan) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + dma_addr_t addr; + + if (chan_is_physical(d40c)) + addr = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSPTR); + else { + unsigned long lower; + unsigned long upper; + + /* + * There is a potential for overflow between the time the two + * halves of the pointer are read. + */ + lower = d40c->lcpa->lcsp0 & D40_MEM_LCSP0_SPTR_MASK; + upper = d40c->lcpa->lcsp1 & D40_MEM_LCSP1_SPTR_MASK; + + addr = upper | lower; + } + + return addr; +} +EXPORT_SYMBOL(stedma40_get_src_addr); + +dma_addr_t stedma40_get_dst_addr(struct dma_chan *chan) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + dma_addr_t addr; + + if (chan_is_physical(d40c)) + addr = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDPTR); + else { + unsigned long lower; + unsigned long upper; + + lower = d40c->lcpa->lcsp2 & D40_MEM_LCSP2_DPTR_MASK; + upper = d40c->lcpa->lcsp3 & D40_MEM_LCSP3_DPTR_MASK; + + addr = upper | lower; + } + + return addr; +} +EXPORT_SYMBOL(stedma40_get_dst_addr); + /* Initialization functions */ static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma, diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h index 51e8e5396e9..2f3395d6850 100644 --- a/drivers/dma/ste_dma40_ll.h +++ b/drivers/dma/ste_dma40_ll.h @@ -94,10 +94,13 @@ /* LCSP2 */ #define D40_MEM_LCSP2_ECNT_POS 16 +#define D40_MEM_LCSP2_DPTR_POS 0 #define D40_MEM_LCSP2_ECNT_MASK (0xFFFF << D40_MEM_LCSP2_ECNT_POS) +#define D40_MEM_LCSP2_DPTR_MASK (0xFFFF << D40_MEM_LCSP2_DPTR_POS) /* LCSP3 */ +#define D40_MEM_LCSP3_DPTR_POS 16 #define D40_MEM_LCSP3_DCFG_MST_POS 15 #define D40_MEM_LCSP3_DCFG_TIM_POS 14 #define D40_MEM_LCSP3_DCFG_EIM_POS 13 @@ -107,6 +110,7 @@ #define D40_MEM_LCSP3_DLOS_POS 1 #define D40_MEM_LCSP3_DTCP_POS 0 +#define D40_MEM_LCSP3_DPTR_MASK (0xFFFF << D40_MEM_LCSP3_DPTR_POS) #define D40_MEM_LCSP3_DLOS_MASK (0x7F << D40_MEM_LCSP3_DLOS_POS) #define D40_MEM_LCSP3_DTCP_MASK (0x1 << D40_MEM_LCSP3_DTCP_POS) -- cgit v1.2.3 From 5926dc0478e3506a9fc2e08e59ab1071e7060d9f Mon Sep 17 00:00:00 2001 From: Narayanan G Date: Fri, 20 Jan 2012 13:56:14 +0530 Subject: dma40: don't check for pm_runtime_suspended() The check for runtime suspend is not needed during a regular suspend, as the framework takes care of this. This fixes the issue of DMA driver not letting the system to go to deepsleep in the first attempt. ST-Ericsson ID: 411801 ST-Ericsson FOSS-OUT ID: NA ST-Ericsson Linux next: NA Change-Id: I2b6ef1593da3386b8b93c9d21eaa3a1f7daa7cd6 Signed-off-by: Narayanan G Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/46030 Reviewed-by: QATOOLS Reviewed-by: QABUILD Reviewed-by: Rabin VINCENT --- drivers/dma/ste_dma40.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 1c20b4ebc8b..0fe43c3f598 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2832,8 +2832,6 @@ static int dma40_pm_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct d40_base *base = platform_get_drvdata(pdev); int ret = 0; - if (!pm_runtime_suspended(dev)) - return -EBUSY; if (base->lcpa_regulator) ret = regulator_disable(base->lcpa_regulator); -- cgit v1.2.3