lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1c160c5169f6f5b6ff49e7478171bd5c27ff9b4b.1764927089.git.khairul.anuar.romli@altera.com>
Date: Mon,  8 Dec 2025 09:57:45 +0800
From: Khairul Anuar Romli <khairul.anuar.romli@...era.com>
To: Dinh Nguyen <dinguyen@...nel.org>,
	Rob Herring <robh@...nel.org>,
	Krzysztof Kozlowski <krzk+dt@...nel.org>,
	Conor Dooley <conor+dt@...nel.org>,
	Eugeniy Paltsev <Eugeniy.Paltsev@...opsys.com>,
	Vinod Koul <vkoul@...nel.org>,
	dmaengine@...r.kernel.org,
	devicetree@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Khairul Anuar Romli <khairul.anuar.romli@...era.com>
Subject: [PATCH v2 4/4] dma: dw-axi-dmac: Add support for Agilex5 and dynamic bus width

Add device tree compatible string support for the Altera Agilex5 AXI DMA
controller.

Introduces logic to parse the "dma-ranges" property and calculate the
actual number of addressable bits (bus width) for the DMA engine. This
calculated value is then used to set the coherent mask via
'dma_set_mask_and_coherent()', allowing the driver to correctly handle
devices with bus widths less than 64 bits. The addressable bits default to
64 if 'dma-ranges' is not specified or cannot be parsed.

Introduce 'addressable_bits' to 'struct axi_dma_chip' to store this value.

Signed-off-by: Khairul Anuar Romli <khairul.anuar.romli@...era.com>
---
Changes in v2:
	- Add driver implementation to set the DMA BIT MAST to 40 based on
	  dma-ranges defined in DT.
	- Add glue for driver and DT.
---
 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 63 ++++++++++++++++++-
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h         |  1 +
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index b23536645ff7..165481b4dde1 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -271,7 +271,9 @@ static void axi_dma_hw_init(struct axi_dma_chip *chip)
 		axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
 		axi_chan_disable(&chip->dw->chan[i]);
 	}
-	ret = dma_set_mask_and_coherent(chip->dev, DMA_BIT_MASK(64));
+
+	dev_dbg(chip->dev, "Adressable bus width: %u\n", chip->addressable_bits);
+	ret = dma_set_mask_and_coherent(chip->dev, DMA_BIT_MASK(chip->addressable_bits));
 	if (ret)
 		dev_warn(chip->dev, "Unable to set coherent mask\n");
 }
@@ -1461,13 +1463,23 @@ static int axi_req_irqs(struct platform_device *pdev, struct axi_dma_chip *chip)
 	return 0;
 }
 
+/* Forward declaration (no size required) */
+static const struct of_device_id dw_dma_of_id_table[];
+
 static int dw_probe(struct platform_device *pdev)
 {
 	struct axi_dma_chip *chip;
 	struct dw_axi_dma *dw;
 	struct dw_axi_dma_hcfg *hdata;
 	struct reset_control *resets;
+	const struct of_device_id *match;
 	unsigned int flags;
+	unsigned int addressable_bits = 64;
+	unsigned int len_bytes;
+	unsigned int num_cells;
+	const __be32 *prop;
+	u64 bus_width;
+	u32 *cells;
 	u32 i;
 	int ret;
 
@@ -1483,9 +1495,56 @@ static int dw_probe(struct platform_device *pdev)
 	if (!hdata)
 		return -ENOMEM;
 
+	match = of_match_node(dw_dma_of_id_table, pdev->dev.of_node);
+	if (!match) {
+		dev_err(&pdev->dev, "Unsupported AXI DMA device\n");
+		return -ENODEV;
+	}
+
+	prop = of_get_property(pdev->dev.of_node, "dma-ranges", &len_bytes);
+	if (prop) {
+		num_cells = len_bytes / sizeof(__be32);
+		cells = kcalloc(num_cells, sizeof(*cells), GFP_KERNEL);
+		if (!cells)
+			return -ENOMEM;
+
+		ret = of_property_read_u32(pdev->dev.of_node, "#address-cells", &i);
+		if (ret) {
+			dev_err(&pdev->dev, "missing #address-cells property\n");
+			return ret;
+		}
+
+		ret = of_property_read_u32(pdev->dev.of_node, "#size-cells", &i);
+		if (ret) {
+			dev_err(&pdev->dev, "missing #size-cells property\n");
+			return ret;
+		}
+
+		if (!of_property_read_u32_array(pdev->dev.of_node,
+						"dma-ranges", cells, num_cells)) {
+			dev_dbg(&pdev->dev, "dma-ranges numbe of cells: %u\n", num_cells);
+			// Check if size-cells is 2 cells.
+			if (i == 2 && num_cells > 3) {
+				// Combine size cells into 64-bit length
+				dev_dbg(&pdev->dev, "size-cells MSB: %u\n", cells[num_cells - 2]);
+				dev_dbg(&pdev->dev, "size-cells LSB: %u\n", cells[num_cells - 1]);
+				bus_width = ((u64)cells[num_cells - 2] << 32) |
+cells[num_cells - 1];
+			}
+
+			// Count number of bits in bus_width
+			if (bus_width)
+				addressable_bits = fls64(bus_width) - 1;
+
+			dev_dbg(&pdev->dev, "Bus width: %u bits (length: 0x%llx)\n",
+				addressable_bits, bus_width);
+		}
+	}
+
 	chip->dw = dw;
 	chip->dev = &pdev->dev;
 	chip->dw->hdata = hdata;
+	chip->addressable_bits = addressable_bits;
 
 	chip->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(chip->regs))
@@ -1669,6 +1728,8 @@ static const struct of_device_id dw_dma_of_id_table[] = {
 	}, {
 		.compatible = "starfive,jh8100-axi-dma",
 		.data = (void *)AXI_DMA_FLAG_HAS_RESETS,
+	}, {
+		.compatible = "altr,agilex5-axi-dma"
 	},
 	{}
 };
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index b842e6a8d90d..f8152f8b3798 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -71,6 +71,7 @@ struct axi_dma_chip {
 	struct clk		*core_clk;
 	struct clk		*cfgr_clk;
 	struct dw_axi_dma	*dw;
+	u32			addressable_bits;
 };
 
 /* LLI == Linked List Item */
-- 
2.43.7


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ