summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNarayanan G <narayanan.gopalakrishnan@stericsson.com>2011-09-15 18:58:35 +0530
committerRabin Vincent <rabin.vincent@stericsson.com>2011-09-22 15:41:23 +0530
commitff06a7b800df8a7dd93981b8971c572dcd897f49 (patch)
treeca17817c010aa9728b53cf605dde46ed93f53724
parent2c2d45d3b5b47e3fbe055ea4793e5917a1cbfa6a (diff)
dma40: Add support to use lcla area from esram
This patch provides an option of having the lcla in ESRAM instead of allocating it. The bool value (use_esram_lcla) in the stedma40_platform_data if set to true, then the lcla address would be taken from platform resources. This patch does not enable the feature, as the other dependencies related to keeping the esram34 regulator on, changes in mcde for releasing 8k from esram bank4 and the changes needed in cmdma have to be merged. ST-Ericsson ID: 362066 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: I590751f732021c5f2f4da9b7d51ae5dc10087be7 Signed-off-by: Narayanan G <narayanan.gopalakrishnan@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/31123 Reviewed-by: Rabin VINCENT <rabin.vincent@stericsson.com>
-rw-r--r--arch/arm/mach-ux500/dma-db8500.c7
-rw-r--r--arch/arm/mach-ux500/include/mach/db8500-regs.h3
-rw-r--r--arch/arm/plat-nomadik/include/plat/ste_dma40.h2
-rw-r--r--drivers/dma/ste_dma40.c59
4 files changed, 57 insertions, 14 deletions
diff --git a/arch/arm/mach-ux500/dma-db8500.c b/arch/arm/mach-ux500/dma-db8500.c
index 12bc9a3406c..d7dcc9147ed 100644
--- a/arch/arm/mach-ux500/dma-db8500.c
+++ b/arch/arm/mach-ux500/dma-db8500.c
@@ -36,6 +36,12 @@ static struct resource dma40_resources[] = {
.start = IRQ_DB8500_DMA,
.end = IRQ_DB8500_DMA,
.flags = IORESOURCE_IRQ
+ },
+ [3] = {
+ .start = U8500_DMA_LCLA_BASE,
+ .end = U8500_DMA_LCLA_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "lcla_esram",
}
};
@@ -223,6 +229,7 @@ static struct stedma40_platform_data dma40_plat_data = {
.memcpy_conf_log = &dma40_memcpy_conf_log,
/* Audio is using physical channel 2 from MMDSP */
.disabled_channels = {2, -1},
+ .use_esram_lcla = false,
};
#ifdef CONFIG_UX500_CONTEXT
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index 99baa905133..45d0c506e43 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -23,6 +23,9 @@
#define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET)
+/* This address fulfills the 256k alignment requirement of the lcla base */
+#define U8500_DMA_LCLA_BASE U8500_ESRAM_BANK4
+
#define U8500_PER3_BASE 0x80000000
#define U8500_STM_BASE 0x80100000
#define U8500_STM_REG_BASE (U8500_STM_BASE + 0xF000)
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
index 665f2c5ee3c..9a3bcb10d21 100644
--- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h
+++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
@@ -141,6 +141,7 @@ struct stedma40_chan_cfg {
* @memcpy_conf_phy: default configuration of physical channel memcpy
* @memcpy_conf_log: default configuration of logical channel memcpy
* @disabled_channels: A vector, ending with -1, that marks physical channels
+ * @use_esram_lcla: flag for mapping the lcla into esram region
* that are for different reasons not available for the driver.
*/
struct stedma40_platform_data {
@@ -152,6 +153,7 @@ struct stedma40_platform_data {
struct stedma40_chan_cfg *memcpy_conf_phy;
struct stedma40_chan_cfg *memcpy_conf_log;
int disabled_channels[STEDMA40_MAX_PHYS];
+ bool use_esram_lcla;
};
struct d40_desc;
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 9bf4427314e..2a3895eb52b 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -575,6 +575,7 @@ static int d40_desc_log_lli_to_lcxa(struct d40_chan *d40c,
struct d40_log_lli_bidir *lli = &d40d->lli_log;
int curr_lcla = -EINVAL;
int first_lcla = 0;
+ bool use_esram_lcla = d40c->base->plat_data->use_esram_lcla;
if ((d40d->lli_len - d40d->lli_current) > 1 ||
d40d->cyclic || !use_lcpa) {
@@ -640,11 +641,15 @@ static int d40_desc_log_lli_to_lcxa(struct d40_chan *d40c,
if (d40d->lli_current == d40d->lli_len - 1)
d40d->last_lcla = lcla;
-
- (void) dma_map_single(d40c->base->dev, lcla,
- 2 * sizeof(struct d40_log_lli),
- DMA_TO_DEVICE);
-
+ /*
+ * Cache maintenance is not needed if lcla is
+ * mapped in esram
+ */
+ if (!use_esram_lcla) {
+ (void) dma_map_single(d40c->base->dev, lcla,
+ 2 * sizeof(struct d40_log_lli),
+ DMA_TO_DEVICE);
+ }
curr_lcla = next_lcla;
if (curr_lcla == -EINVAL || curr_lcla == first_lcla) {
@@ -3681,14 +3686,35 @@ static int __init d40_probe(struct platform_device *pdev)
__func__);
goto failure;
}
-
- ret = d40_lcla_allocate(base);
-
- if (ret) {
- dev_err(&pdev->dev, "[%s] Failed to allocate LCLA area\n",
- __func__);
- goto failure;
-
+ /* If lcla has to be located in ESRAM we don't need to allocate */
+ if (base->plat_data->use_esram_lcla) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "lcla_esram");
+ if (!res) {
+ ret = -ENOENT;
+ dev_err(&pdev->dev,
+ "[%s] No \"lcla_esram\" memory resource\n",
+ __func__);
+ goto failure;
+ }
+ base->lcla_pool.base = ioremap(res->start,
+ resource_size(res));
+ if (!base->lcla_pool.base) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev,
+ "[%s] Failed to ioremap LCLA region\n",
+ __func__);
+ goto failure;
+ }
+ writel(res->start, base->virtbase + D40_DREG_LCLA);
+ } else {
+ ret = d40_lcla_allocate(base);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "[%s] Failed to allocate LCLA area\n",
+ __func__);
+ goto failure;
+ }
}
#ifdef CONFIG_STE_DMA40_DEBUG
@@ -3736,12 +3762,17 @@ failure:
kmem_cache_destroy(base->desc_slab);
if (base->virtbase)
iounmap(base->virtbase);
+
+ if (base->lcla_pool.base && base->plat_data->use_esram_lcla) {
+ iounmap(base->lcla_pool.base);
+ base->lcla_pool.base = NULL;
+ }
+
if (!base->lcla_pool.base_unaligned && base->lcla_pool.base)
free_pages((unsigned long)base->lcla_pool.base,
base->lcla_pool.pages);
kfree(base->lcla_pool.base_unaligned);
-
if (base->phy_lcpa)
release_mem_region(base->phy_lcpa,
base->lcpa_size);