Skip to content

Commit

Permalink
dmaengine: sprd: Fix the link-list pointer register configuration issue
Browse files Browse the repository at this point in the history
We will set the link-list pointer register point to next link-list
configuration's physical address, which can load DMA configuration
from the link-list node automatically.

But the link-list node's physical address can be larger than 32bits,
and now Spreadtrum DMA driver only supports 32bits physical address,
which may cause loading a incorrect DMA configuration when starting
the link-list transfer mode. According to the DMA datasheet, we can
use SRC_BLK_STEP register (bit28 - bit31) to save the high bits of the
link-list node's physical address to fix this issue.

Fixes: 4ac6954 ("dmaengine: sprd: Support DMA link-list mode")
Signed-off-by: Zhenfang Wang <zhenfang.wang@unisoc.com>
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
Link: https://lore.kernel.org/r/eadfe9295499efa003e1c344e67e2890f9d1d780.1568267061.git.baolin.wang@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
  • Loading branch information
Zhenfang Wang authored and Vinod Koul committed Oct 14, 2019
1 parent 54ecb8f commit 8b6bc5f
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions drivers/dma/sprd-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@
#define SPRD_DMA_SRC_TRSF_STEP_OFFSET 0
#define SPRD_DMA_TRSF_STEP_MASK GENMASK(15, 0)

/* SPRD DMA_SRC_BLK_STEP register definition */
#define SPRD_DMA_LLIST_HIGH_MASK GENMASK(31, 28)
#define SPRD_DMA_LLIST_HIGH_SHIFT 28

/* define DMA channel mode & trigger mode mask */
#define SPRD_DMA_CHN_MODE_MASK GENMASK(7, 0)
#define SPRD_DMA_TRG_MODE_MASK GENMASK(7, 0)
Expand Down Expand Up @@ -717,6 +721,7 @@ static int sprd_dma_fill_desc(struct dma_chan *chan,
u32 int_mode = flags & SPRD_DMA_INT_MASK;
int src_datawidth, dst_datawidth, src_step, dst_step;
u32 temp, fix_mode = 0, fix_en = 0;
phys_addr_t llist_ptr;

if (dir == DMA_MEM_TO_DEV) {
src_step = sprd_dma_get_step(slave_cfg->src_addr_width);
Expand Down Expand Up @@ -814,13 +819,16 @@ static int sprd_dma_fill_desc(struct dma_chan *chan,
* Set the link-list pointer point to next link-list
* configuration's physical address.
*/
hw->llist_ptr = schan->linklist.phy_addr + temp;
llist_ptr = schan->linklist.phy_addr + temp;
hw->llist_ptr = lower_32_bits(llist_ptr);
hw->src_blk_step = (upper_32_bits(llist_ptr) << SPRD_DMA_LLIST_HIGH_SHIFT) &
SPRD_DMA_LLIST_HIGH_MASK;
} else {
hw->llist_ptr = 0;
hw->src_blk_step = 0;
}

hw->frg_step = 0;
hw->src_blk_step = 0;
hw->des_blk_step = 0;
return 0;
}
Expand Down

0 comments on commit 8b6bc5f

Please sign in to comment.