[PATCH 2/2] PCI: xilinx-cpm: Add support for Versal Net CPM5NC Root Port controller

Thippeswamy Havalige posted 2 patches 12 months ago
There is a newer version of this series
[PATCH 2/2] PCI: xilinx-cpm: Add support for Versal Net CPM5NC Root Port controller
Posted by Thippeswamy Havalige 12 months ago
The Versal Net ACAP (Adaptive Compute Acceleration Platform) devices
incorporate the Coherency and PCIe Gen5 Module, specifically the
Next-Generation Compact Module (CPM5NC).

The integrated CPM5NC block, along with the built-in bridge, can function
as a PCIe Root Port & supports the PCIe Gen5 protocol with data transfer
rates of up to 32 GT/s, capable of supporting up to a x16 lane-width
configuration.

Bridge errors are managed using a specific interrupt line designed for
CPM5N. Legacy interrupt support is not available.

Currently in this patch Bridge errors support is not added.

Signed-off-by: Thippeswamy Havalige <thippeswamy.havalige@amd.com>
---
 drivers/pci/controller/pcie-xilinx-cpm.c | 85 ++++++++++++++----------
 1 file changed, 51 insertions(+), 34 deletions(-)

diff --git a/drivers/pci/controller/pcie-xilinx-cpm.c b/drivers/pci/controller/pcie-xilinx-cpm.c
index 81e8bfae53d0..c26ba662efd7 100644
--- a/drivers/pci/controller/pcie-xilinx-cpm.c
+++ b/drivers/pci/controller/pcie-xilinx-cpm.c
@@ -84,6 +84,7 @@ enum xilinx_cpm_version {
 	CPM,
 	CPM5,
 	CPM5_HOST1,
+	CPM5NC_HOST,
 };
 
 /**
@@ -483,31 +484,33 @@ static void xilinx_cpm_pcie_init_port(struct xilinx_cpm_pcie *port)
 	else
 		dev_info(port->dev, "PCIe Link is DOWN\n");
 
-	/* Disable all interrupts */
-	pcie_write(port, ~XILINX_CPM_PCIE_IDR_ALL_MASK,
-		   XILINX_CPM_PCIE_REG_IMR);
-
-	/* Clear pending interrupts */
-	pcie_write(port, pcie_read(port, XILINX_CPM_PCIE_REG_IDR) &
-		   XILINX_CPM_PCIE_IMR_ALL_MASK,
-		   XILINX_CPM_PCIE_REG_IDR);
-
-	/*
-	 * XILINX_CPM_PCIE_MISC_IR_ENABLE register is mapped to
-	 * CPM SLCR block.
-	 */
-	writel(variant->ir_misc_value,
-	       port->cpm_base + XILINX_CPM_PCIE_MISC_IR_ENABLE);
+	if (variant->version != CPM5NC_HOST) {
+		/* Disable all interrupts */
+		pcie_write(port, ~XILINX_CPM_PCIE_IDR_ALL_MASK,
+			   XILINX_CPM_PCIE_REG_IMR);
+
+		/* Clear pending interrupts */
+		pcie_write(port, pcie_read(port, XILINX_CPM_PCIE_REG_IDR) &
+			   XILINX_CPM_PCIE_IMR_ALL_MASK,
+			   XILINX_CPM_PCIE_REG_IDR);
+
+		/*
+		 * XILINX_CPM_PCIE_MISC_IR_ENABLE register is mapped to
+		 * CPM SLCR block.
+		 */
+		writel(variant->ir_misc_value,
+		       port->cpm_base + XILINX_CPM_PCIE_MISC_IR_ENABLE);
+
+		if (variant->ir_enable) {
+			writel(XILINX_CPM_PCIE_IR_LOCAL,
+			       port->cpm_base + variant->ir_enable);
+		}
 
-	if (variant->ir_enable) {
-		writel(XILINX_CPM_PCIE_IR_LOCAL,
-		       port->cpm_base + variant->ir_enable);
+		/* Set Bridge enable bit */
+		pcie_write(port, pcie_read(port, XILINX_CPM_PCIE_REG_RPSC) |
+			   XILINX_CPM_PCIE_REG_RPSC_BEN,
+			   XILINX_CPM_PCIE_REG_RPSC);
 	}
-
-	/* Set Bridge enable bit */
-	pcie_write(port, pcie_read(port, XILINX_CPM_PCIE_REG_RPSC) |
-		   XILINX_CPM_PCIE_REG_RPSC_BEN,
-		   XILINX_CPM_PCIE_REG_RPSC);
 }
 
 /**
@@ -578,16 +581,18 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
 
 	port->dev = dev;
 
-	err = xilinx_cpm_pcie_init_irq_domain(port);
-	if (err)
-		return err;
+	port->variant = of_device_get_match_data(dev);
+
+	if (port->variant->version != CPM5NC_HOST) {
+		err = xilinx_cpm_pcie_init_irq_domain(port);
+		if (err)
+			return err;
+	}
 
 	bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
 	if (!bus)
 		return -ENODEV;
 
-	port->variant = of_device_get_match_data(dev);
-
 	err = xilinx_cpm_pcie_parse_dt(port, bus->res);
 	if (err) {
 		dev_err(dev, "Parsing DT failed\n");
@@ -596,10 +601,12 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
 
 	xilinx_cpm_pcie_init_port(port);
 
-	err = xilinx_cpm_setup_irq(port);
-	if (err) {
-		dev_err(dev, "Failed to set up interrupts\n");
-		goto err_setup_irq;
+	if (port->variant->version != CPM5NC_HOST) {
+		err = xilinx_cpm_setup_irq(port);
+		if (err) {
+			dev_err(dev, "Failed to set up interrupts\n");
+			goto err_setup_irq;
+		}
 	}
 
 	bridge->sysdata = port->cfg;
@@ -612,11 +619,13 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
 	return 0;
 
 err_host_bridge:
-	xilinx_cpm_free_interrupts(port);
+	if (port->variant->version != CPM5NC_HOST)
+		xilinx_cpm_free_interrupts(port);
 err_setup_irq:
 	pci_ecam_free(port->cfg);
 err_parse_dt:
-	xilinx_cpm_free_irq_domains(port);
+	if (port->variant->version != CPM5NC_HOST)
+		xilinx_cpm_free_irq_domains(port);
 	return err;
 }
 
@@ -639,6 +648,10 @@ static const struct xilinx_cpm_variant cpm5_host1 = {
 	.ir_enable = XILINX_CPM_PCIE1_IR_ENABLE,
 };
 
+static const struct xilinx_cpm_variant cpm5n_host = {
+	.version = CPM5NC_HOST,
+};
+
 static const struct of_device_id xilinx_cpm_pcie_of_match[] = {
 	{
 		.compatible = "xlnx,versal-cpm-host-1.00",
@@ -652,6 +665,10 @@ static const struct of_device_id xilinx_cpm_pcie_of_match[] = {
 		.compatible = "xlnx,versal-cpm5-host1",
 		.data = &cpm5_host1,
 	},
+	{
+		.compatible = "xlnx,versal-cpm5nc-host",
+		.data = &cpm5n_host,
+	},
 	{}
 };
 
-- 
2.43.0
Re: [PATCH 2/2] PCI: xilinx-cpm: Add support for Versal Net CPM5NC Root Port controller
Posted by Bjorn Helgaas 12 months ago
On Tue, Feb 11, 2025 at 01:47:24PM +0530, Thippeswamy Havalige wrote:
> The Versal Net ACAP (Adaptive Compute Acceleration Platform) devices
> incorporate the Coherency and PCIe Gen5 Module, specifically the
> Next-Generation Compact Module (CPM5NC).
> 
> The integrated CPM5NC block, along with the built-in bridge, can function
> as a PCIe Root Port & supports the PCIe Gen5 protocol with data transfer
> rates of up to 32 GT/s, capable of supporting up to a x16 lane-width
> configuration.
> 
> Bridge errors are managed using a specific interrupt line designed for
> CPM5N. Legacy interrupt support is not available.

I guess this means INTx support is not available?

If so, I'd like to say "INTx" instead of "legacy" to be more specific.
Someday "MSI" may also be considered "legacy".

Bjorn