aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/ste_dma40.c
diff options
context:
space:
mode:
authorNarayanan G <narayanan.gopalakrishnan@stericsson.com>2011-11-22 03:26:55 -0500
committerVinod Koul <vinod.koul@linux.intel.com>2011-11-27 22:30:08 -0500
commit28c7a19d230228ab9ae61c300c5003a2400fadd3 (patch)
treed66f1e8a74528afc4226df129dcaf5f3abb97f1d /drivers/dma/ste_dma40.c
parentd5613947addb1e1096a3be29dfe817905e385469 (diff)
dmaengine/ste_dma40: Add support to use lcla area from esram
This patch provides an option of having the lcla (link address) 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. Also, the corresponding esram regulator is managed in the suspend/resume functions. Signed-off-by: Narayanan G <narayanan.gopalakrishnan@stericsson.com> Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
Diffstat (limited to 'drivers/dma/ste_dma40.c')
-rw-r--r--drivers/dma/ste_dma40.c95
1 files changed, 85 insertions, 10 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index c2cf8cfaf7d4..aff128a39a4b 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -304,6 +304,7 @@ struct d40_chan {
304 * to phy_chans entries. 304 * to phy_chans entries.
305 * @plat_data: Pointer to provided platform_data which is the driver 305 * @plat_data: Pointer to provided platform_data which is the driver
306 * configuration. 306 * configuration.
307 * @lcpa_regulator: Pointer to hold the regulator for the esram bank for lcla.
307 * @phy_res: Vector containing all physical channels. 308 * @phy_res: Vector containing all physical channels.
308 * @lcla_pool: lcla pool settings and data. 309 * @lcla_pool: lcla pool settings and data.
309 * @lcpa_base: The virtual mapped address of LCPA. 310 * @lcpa_base: The virtual mapped address of LCPA.
@@ -338,6 +339,7 @@ struct d40_base {
338 struct d40_chan **lookup_log_chans; 339 struct d40_chan **lookup_log_chans;
339 struct d40_chan **lookup_phy_chans; 340 struct d40_chan **lookup_phy_chans;
340 struct stedma40_platform_data *plat_data; 341 struct stedma40_platform_data *plat_data;
342 struct regulator *lcpa_regulator;
341 /* Physical half channels */ 343 /* Physical half channels */
342 struct d40_phy_res *phy_res; 344 struct d40_phy_res *phy_res;
343 struct d40_lcla_pool lcla_pool; 345 struct d40_lcla_pool lcla_pool;
@@ -605,6 +607,7 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc)
605 bool cyclic = desc->cyclic; 607 bool cyclic = desc->cyclic;
606 int curr_lcla = -EINVAL; 608 int curr_lcla = -EINVAL;
607 int first_lcla = 0; 609 int first_lcla = 0;
610 bool use_esram_lcla = chan->base->plat_data->use_esram_lcla;
608 bool linkback; 611 bool linkback;
609 612
610 /* 613 /*
@@ -677,11 +680,16 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc)
677 &lli->src[lli_current], 680 &lli->src[lli_current],
678 next_lcla, flags); 681 next_lcla, flags);
679 682
680 dma_sync_single_range_for_device(chan->base->dev, 683 /*
681 pool->dma_addr, lcla_offset, 684 * Cache maintenance is not needed if lcla is
682 2 * sizeof(struct d40_log_lli), 685 * mapped in esram
683 DMA_TO_DEVICE); 686 */
684 687 if (!use_esram_lcla) {
688 dma_sync_single_range_for_device(chan->base->dev,
689 pool->dma_addr, lcla_offset,
690 2 * sizeof(struct d40_log_lli),
691 DMA_TO_DEVICE);
692 }
685 curr_lcla = next_lcla; 693 curr_lcla = next_lcla;
686 694
687 if (curr_lcla == -EINVAL || curr_lcla == first_lcla) { 695 if (curr_lcla == -EINVAL || curr_lcla == first_lcla) {
@@ -2668,10 +2676,15 @@ failure1:
2668#ifdef CONFIG_PM 2676#ifdef CONFIG_PM
2669static int dma40_pm_suspend(struct device *dev) 2677static int dma40_pm_suspend(struct device *dev)
2670{ 2678{
2679 struct platform_device *pdev = to_platform_device(dev);
2680 struct d40_base *base = platform_get_drvdata(pdev);
2681 int ret = 0;
2671 if (!pm_runtime_suspended(dev)) 2682 if (!pm_runtime_suspended(dev))
2672 return -EBUSY; 2683 return -EBUSY;
2673 2684
2674 return 0; 2685 if (base->lcpa_regulator)
2686 ret = regulator_disable(base->lcpa_regulator);
2687 return ret;
2675} 2688}
2676 2689
2677static int dma40_runtime_suspend(struct device *dev) 2690static int dma40_runtime_suspend(struct device *dev)
@@ -2702,11 +2715,23 @@ static int dma40_runtime_resume(struct device *dev)
2702 return 0; 2715 return 0;
2703} 2716}
2704 2717
2718static int dma40_resume(struct device *dev)
2719{
2720 struct platform_device *pdev = to_platform_device(dev);
2721 struct d40_base *base = platform_get_drvdata(pdev);
2722 int ret = 0;
2723
2724 if (base->lcpa_regulator)
2725 ret = regulator_enable(base->lcpa_regulator);
2726
2727 return ret;
2728}
2705 2729
2706static const struct dev_pm_ops dma40_pm_ops = { 2730static const struct dev_pm_ops dma40_pm_ops = {
2707 .suspend = dma40_pm_suspend, 2731 .suspend = dma40_pm_suspend,
2708 .runtime_suspend = dma40_runtime_suspend, 2732 .runtime_suspend = dma40_runtime_suspend,
2709 .runtime_resume = dma40_runtime_resume, 2733 .runtime_resume = dma40_runtime_resume,
2734 .resume = dma40_resume,
2710}; 2735};
2711#define DMA40_PM_OPS (&dma40_pm_ops) 2736#define DMA40_PM_OPS (&dma40_pm_ops)
2712#else 2737#else
@@ -3165,11 +3190,31 @@ static int __init d40_probe(struct platform_device *pdev)
3165 d40_err(&pdev->dev, "Failed to ioremap LCPA region\n"); 3190 d40_err(&pdev->dev, "Failed to ioremap LCPA region\n");
3166 goto failure; 3191 goto failure;
3167 } 3192 }
3193 /* If lcla has to be located in ESRAM we don't need to allocate */
3194 if (base->plat_data->use_esram_lcla) {
3195 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
3196 "lcla_esram");
3197 if (!res) {
3198 ret = -ENOENT;
3199 d40_err(&pdev->dev,
3200 "No \"lcla_esram\" memory resource\n");
3201 goto failure;
3202 }
3203 base->lcla_pool.base = ioremap(res->start,
3204 resource_size(res));
3205 if (!base->lcla_pool.base) {
3206 ret = -ENOMEM;
3207 d40_err(&pdev->dev, "Failed to ioremap LCLA region\n");
3208 goto failure;
3209 }
3210 writel(res->start, base->virtbase + D40_DREG_LCLA);
3168 3211
3169 ret = d40_lcla_allocate(base); 3212 } else {
3170 if (ret) { 3213 ret = d40_lcla_allocate(base);
3171 d40_err(&pdev->dev, "Failed to allocate LCLA area\n"); 3214 if (ret) {
3172 goto failure; 3215 d40_err(&pdev->dev, "Failed to allocate LCLA area\n");
3216 goto failure;
3217 }
3173 } 3218 }
3174 3219
3175 spin_lock_init(&base->lcla_pool.lock); 3220 spin_lock_init(&base->lcla_pool.lock);
@@ -3187,6 +3232,26 @@ static int __init d40_probe(struct platform_device *pdev)
3187 pm_runtime_use_autosuspend(base->dev); 3232 pm_runtime_use_autosuspend(base->dev);
3188 pm_runtime_enable(base->dev); 3233 pm_runtime_enable(base->dev);
3189 pm_runtime_resume(base->dev); 3234 pm_runtime_resume(base->dev);
3235
3236 if (base->plat_data->use_esram_lcla) {
3237
3238 base->lcpa_regulator = regulator_get(base->dev, "lcla_esram");
3239 if (IS_ERR(base->lcpa_regulator)) {
3240 d40_err(&pdev->dev, "Failed to get lcpa_regulator\n");
3241 base->lcpa_regulator = NULL;
3242 goto failure;
3243 }
3244
3245 ret = regulator_enable(base->lcpa_regulator);
3246 if (ret) {
3247 d40_err(&pdev->dev,
3248 "Failed to enable lcpa_regulator\n");
3249 regulator_put(base->lcpa_regulator);
3250 base->lcpa_regulator = NULL;
3251 goto failure;
3252 }
3253 }
3254
3190 base->initialized = true; 3255 base->initialized = true;
3191 err = d40_dmaengine_init(base, num_reserved_chans); 3256 err = d40_dmaengine_init(base, num_reserved_chans);
3192 if (err) 3257 if (err)
@@ -3204,6 +3269,11 @@ failure:
3204 if (base->virtbase) 3269 if (base->virtbase)
3205 iounmap(base->virtbase); 3270 iounmap(base->virtbase);
3206 3271
3272 if (base->lcla_pool.base && base->plat_data->use_esram_lcla) {
3273 iounmap(base->lcla_pool.base);
3274 base->lcla_pool.base = NULL;
3275 }
3276
3207 if (base->lcla_pool.dma_addr) 3277 if (base->lcla_pool.dma_addr)
3208 dma_unmap_single(base->dev, base->lcla_pool.dma_addr, 3278 dma_unmap_single(base->dev, base->lcla_pool.dma_addr,
3209 SZ_1K * base->num_phy_chans, 3279 SZ_1K * base->num_phy_chans,
@@ -3226,6 +3296,11 @@ failure:
3226 clk_put(base->clk); 3296 clk_put(base->clk);
3227 } 3297 }
3228 3298
3299 if (base->lcpa_regulator) {
3300 regulator_disable(base->lcpa_regulator);
3301 regulator_put(base->lcpa_regulator);
3302 }
3303
3229 kfree(base->lcla_pool.alloc_map); 3304 kfree(base->lcla_pool.alloc_map);
3230 kfree(base->lookup_log_chans); 3305 kfree(base->lookup_log_chans);
3231 kfree(base->lookup_phy_chans); 3306 kfree(base->lookup_phy_chans);