From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from omzsmtpe03.verizonbusiness.com ([199.249.25.208]:9345 "EHLO omzsmtpe03.verizonbusiness.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754221AbdDDTcu (ORCPT ); Tue, 4 Apr 2017 15:32:50 -0400 From: alexander.levin@verizon.com To: "gregkh@linuxfoundation.org" CC: "stable@vger.kernel.org" Subject: [PATCH for 4.9 26/98] PCI: Add MCFG quirks for Cavium ThunderX pass2.x host controller Date: Tue, 4 Apr 2017 19:32:11 +0000 Message-ID: <20170404193158.19041-27-alexander.levin@verizon.com> References: <20170404193158.19041-1-alexander.levin@verizon.com> In-Reply-To: <20170404193158.19041-1-alexander.levin@verizon.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Tomasz Nowicki [ Upstream commit 44f22bd91e88f9a1203a6e564a237e593f5f2f74 ] ThunderX PCIe controller to off-chip devices (so-called PEM) is not fully compliant with ECAM standard. It uses non-standard configuration space accessors (see thunder_pem_ecam_ops) and custom configuration space granulation (see bus_shift =3D 24). In order to access configuration space and probe PEM as ACPI-based PCI host controller we need to add MCFG quirk infrastructure. This involves: 1. A new thunder_pem_acpi_init() init function to locate PEM-specific register ranges using ACPI. 2. Export PEM thunder_pem_ecam_ops structure so it is visible to MCFG quirk code. 3. New quirk entries for each PEM segment. Each contains platform IDs, mentioned thunder_pem_ecam_ops and CFG resources. Quirk is considered for ThunderX silicon pass2.x only which is identified via MCFG revision 1. ThunderX pass 2.x requires the following accessors: NUMA Node 0 PCI segments 0- 3: pci_generic_ecam_ops (ECAM-compliant) NUMA Node 0 PCI segments 4- 9: thunder_pem_ecam_ops (MCFG quirk) NUMA Node 1 PCI segments 10-13: pci_generic_ecam_ops (ECAM-compliant) NUMA Node 1 PCI segments 14-19: thunder_pem_ecam_ops (MCFG quirk) [bhelgaas: adapt to use acpi_get_rc_resources(), update Makefile/ifdefs so quirk doesn't depend on CONFIG_PCI_HOST_THUNDER_PEM] Signed-off-by: Tomasz Nowicki Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/acpi/pci_mcfg.c | 19 ++++++++++++++++ drivers/pci/host/Kconfig | 3 ++- drivers/pci/host/Makefile | 2 +- drivers/pci/host/pci-thunder-pem.c | 44 ++++++++++++++++++++++++++++++++++= ++++ include/linux/pci-ecam.h | 1 + 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c index dd16224..17cbb07 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c @@ -74,6 +74,25 @@ static struct mcfg_fixup mcfg_quirks[] =3D { HISI_QUAD_DOM("HIP07 ", 4, &hisi_pcie_ops), HISI_QUAD_DOM("HIP07 ", 8, &hisi_pcie_ops), HISI_QUAD_DOM("HIP07 ", 12, &hisi_pcie_ops), + +#define THUNDER_PEM_RES(addr, node) \ + DEFINE_RES_MEM((addr) + ((u64) (node) << 44), 0x39 * SZ_16M) +#define THUNDER_PEM_QUIRK(rev, node) \ + { "CAVIUM", "THUNDERX", rev, 4 + (10 * (node)), MCFG_BUS_ANY, \ + &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88001f000000UL, node) }, \ + { "CAVIUM", "THUNDERX", rev, 5 + (10 * (node)), MCFG_BUS_ANY, \ + &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x884057000000UL, node) }, \ + { "CAVIUM", "THUNDERX", rev, 6 + (10 * (node)), MCFG_BUS_ANY, \ + &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88808f000000UL, node) }, \ + { "CAVIUM", "THUNDERX", rev, 7 + (10 * (node)), MCFG_BUS_ANY, \ + &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89001f000000UL, node) }, \ + { "CAVIUM", "THUNDERX", rev, 8 + (10 * (node)), MCFG_BUS_ANY, \ + &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x894057000000UL, node) }, \ + { "CAVIUM", "THUNDERX", rev, 9 + (10 * (node)), MCFG_BUS_ANY, \ + &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89808f000000UL, node) } + /* SoC pass2.x */ + THUNDER_PEM_QUIRK(1, 0), + THUNDER_PEM_QUIRK(1, 1), }; =20 static char mcfg_oem_id[ACPI_OEM_ID_SIZE]; diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index d7e7c0a..1239a8e 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -240,7 +240,8 @@ config PCIE_QCOM =20 config PCI_HOST_THUNDER_PEM bool "Cavium Thunder PCIe controller to off-chip devices" - depends on OF && ARM64 + depends on ARM64 + depends on OF || (ACPI && PCI_QUIRKS) select PCI_HOST_COMMON help Say Y here if you want PCIe support for CN88XX Cavium Thunder SoCs. diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 64845f0..97e6bfc 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -28,7 +28,7 @@ obj-$(CONFIG_PCIE_ALTERA_MSI) +=3D pcie-altera-msi.o obj-$(CONFIG_ARM64) +=3D pcie-hisi.o obj-$(CONFIG_PCIE_QCOM) +=3D pcie-qcom.o obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) +=3D pci-thunder-ecam.o -obj-$(CONFIG_PCI_HOST_THUNDER_PEM) +=3D pci-thunder-pem.o +obj-$(CONFIG_ARM64) +=3D pci-thunder-pem.o obj-$(CONFIG_PCIE_ARMADA_8K) +=3D pcie-armada8k.o obj-$(CONFIG_PCIE_ARTPEC6) +=3D pcie-artpec6.o obj-$(CONFIG_PCIE_ROCKCHIP) +=3D pcie-rockchip.o diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thun= der-pem.c index c3276ee..af722eb 100644 --- a/drivers/pci/host/pci-thunder-pem.c +++ b/drivers/pci/host/pci-thunder-pem.c @@ -18,8 +18,12 @@ #include #include #include +#include #include #include +#include "../pci.h" + +#if defined(CONFIG_PCI_HOST_THUNDER_PEM) || (defined(CONFIG_ACPI) && defin= ed(CONFIG_PCI_QUIRKS)) =20 #define PEM_CFG_WR 0x28 #define PEM_CFG_RD 0x30 @@ -313,6 +317,43 @@ static int thunder_pem_init(struct device *dev, struct= pci_config_window *cfg, return 0; } =20 +#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) + +static int thunder_pem_acpi_init(struct pci_config_window *cfg) +{ + struct device *dev =3D cfg->parent; + struct acpi_device *adev =3D to_acpi_device(dev); + struct acpi_pci_root *root =3D acpi_driver_data(adev); + struct resource *res_pem; + int ret; + + res_pem =3D devm_kzalloc(&adev->dev, sizeof(*res_pem), GFP_KERNEL); + if (!res_pem) + return -ENOMEM; + + ret =3D acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem); + if (ret) { + dev_err(dev, "can't get rc base address\n"); + return ret; + } + + return thunder_pem_init(dev, cfg, res_pem); +} + +struct pci_ecam_ops thunder_pem_ecam_ops =3D { + .bus_shift =3D 24, + .init =3D thunder_pem_acpi_init, + .pci_ops =3D { + .map_bus =3D pci_ecam_map_bus, + .read =3D thunder_pem_config_read, + .write =3D thunder_pem_config_write, + } +}; + +#endif + +#ifdef CONFIG_PCI_HOST_THUNDER_PEM + static int thunder_pem_platform_init(struct pci_config_window *cfg) { struct device *dev =3D cfg->parent; @@ -364,3 +405,6 @@ static struct platform_driver thunder_pem_driver =3D { .probe =3D thunder_pem_probe, }; builtin_platform_driver(thunder_pem_driver); + +#endif +#endif diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h index bdacbc8..e88d7db 100644 --- a/include/linux/pci-ecam.h +++ b/include/linux/pci-ecam.h @@ -62,6 +62,7 @@ extern struct pci_ecam_ops pci_generic_ecam_ops; #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) extern struct pci_ecam_ops pci_32b_ops; /* 32-bit accesses only */ extern struct pci_ecam_ops hisi_pcie_ops; /* HiSilicon */ +extern struct pci_ecam_ops thunder_pem_ecam_ops; /* Cavium ThunderX 2.x */ #endif =20 #ifdef CONFIG_PCI_HOST_GENERIC --=20 2.9.3