blob: c15b464c73fbb95490aee90d58c89f675316352e [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001Upstream-Status: Inappropriate [will not be submitted as its an hack required to fix the hardware issue]
2Signed-off-by: Sayanta Pattanayak <sayanta.pattanayak@arm.com>
3
4From 4d69e38213bf52a48f2f0239da8c7b76501428b2 Mon Sep 17 00:00:00 2001
5From: Sayanta Pattanayak <sayanta.pattanayak@arm.com>
6Date: Wed, 9 Feb 2022 20:37:43 +0530
7Subject: [PATCH 4/5] n1sdp: pcie: add quirk support enabling remote chip PCIe
8
9Base address mapping for remote chip Root PCIe ECAM space.
10
11When two N1SDP boards are coupled via the CCIX connection, the PCI host
12complex of the remote board appears as PCIe segment 2 on the primary board.
13The resources of the secondary board, including the host complex, are
14mapped at offset 0x40000000000 into the address space of the primary
15board, so take that into account when accessing the remote PCIe segment.
16
17Change-Id: I0e8d1eb119aef6444b9df854a39b24441c12195a
18Signed-off-by: Sayanta Pattanayak <sayanta.pattanayak@arm.com>
19Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
20Signed-off-by: Andre Przywara <andre.przywara@arm.com>
21Signed-off-by: sahil <sahil@arm.com>
22---
23 drivers/acpi/pci_mcfg.c | 1 +
24 drivers/pci/controller/pcie-n1sdp.c | 32 +++++++++++++++++++++++++----
25 include/linux/pci-ecam.h | 1 +
26 3 files changed, 30 insertions(+), 4 deletions(-)
27
28diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
29index f31727da21ac..58f59b5fffa2 100644
30--- a/drivers/acpi/pci_mcfg.c
31+++ b/drivers/acpi/pci_mcfg.c
32@@ -176,6 +176,7 @@ static struct mcfg_fixup mcfg_quirks[] = {
33 /* N1SDP SoC with v1 PCIe controller */
34 N1SDP_ECAM_MCFG(0x20181101, 0, &pci_n1sdp_pcie_ecam_ops),
35 N1SDP_ECAM_MCFG(0x20181101, 1, &pci_n1sdp_ccix_ecam_ops),
36+ N1SDP_ECAM_MCFG(0x20181101, 2, &pci_n1sdp_remote_pcie_ecam_ops),
37 };
38
39 static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
40diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c
41index 408699b9dcb1..a03665dd056a 100644
42--- a/drivers/pci/controller/pcie-n1sdp.c
43+++ b/drivers/pci/controller/pcie-n1sdp.c
44@@ -30,8 +30,10 @@
45
46 /* Platform specific values as hardcoded in the firmware. */
47 #define AP_NS_SHARED_MEM_BASE 0x06000000
48-#define MAX_SEGMENTS 2 /* Two PCIe root complexes. */
49+/* Two PCIe root complexes in One Chip + One PCIe RC in Remote Chip */
50+#define MAX_SEGMENTS 3
51 #define BDF_TABLE_SIZE SZ_16K
52+#define REMOTE_CHIP_ADDR_OFFSET 0x40000000000
53
54 /*
55 * Shared memory layout as written by the SCP upon boot time:
56@@ -97,12 +99,17 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment)
57 phys_addr_t table_base;
58 struct device *dev = cfg->parent;
59 struct pcie_discovery_data *shared_data;
60- size_t bdfs_size;
61+ size_t bdfs_size, rc_base_addr = 0;
62
63 if (segment >= MAX_SEGMENTS)
64 return -ENODEV;
65
66- table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE;
67+ if (segment > 1) {
68+ rc_base_addr = REMOTE_CHIP_ADDR_OFFSET;
69+ table_base = AP_NS_SHARED_MEM_BASE + REMOTE_CHIP_ADDR_OFFSET;
70+ } else {
71+ table_base = AP_NS_SHARED_MEM_BASE + segment * BDF_TABLE_SIZE;
72+ }
73
74 if (!request_mem_region(table_base, BDF_TABLE_SIZE,
75 "PCIe valid BDFs")) {
76@@ -114,6 +121,7 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment)
77 table_base, BDF_TABLE_SIZE);
78 if (!shared_data)
79 return -ENOMEM;
80+ rc_base_addr += shared_data->rc_base_addr;
81
82 /* Copy the valid BDFs structure to allocated normal memory. */
83 bdfs_size = sizeof(struct pcie_discovery_data) +
84@@ -125,7 +133,7 @@ static int pci_n1sdp_init(struct pci_config_window *cfg, unsigned int segment)
85 memcpy_fromio(pcie_discovery_data[segment], shared_data, bdfs_size);
86
87 rc_remapped_addr[segment] = devm_ioremap(dev,
88- shared_data->rc_base_addr,
89+ rc_base_addr,
90 PCI_CFG_SPACE_EXP_SIZE);
91 if (!rc_remapped_addr[segment]) {
92 dev_err(dev, "Cannot remap root port base\n");
93@@ -161,6 +169,12 @@ static int pci_n1sdp_ccix_init(struct pci_config_window *cfg)
94 return pci_n1sdp_init(cfg, 1);
95 }
96
97+/* Called for ACPI segment 2. */
98+static int pci_n1sdp_remote_pcie_init(struct pci_config_window *cfg)
99+{
100+ return pci_n1sdp_init(cfg, 2);
101+}
102+
103 const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops = {
104 .bus_shift = 20,
105 .init = pci_n1sdp_pcie_init,
106@@ -181,6 +195,16 @@ const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops = {
107 }
108 };
109
110+const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops = {
111+ .bus_shift = 20,
112+ .init = pci_n1sdp_remote_pcie_init,
113+ .pci_ops = {
114+ .map_bus = pci_n1sdp_map_bus,
115+ .read = pci_generic_config_read32,
116+ .write = pci_generic_config_write32,
117+ }
118+};
119+
120 static const struct of_device_id n1sdp_pcie_of_match[] = {
121 { .compatible = "arm,n1sdp-pcie", .data = &pci_n1sdp_pcie_ecam_ops },
122 { },
123diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
124index e6bbc037cef8..7bd8c1d702ee 100644
125--- a/include/linux/pci-ecam.h
126+++ b/include/linux/pci-ecam.h
127@@ -89,6 +89,7 @@ extern const struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */
128 extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
129 extern const struct pci_ecam_ops pci_n1sdp_pcie_ecam_ops; /* Arm N1SDP PCIe */
130 extern const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops; /* Arm N1SDP PCIe */
131+extern const struct pci_ecam_ops pci_n1sdp_remote_pcie_ecam_ops; /* Arm N1SDP PCIe */
132 #endif
133
134 #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
135--
1362.17.1
137