Patchwork dmaengine: axi-dmac: Infer synthesis configuration parameters hardware

login
register
mail settings
Submitter Alexandru Ardelean
Date March 26, 2019, 1:06 p.m.
Message ID <20190326130628.10121-1-alexandru.ardelean@analog.com>
Download mbox | patch
Permalink /patch/757985/
State New
Headers show

Comments

Alexandru Ardelean - March 26, 2019, 1:06 p.m.
From: Lars-Peter Clausen <lars@metafoo.de>

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>
---
 .../devicetree/bindings/dma/adi,axi-dmac.txt  |  4 +--
 drivers/dma/dma-axi-dmac.c                    | 32 ++++++++++++-------
 2 files changed, 22 insertions(+), 14 deletions(-)
Vinod Koul - April 24, 2019, 5:36 a.m.
On 26-03-19, 15:06, Alexandru Ardelean wrote:
> From: Lars-Peter Clausen <lars@metafoo.de>
> 
> 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.

Applied, thanks

Patch

diff --git a/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt b/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
index 47cb1d14b690..b38ee732efa9 100644
--- a/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
+++ b/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
@@ -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.
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);