diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2019-03-26 14:06:28 +0100 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2019-04-24 07:34:09 +0200 |
commit | 56009f0d2f54e4ce4305d65ce589eee6c22ac25f (patch) | |
tree | 55cdf9644bc0d9ea4045d16514f4cec4e9f5208c /drivers/dma/dma-axi-dmac.c | |
parent | dmaengine: at_xdmac: only monitor overflow errors for peripheral xfer (diff) | |
download | linux-56009f0d2f54e4ce4305d65ce589eee6c22ac25f.tar.xz linux-56009f0d2f54e4ce4305d65ce589eee6c22ac25f.zip |
dmaengine: axi-dmac: Infer synthesis configuration parameters hardware
Some synthesis time configuration parameters of the DMA controller can be
inferred from the hardware itself.
Use this information as it is more reliably than the information specified
in the devicetree which might be outdated if the HDL project got changed.
Deprecate the devicetree properties that can be inferred from the hardware
itself.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to '')
-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); |