dmaengine: axi-dmac: Infer synthesis configuration parameters hardware
authorLars-Peter Clausen <lars@metafoo.de>
Tue, 26 Mar 2019 13:06:28 +0000 (15:06 +0200)
committerVinod Koul <vkoul@kernel.org>
Wed, 24 Apr 2019 05:34:09 +0000 (11:04 +0530)
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>
Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
drivers/dma/dma-axi-dmac.c

index 47cb1d14b690f0f0c7051733f6fc6648984bd560..b38ee732efa9fd5f857b207c8941ca17acf83c5f 100644 (file)
@@ -18,7 +18,6 @@ Required properties for adi,channels sub-node:
 
 Required channel sub-node properties:
  - reg: Which channel this node refers to.
- - adi,length-width: Width of the DMA transfer length register.
  - adi,source-bus-width,
    adi,destination-bus-width: Width of the source or destination bus in bits.
  - adi,source-bus-type,
@@ -28,7 +27,8 @@ Required channel sub-node properties:
        1 (AXI_DMAC_TYPE_AXI_STREAM): Streaming AXI interface
        2 (AXI_DMAC_TYPE_AXI_FIFO): FIFO interface
 
-Optional channel properties:
+Deprecated optional channel properties:
+ - adi,length-width: Width of the DMA transfer length register.
  - adi,cyclic: Must be set if the channel supports hardware cyclic DMA
    transfers.
  - adi,2d: Must be set if the channel supports hardware 2D DMA transfers.
index 0fe3a931d8d5396b6c3a6075a337278f009a910f..eecb367b4f3e42293ca5499b566b08e2b07afe95 100644 (file)
@@ -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);