diff options
author | Narayanan G <narayanan.gopalakrishnan@stericsson.com> | 2011-09-15 18:58:35 +0530 |
---|---|---|
committer | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-09-22 15:41:23 +0530 |
commit | ff06a7b800df8a7dd93981b8971c572dcd897f49 (patch) | |
tree | ca17817c010aa9728b53cf605dde46ed93f53724 | |
parent | 2c2d45d3b5b47e3fbe055ea4793e5917a1cbfa6a (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.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/include/plat/ste_dma40.h | 2 | ||||
-rw-r--r-- | drivers/dma/ste_dma40.c | 59 |
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); |