Unverified Commit ad3b7174 authored by Thippeswamy Havalige's avatar Thippeswamy Havalige Committed by Krzysztof Wilczyński
Browse files

PCI: xilinx-cpm: Add support for Versal Net CPM5NC Root Port controller



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 and supports the PCIe Gen5 protocol with data transfer
rates of up to 32 GT/s, and is capable of supporting up to a x16 lane-width
configuration.

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

Currently in this commit platform specific bridge errors support is not
added.

Signed-off-by: default avatarThippeswamy Havalige <thippeswamy.havalige@amd.com>
[kwilczynski: commit log, squashed patch to fix an if-statement condition
to ensure that xilinx_cpm_pcie_init_port() does not run on the CPM5NC_HOST
variant from https://lore.kernel.org/linux-pci/20250311072402.1049990-1-thippeswamy.havalige@amd.com

]
Signed-off-by: default avatarKrzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20250224155025.782179-4-thippeswamy.havalige@amd.com
parent ce095c59
Loading
Loading
Loading
Loading
+29 −11
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ enum xilinx_cpm_version {
	CPM,
	CPM5,
	CPM5_HOST1,
	CPM5NC_HOST,
};

/**
@@ -478,6 +479,9 @@ static void xilinx_cpm_pcie_init_port(struct xilinx_cpm_pcie *port)
{
	const struct xilinx_cpm_variant *variant = port->variant;

	if (variant->version == CPM5NC_HOST)
		return;

	if (cpm_pcie_link_up(port))
		dev_info(port->dev, "PCIe Link is UP\n");
	else
@@ -578,9 +582,13 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)

	port->dev = dev;

	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) {
@@ -588,8 +596,6 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
		goto err_free_irq_domains;
	}

	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");
@@ -598,11 +604,13 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)

	xilinx_cpm_pcie_init_port(port);

	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;
	bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops;
@@ -614,10 +622,12 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
	return 0;

err_host_bridge:
	if (port->variant->version != CPM5NC_HOST)
		xilinx_cpm_free_interrupts(port);
err_setup_irq:
	pci_ecam_free(port->cfg);
err_free_irq_domains:
	if (port->variant->version != CPM5NC_HOST)
		xilinx_cpm_free_irq_domains(port);
	return err;
}
@@ -641,6 +651,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",
@@ -654,6 +668,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,
	},
	{}
};