lkml.org 
[lkml]   [2019]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 092/193] dmaengine: sprd: Fix the link-list pointer register configuration issue
    Date
    From: Zhenfang Wang <zhenfang.wang@unisoc.com>

    [ Upstream commit 8b6bc5fd71e677864d1a3b896b3069a6e0c5e214 ]

    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: 4ac695464763 ("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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/dma/sprd-dma.c | 12 ++++++++++--
    1 file changed, 10 insertions(+), 2 deletions(-)

    diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
    index 525dc7338fe3b..a4a91f233121a 100644
    --- a/drivers/dma/sprd-dma.c
    +++ b/drivers/dma/sprd-dma.c
    @@ -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)
    @@ -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);
    @@ -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;
    }
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-11-11 20:01    [W:5.267 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site