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