Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 1 | From 7a5147f51f2eb80ecb6f62a28b8bd86aa5ceebf7 Mon Sep 17 00:00:00 2001 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 2 | From: Sayanta Pattanayak <sayanta.pattanayak@arm.com> |
| 3 | Date: Wed, 9 Feb 2022 20:37:43 +0530 |
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 |
| 9 | complex of the remote board appears as PCIe segment 2 on the primary board. |
| 10 | The resources of the secondary board, including the host complex, are |
| 11 | mapped at offset 0x40000000000 into the address space of the primary |
| 12 | board, so take that into account when accessing the remote PCIe segment. |
| 13 | |
| 14 | Change-Id: I0e8d1eb119aef6444b9df854a39b24441c12195a |
| 15 | Signed-off-by: Sayanta Pattanayak <sayanta.pattanayak@arm.com> |
| 16 | Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com> |
| 17 | Signed-off-by: Andre Przywara <andre.przywara@arm.com> |
| 18 | Signed-off-by: sahil <sahil@arm.com> |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 19 | |
| 20 | Upstream-Status: Inappropriate [will not be submitted as its an hack required to fix the hardware issue] |
| 21 | Signed-off-by: Sayanta Pattanayak <sayanta.pattanayak@arm.com> |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 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 | |
| 28 | diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 29 | index 67c34e6c24a7..4584a5a2ca20 100644 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 30 | --- a/drivers/acpi/pci_mcfg.c |
| 31 | +++ b/drivers/acpi/pci_mcfg.c |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 32 | @@ -158,6 +158,7 @@ static struct mcfg_fixup mcfg_quirks[] = { |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 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), |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 37 | |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 38 | #define ALTRA_ECAM_QUIRK(rev, seg) \ |
| 39 | { "Ampere", "Altra ", rev, seg, MCFG_BUS_ANY, &pci_32b_read_ops } |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 40 | diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c |
| 41 | index 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 | { }, |
| 123 | diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 124 | index e6bbc037cef8..d936d3f14bce 100644 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 125 | --- a/include/linux/pci-ecam.h |
| 126 | +++ b/include/linux/pci-ecam.h |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 127 | @@ -91,6 +91,7 @@ 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] | 128 | extern const struct pci_ecam_ops pci_n1sdp_ccix_ecam_ops; /* Arm N1SDP PCIe */ |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 129 | #endif |
| 130 | |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 131 | +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] | 132 | #if IS_ENABLED(CONFIG_PCI_HOST_COMMON) |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 133 | /* for DT-based PCI controllers that support ECAM */ |
| 134 | int pci_host_common_probe(struct platform_device *pdev); |