Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Lars-Peter Clausen and committed by
Vinod Koul
56009f0d 38a829a3

+22 -14
+2 -2
Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
··· 18 18 19 19 Required channel sub-node properties: 20 20 - reg: Which channel this node refers to. 21 - - adi,length-width: Width of the DMA transfer length register. 22 21 - adi,source-bus-width, 23 22 adi,destination-bus-width: Width of the source or destination bus in bits. 24 23 - adi,source-bus-type, ··· 27 28 1 (AXI_DMAC_TYPE_AXI_STREAM): Streaming AXI interface 28 29 2 (AXI_DMAC_TYPE_AXI_FIFO): FIFO interface 29 30 30 - Optional channel properties: 31 + Deprecated optional channel properties: 32 + - adi,length-width: Width of the DMA transfer length register. 31 33 - adi,cyclic: Must be set if the channel supports hardware cyclic DMA 32 34 transfers. 33 35 - adi,2d: Must be set if the channel supports hardware 2D DMA transfers.
+20 -12
drivers/dma/dma-axi-dmac.c
··· 618 618 return ret; 619 619 chan->dest_width = val / 8; 620 620 621 - ret = of_property_read_u32(of_chan, "adi,length-width", &val); 622 - if (ret) 623 - return ret; 624 - 625 - if (val >= 32) 626 - chan->max_length = UINT_MAX; 627 - else 628 - chan->max_length = (1ULL << val) - 1; 629 - 630 621 chan->align_mask = max(chan->dest_width, chan->src_width) - 1; 631 622 632 623 if (axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan)) ··· 629 638 else 630 639 chan->direction = DMA_DEV_TO_DEV; 631 640 632 - chan->hw_cyclic = of_property_read_bool(of_chan, "adi,cyclic"); 633 - chan->hw_2d = of_property_read_bool(of_chan, "adi,2d"); 634 - 635 641 return 0; 642 + } 643 + 644 + static void axi_dmac_detect_caps(struct axi_dmac *dmac) 645 + { 646 + struct axi_dmac_chan *chan = &dmac->chan; 647 + 648 + axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC); 649 + if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC) 650 + chan->hw_cyclic = true; 651 + 652 + axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 1); 653 + if (axi_dmac_read(dmac, AXI_DMAC_REG_Y_LENGTH) == 1) 654 + chan->hw_2d = true; 655 + 656 + axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, 0xffffffff); 657 + chan->max_length = axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH); 658 + if (chan->max_length != UINT_MAX) 659 + chan->max_length++; 636 660 } 637 661 638 662 static int axi_dmac_probe(struct platform_device *pdev) ··· 721 715 ret = clk_prepare_enable(dmac->clk); 722 716 if (ret < 0) 723 717 return ret; 718 + 719 + axi_dmac_detect_caps(dmac); 724 720 725 721 axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x00); 726 722