aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/pci_mcfg.c1
-rw-r--r--drivers/pci/controller/pcie-n1sdp.c36
-rw-r--r--include/linux/pci-ecam.h1
3 files changed, 35 insertions, 3 deletions
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
index f7a7d6e87780..0523f485c930 100644
--- a/drivers/acpi/pci_mcfg.c
+++ b/drivers/acpi/pci_mcfg.c
@@ -149,6 +149,7 @@ static struct mcfg_fixup mcfg_quirks[] = {
/* N1SDP SoC with v1 PCIe controller */
N1SDP_ECAM_MCFG(0x20181101, 0, &pci_n1sdp_pcie_ecam_ops),
N1SDP_ECAM_MCFG(0x20181101, 1, &pci_n1sdp_ccix_ecam_ops),
+ N1SDP_ECAM_MCFG(0x20181101, 2, &pci_n1sdp_remote_pcie_ecam_ops),
#define ALTRA_ECAM_QUIRK(rev, seg) \
{ "Ampere", "Altra ", rev, seg, MCFG_BUS_ANY, &pci_32b_read_ops }
diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c
index 45bbe506045a..01f601e36343 100644
--- a/drivers/pci/controller/pcie-n1sdp.c
+++ b/drivers/pci/controller/pcie-n1sdp.c
@@ -28,8 +28,11 @@
/* Platform specific values as hardcoded in the firmware. */
#define AP_NS_SHARED_MEM_BASE 0x06000000
-#define MAX_SEGMENTS 2
+
+/* Two PCIe root complexes in One Chip + One PCIe RC in Remote Chip*/
+#define MAX_SEGMENTS 3
#define BDF_TABLE_SIZE SZ_16K
+#define REMOTE_CHIP_ADDR_OFFSET 0x40000000000
/*
* Shared memory layout as written by the SCP upon boot time:
@@ -100,7 +103,10 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment)
if (segment >= MAX_SEGMENTS)
return -ENODEV;
- table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE;
+ if (segment > 1)
+ table_base = AP_NS_SHARED_MEM_BASE + REMOTE_CHIP_ADDR_OFFSET;
+ else
+ table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE;
if (!request_mem_region(table_base, BDF_TABLE_SIZE,
"PCIe valid BDFs")) {
@@ -122,9 +128,15 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment)
memcpy_fromio(pcie_discovery_data[segment], shared_data, bdfs_size);
- rc_remapped_addr[segment] = devm_ioremap(dev,
+ if (segment > 1)
+ rc_remapped_addr[segment] = devm_ioremap(dev,
+ shared_data->rc_base_addr + REMOTE_CHIP_ADDR_OFFSET,
+ PCI_CFG_SPACE_EXP_SIZE);
+ else
+ rc_remapped_addr[segment] = devm_ioremap(dev,
shared_data->rc_base_addr,
PCI_CFG_SPACE_EXP_SIZE);
+
if (!rc_remapped_addr[segment]) {
dev_err(dev, "Cannot remap root port base\n");
return -ENOMEM;
@@ -145,6 +157,11 @@ static int pci_n1sdp_ccix_init(struct pci_config_window *cfg)
return pci_n1sdp_init(cfg, 1);
}
+static int pci_n1sdp_remote_pcie_init(struct pci_config_window *cfg)
+{
+ return pci_n1sdp_init(cfg, 2);
+}
+
const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops = {
.bus_shift = 20,
.init = pci_n1sdp_pcie_init,
@@ -165,6 +182,16 @@ const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops = {
}
};
+const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops = {
+ .bus_shift = 20,
+ .init = pci_n1sdp_remote_pcie_init,
+ .pci_ops = {
+ .map_bus = pci_n1sdp_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write32,
+ }
+};
+
struct of_device_id n1sdp_pcie_of_match[] = {
{ .compatible = "arm,n1sdp-pcie" },
{ },
@@ -188,6 +215,9 @@ static int n1sdp_pcie_probe(struct platform_device *pdev)
case 1:
n1sdp_pcie_of_match[0].data = &pci_n1sdp_ccix_ecam_ops;
return pci_host_common_probe(pdev);
+ case 2:
+ n1sdp_pcie_of_match[0].data = &pci_n1sdp_remote_pcie_ecam_ops;
+ return pci_host_common_probe(pdev);
}
dev_err(&pdev->dev, "Invalid segment number, must be smaller than %d\n",
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index d3959ada44af..08d9684b7dc8 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -60,6 +60,7 @@ extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x
extern const struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */
extern const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops; /* Arm N1SDP PCIe */
extern const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops; /* Arm N1SDP PCIe */
+extern const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops; /* Arm N1SDP PCIe */
#endif
#if IS_ENABLED(CONFIG_PCI_HOST_COMMON)