diff options
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/dma-axi-dmac.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index 0fe3a931d8d5..eecb367b4f3e 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c @@ -618,15 +618,6 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan, return ret; chan->dest_width = val / 8; - ret = of_property_read_u32(of_chan, "adi,length-width", &val); - if (ret) - return ret; - - if (val >= 32) - chan->max_length = UINT_MAX; - else - chan->max_length = (1ULL << val) - 1; - chan->align_mask = max(chan->dest_width, chan->src_width) - 1; if (axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan)) @@ -638,12 +629,27 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan, else chan->direction = DMA_DEV_TO_DEV; - chan->hw_cyclic = of_property_read_bool(of_chan, "adi,cyclic"); - chan->hw_2d = of_property_read_bool(of_chan, "adi,2d"); - return 0; } +static void axi_dmac_detect_caps(struct axi_dmac *dmac) +{ + struct axi_dmac_chan *chan = &dmac->chan; + + axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC); + if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC) + chan->hw_cyclic = true; + + axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 1); + if (axi_dmac_read(dmac, AXI_DMAC_REG_Y_LENGTH) == 1) + chan->hw_2d = true; + + axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, 0xffffffff); + chan->max_length = axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH); + if (chan->max_length != UINT_MAX) + chan->max_length++; +} + static int axi_dmac_probe(struct platform_device *pdev) { struct device_node *of_channels, *of_chan; @@ -716,6 +722,8 @@ static int axi_dmac_probe(struct platform_device *pdev) if (ret < 0) return ret; + axi_dmac_detect_caps(dmac); + axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x00); ret = dma_async_device_register(dma_dev); |