aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorFabio Baltieri <fabio.baltieri@linaro.org>2012-12-18 06:25:14 -0500
committerFabio Baltieri <fabio.baltieri@linaro.org>2013-01-14 04:51:08 -0500
commit7407048bec896268b50e3c43c1d012a4764dc210 (patch)
tree259a92df30b4c9e08cc0c2270bc997fa212225cb /drivers/dma
parent7ce529efbcf6fdcb1854e4634adf7f6a18216e81 (diff)
dmaengine: ste_dma40: add software lli support
This patch add support to manage LLI by SW for select phy channels. There is a HW issue in certain controllers due to which on certain occassions HW LLI cannot be used on some physical channels. To avoid the HW issue on a specific phy channel, the phy channel number can be added to the list of soft_lli_channels and there after all the transfers on that channel will use software LLI, for peripheral to memory transfers. SoftLLI introduces relink overhead, that could impact performace for certain use cases. This is based on a previous patch of Narayanan Gopalakrishnan. Cc: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/ste_dma40.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index e317debdbe5a..2ecefb7113b9 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -355,6 +355,7 @@ struct d40_lcla_pool {
355 * @allocated_dst: Same as for src but is dst. 355 * @allocated_dst: Same as for src but is dst.
356 * allocated_dst and allocated_src uses the D40_ALLOC* defines as well as 356 * allocated_dst and allocated_src uses the D40_ALLOC* defines as well as
357 * event line number. 357 * event line number.
358 * @use_soft_lli: To mark if the linked lists of channel are managed by SW.
358 */ 359 */
359struct d40_phy_res { 360struct d40_phy_res {
360 spinlock_t lock; 361 spinlock_t lock;
@@ -362,6 +363,7 @@ struct d40_phy_res {
362 int num; 363 int num;
363 u32 allocated_src; 364 u32 allocated_src;
364 u32 allocated_dst; 365 u32 allocated_dst;
366 bool use_soft_lli;
365}; 367};
366 368
367struct d40_base; 369struct d40_base;
@@ -783,7 +785,16 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc)
783 * can't link back to the one in LCPA space 785 * can't link back to the one in LCPA space
784 */ 786 */
785 if (linkback || (lli_len - lli_current > 1)) { 787 if (linkback || (lli_len - lli_current > 1)) {
786 curr_lcla = d40_lcla_alloc_one(chan, desc); 788 /*
789 * If the channel is expected to use only soft_lli don't
790 * allocate a lcla. This is to avoid a HW issue that exists
791 * in some controller during a peripheral to memory transfer
792 * that uses linked lists.
793 */
794 if (!(chan->phy_chan->use_soft_lli &&
795 chan->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM))
796 curr_lcla = d40_lcla_alloc_one(chan, desc);
797
787 first_lcla = curr_lcla; 798 first_lcla = curr_lcla;
788 } 799 }
789 800
@@ -3063,6 +3074,13 @@ static int __init d40_phy_res_init(struct d40_base *base)
3063 num_phy_chans_avail--; 3074 num_phy_chans_avail--;
3064 } 3075 }
3065 3076
3077 /* Mark soft_lli channels */
3078 for (i = 0; i < base->plat_data->num_of_soft_lli_chans; i++) {
3079 int chan = base->plat_data->soft_lli_chans[i];
3080
3081 base->phy_res[chan].use_soft_lli = true;
3082 }
3083
3066 dev_info(base->dev, "%d of %d physical DMA channels available\n", 3084 dev_info(base->dev, "%d of %d physical DMA channels available\n",
3067 num_phy_chans_avail, base->num_phy_chans); 3085 num_phy_chans_avail, base->num_phy_chans);
3068 3086