dmaengine: zynqmp_dma: fix burst length configuration
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>
This commit is contained in:
parent
ffc079a4ac
commit
cc88525ebf
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue
Block a user