diff mbox

[v10,11/12] PCI: Add MCFG quirks for Cavium ThunderX pass2.x host controller

Message ID 20161201083058.12247.42729.stgit@bhelgaas-glaptop.roam.corp.google.com
State Not Applicable
Headers show

Commit Message

Bjorn Helgaas Dec. 1, 2016, 8:30 a.m. UTC
From: Tomasz Nowicki <tn@semihalf.com>

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 = 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.

[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 <tn@semihalf.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/acpi/pci_mcfg.c            |   19 ++++++++++++++++++
 drivers/pci/host/Makefile          |    2 +-
 drivers/pci/host/pci-thunder-pem.c |   38 ++++++++++++++++++++++++++++++++++++
 include/linux/pci-ecam.h           |    1 +
 4 files changed, 59 insertions(+), 1 deletion(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Bjorn Helgaas Dec. 2, 2016, 5:35 p.m. UTC | #1
On Thu, Dec 01, 2016 at 02:30:58AM -0600, Bjorn Helgaas wrote:
> From: Tomasz Nowicki <tn@semihalf.com>
> 
> 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 = 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.
> 
> [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 <tn@semihalf.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>  drivers/acpi/pci_mcfg.c            |   19 ++++++++++++++++++
>  drivers/pci/host/Makefile          |    2 +-
>  drivers/pci/host/pci-thunder-pem.c |   38 ++++++++++++++++++++++++++++++++++++
>  include/linux/pci-ecam.h           |    1 +
>  4 files changed, 59 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
> index c6a6949..a48b508 100644
> --- a/drivers/acpi/pci_mcfg.c
> +++ b/drivers/acpi/pci_mcfg.c
> @@ -74,6 +74,25 @@ static struct mcfg_fixup mcfg_quirks[] = {
>  	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 + (node << 44), 0x39 * SZ_16M)

I assume we should do s/node/seg/ here as well?  I already did that for
THUNDER_ECAM_QUIRK in the next patch.
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tomasz Nowicki Dec. 5, 2016, 8:32 a.m. UTC | #2
On 02.12.2016 18:35, Bjorn Helgaas wrote:
> On Thu, Dec 01, 2016 at 02:30:58AM -0600, Bjorn Helgaas wrote:
>> From: Tomasz Nowicki <tn@semihalf.com>
>>
>> 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 = 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.
>>
>> [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 <tn@semihalf.com>
>> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>> ---
>>  drivers/acpi/pci_mcfg.c            |   19 ++++++++++++++++++
>>  drivers/pci/host/Makefile          |    2 +-
>>  drivers/pci/host/pci-thunder-pem.c |   38 ++++++++++++++++++++++++++++++++++++
>>  include/linux/pci-ecam.h           |    1 +
>>  4 files changed, 59 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>> index c6a6949..a48b508 100644
>> --- a/drivers/acpi/pci_mcfg.c
>> +++ b/drivers/acpi/pci_mcfg.c
>> @@ -74,6 +74,25 @@ static struct mcfg_fixup mcfg_quirks[] = {
>>  	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 + (node << 44), 0x39 * SZ_16M)
>
> I assume we should do s/node/seg/ here as well?  I already did that for
> THUNDER_ECAM_QUIRK in the next patch.
>

Here node means NUMA node number so it is fine.

Thanks,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
index c6a6949..a48b508 100644
--- a/drivers/acpi/pci_mcfg.c
+++ b/drivers/acpi/pci_mcfg.c
@@ -74,6 +74,25 @@  static struct mcfg_fixup mcfg_quirks[] = {
 	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 + (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, 0UL),
+	THUNDER_PEM_QUIRK(1, 1UL),
 };
 
 static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
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) += pcie-altera-msi.o
 obj-$(CONFIG_ARM64) += pcie-hisi.o
 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
 obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
-obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
+obj-$(CONFIG_ARM64) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
 obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c
index c3276ee..7b03939 100644
--- a/drivers/pci/host/pci-thunder-pem.c
+++ b/drivers/pci/host/pci-thunder-pem.c
@@ -18,9 +18,12 @@ 
 #include <linux/init.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
+#include <linux/pci-acpi.h>
 #include <linux/pci-ecam.h>
 #include <linux/platform_device.h>
 
+#if defined(CONFIG_PCI_HOST_THUNDER_PEM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
+
 #define PEM_CFG_WR 0x28
 #define PEM_CFG_RD 0x30
 
@@ -313,6 +316,38 @@  static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
 	return 0;
 }
 
+#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
+
+static int thunder_pem_acpi_init(struct pci_config_window *cfg)
+{
+	struct device *dev = cfg->parent;
+	struct acpi_device *adev = to_acpi_device(dev);
+	struct acpi_pci_root *root = acpi_driver_data(adev);
+	struct resource *res_pem;
+
+	ret = acpi_get_rc_resources("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 = {
+	.bus_shift	= 24,
+	.init		= thunder_pem_acpi_init,
+	.pci_ops	= {
+		.map_bus	= pci_ecam_map_bus,
+		.read		= thunder_pem_config_read,
+		.write		= 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 = cfg->parent;
@@ -364,3 +399,6 @@  static struct platform_driver thunder_pem_driver = {
 	.probe = 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
 
 #ifdef CONFIG_PCI_HOST_GENERIC