lkml.org 
[lkml]   [2020]   [Sep]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.4 098/330] dmaengine: zynqmp_dma: fix burst length configuration
    Date
    From: Matthias Fend <matthias.fend@wolfvision.net>

    [ Upstream commit cc88525ebffc757e00cc5a5d61da6271646c7f5f ]

    Since the dma engine expects the burst length register content as
    power of 2 value, the burst length needs to be converted first.
    Additionally add a burst length range check to avoid corrupting unrelated
    register bits.

    Signed-off-by: Matthias Fend <matthias.fend@wolfvision.net>
    Link: https://lore.kernel.org/r/20200115102249.24398-1-matthias.fend@wolfvision.net
    Signed-off-by: Vinod Koul <vkoul@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/dma/xilinx/zynqmp_dma.c | 24 +++++++++++++++---------
    1 file changed, 15 insertions(+), 9 deletions(-)

    diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
    index 9c845c07b107c..d47749a35863f 100644
    --- a/drivers/dma/xilinx/zynqmp_dma.c
    +++ b/drivers/dma/xilinx/zynqmp_dma.c
    @@ -123,10 +123,12 @@
    /* Max transfer size per descriptor */
    #define ZYNQMP_DMA_MAX_TRANS_LEN 0x40000000

    +/* Max burst lengths */
    +#define ZYNQMP_DMA_MAX_DST_BURST_LEN 32768U
    +#define ZYNQMP_DMA_MAX_SRC_BURST_LEN 32768U
    +
    /* Reset values for data attributes */
    #define ZYNQMP_DMA_AXCACHE_VAL 0xF
    -#define ZYNQMP_DMA_ARLEN_RST_VAL 0xF
    -#define ZYNQMP_DMA_AWLEN_RST_VAL 0xF

    #define ZYNQMP_DMA_SRC_ISSUE_RST_VAL 0x1F

    @@ -534,17 +536,19 @@ static void zynqmp_dma_handle_ovfl_int(struct zynqmp_dma_chan *chan, u32 status)

    static void zynqmp_dma_config(struct zynqmp_dma_chan *chan)
    {
    - u32 val;
    + u32 val, burst_val;

    val = readl(chan->regs + ZYNQMP_DMA_CTRL0);
    val |= ZYNQMP_DMA_POINT_TYPE_SG;
    writel(val, chan->regs + ZYNQMP_DMA_CTRL0);

    val = readl(chan->regs + ZYNQMP_DMA_DATA_ATTR);
    + burst_val = __ilog2_u32(chan->src_burst_len);
    val = (val & ~ZYNQMP_DMA_ARLEN) |
    - (chan->src_burst_len << ZYNQMP_DMA_ARLEN_OFST);
    + ((burst_val << ZYNQMP_DMA_ARLEN_OFST) & ZYNQMP_DMA_ARLEN);
    + burst_val = __ilog2_u32(chan->dst_burst_len);
    val = (val & ~ZYNQMP_DMA_AWLEN) |
    - (chan->dst_burst_len << ZYNQMP_DMA_AWLEN_OFST);
    + ((burst_val << ZYNQMP_DMA_AWLEN_OFST) & ZYNQMP_DMA_AWLEN);
    writel(val, chan->regs + ZYNQMP_DMA_DATA_ATTR);
    }

    @@ -560,8 +564,10 @@ static int zynqmp_dma_device_config(struct dma_chan *dchan,
    {
    struct zynqmp_dma_chan *chan = to_chan(dchan);

    - chan->src_burst_len = config->src_maxburst;
    - chan->dst_burst_len = config->dst_maxburst;
    + chan->src_burst_len = clamp(config->src_maxburst, 1U,
    + ZYNQMP_DMA_MAX_SRC_BURST_LEN);
    + chan->dst_burst_len = clamp(config->dst_maxburst, 1U,
    + ZYNQMP_DMA_MAX_DST_BURST_LEN);

    return 0;
    }
    @@ -887,8 +893,8 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev,
    return PTR_ERR(chan->regs);

    chan->bus_width = ZYNQMP_DMA_BUS_WIDTH_64;
    - chan->dst_burst_len = ZYNQMP_DMA_AWLEN_RST_VAL;
    - chan->src_burst_len = ZYNQMP_DMA_ARLEN_RST_VAL;
    + chan->dst_burst_len = ZYNQMP_DMA_MAX_DST_BURST_LEN;
    + chan->src_burst_len = ZYNQMP_DMA_MAX_SRC_BURST_LEN;
    err = of_property_read_u32(node, "xlnx,bus-width", &chan->bus_width);
    if (err < 0) {
    dev_err(&pdev->dev, "missing xlnx,bus-width property\n");
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-09-18 05:10    [W:4.040 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site