diff options
author | Fabio Baltieri <fabio.baltieri@linaro.org> | 2012-12-18 06:25:14 -0500 |
---|---|---|
committer | Fabio Baltieri <fabio.baltieri@linaro.org> | 2013-01-14 04:51:08 -0500 |
commit | 7407048bec896268b50e3c43c1d012a4764dc210 (patch) | |
tree | 259a92df30b4c9e08cc0c2270bc997fa212225cb /drivers/dma | |
parent | 7ce529efbcf6fdcb1854e4634adf7f6a18216e81 (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.c | 20 |
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 | */ |
359 | struct d40_phy_res { | 360 | struct 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 | ||
367 | struct d40_base; | 369 | struct 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 | ||