]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
powerpc/powernv: Introduce new PHB type for opencapi links
authorFrederic Barrat <fbarrat@linux.vnet.ibm.com>
Tue, 23 Jan 2018 11:31:36 +0000 (12:31 +0100)
committerSeth Forshee <seth.forshee@canonical.com>
Tue, 27 Feb 2018 15:54:30 +0000 (09:54 -0600)
BugLink: http://bugs.launchpad.net/bugs/1746988
The NPU was already abstracted by opal as a virtual PHB for nvlink,
but it helps to be able to differentiate between a nvlink or opencapi
PHB, as it's not completely transparent to linux. In particular, PE
assignment differs and we'll also need the information in later
patches.

So rename existing PNV_PHB_NPU type to PNV_PHB_NPU_NVLINK and add a
new type PNV_PHB_NPU_OCAPI.

Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
(cherry picked from commit 7f2c39e91f61fcd2abed3b39c14e7037c060c6f1)
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
arch/powerpc/platforms/powernv/npu-dma.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/powernv/pci.h

index f6cbc1a7147242393182785459d4f5fafbb40724..c5899c107d591f60974fe00ee983dc4aa96427fb 100644 (file)
@@ -277,7 +277,7 @@ static int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe)
        int64_t rc = 0;
        phys_addr_t top = memblock_end_of_DRAM();
 
-       if (phb->type != PNV_PHB_NPU || !npe->pdev)
+       if (phb->type != PNV_PHB_NPU_NVLINK || !npe->pdev)
                return -EINVAL;
 
        rc = pnv_npu_unset_window(npe, 0);
index 749055553064041369d111b01b793ba9368a5d48..e780263a14ee10fadc084bbc213881b4f74cdfa1 100644 (file)
@@ -54,7 +54,8 @@
 #define POWERNV_IOMMU_DEFAULT_LEVELS   1
 #define POWERNV_IOMMU_MAX_LEVELS       5
 
-static const char * const pnv_phb_names[] = { "IODA1", "IODA2", "NPU" };
+static const char * const pnv_phb_names[] = { "IODA1", "IODA2", "NPU_NVLINK",
+                                             "NPU_OCAPI" };
 static void pnv_pci_ioda2_table_free_pages(struct iommu_table *tbl);
 
 void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
@@ -924,7 +925,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
         * Configure PELTV. NPUs don't have a PELTV table so skip
         * configuration on them.
         */
-       if (phb->type != PNV_PHB_NPU)
+       if (phb->type != PNV_PHB_NPU_NVLINK && phb->type != PNV_PHB_NPU_OCAPI)
                pnv_ioda_set_peltv(phb, pe, true);
 
        /* Setup reverse map */
@@ -1272,16 +1273,23 @@ static void pnv_pci_ioda_setup_PEs(void)
 {
        struct pci_controller *hose, *tmp;
        struct pnv_phb *phb;
+       struct pci_bus *bus;
+       struct pci_dev *pdev;
 
        list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
                phb = hose->private_data;
-               if (phb->type == PNV_PHB_NPU) {
+               if (phb->type == PNV_PHB_NPU_NVLINK) {
                        /* PE#0 is needed for error reporting */
                        pnv_ioda_reserve_pe(phb, 0);
                        pnv_ioda_setup_npu_PEs(hose->bus);
                        if (phb->model == PNV_PHB_MODEL_NPU2)
                                pnv_npu2_init(phb);
                }
+               if (phb->type == PNV_PHB_NPU_OCAPI) {
+                       bus = hose->bus;
+                       list_for_each_entry(pdev, &bus->devices, bus_list)
+                               pnv_ioda_setup_dev_PE(pdev);
+               }
        }
 }
 
@@ -2640,7 +2648,7 @@ static int gpe_table_group_to_npe_cb(struct device *dev, void *opaque)
 
        hose = pci_bus_to_host(pdev->bus);
        phb = hose->private_data;
-       if (phb->type != PNV_PHB_NPU)
+       if (phb->type != PNV_PHB_NPU_NVLINK)
                return 0;
 
        *ptmppe = &phb->ioda.pe_array[pdn->pe_number];
@@ -2724,7 +2732,7 @@ static void pnv_pci_ioda_setup_iommu_api(void)
        list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
                phb = hose->private_data;
 
-               if (phb->type != PNV_PHB_NPU)
+               if (phb->type != PNV_PHB_NPU_NVLINK)
                        continue;
 
                list_for_each_entry(pe, &phb->ioda.pe_list, list) {
@@ -3774,6 +3782,13 @@ static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
        .shutdown               = pnv_pci_ioda_shutdown,
 };
 
+static const struct pci_controller_ops pnv_npu_ocapi_ioda_controller_ops = {
+       .enable_device_hook     = pnv_pci_enable_device_hook,
+       .window_alignment       = pnv_pci_window_alignment,
+       .reset_secondary_bus    = pnv_pci_reset_secondary_bus,
+       .shutdown               = pnv_pci_ioda_shutdown,
+};
+
 #ifdef CONFIG_CXL_BASE
 const struct pci_controller_ops pnv_cxl_cx4_ioda_controller_ops = {
        .dma_dev_setup          = pnv_pci_dma_dev_setup,
@@ -4007,9 +4022,14 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
         */
        ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
 
-       if (phb->type == PNV_PHB_NPU) {
+       switch (phb->type) {
+       case PNV_PHB_NPU_NVLINK:
                hose->controller_ops = pnv_npu_ioda_controller_ops;
-       } else {
+               break;
+       case PNV_PHB_NPU_OCAPI:
+               hose->controller_ops = pnv_npu_ocapi_ioda_controller_ops;
+               break;
+       default:
                phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
                hose->controller_ops = pnv_pci_ioda_controller_ops;
        }
@@ -4052,7 +4072,12 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np)
 
 void __init pnv_pci_init_npu_phb(struct device_node *np)
 {
-       pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU);
+       pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU_NVLINK);
+}
+
+void __init pnv_pci_init_npu2_opencapi_phb(struct device_node *np)
+{
+       pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU_OCAPI);
 }
 
 void __init pnv_pci_init_ioda_hub(struct device_node *np)
index 5422f4a6317cadf06335c4c1a18e3d7dcccd6db6..69d102cbf48f2b386f58cb88223ee99f25da797e 100644 (file)
@@ -1142,6 +1142,10 @@ void __init pnv_pci_init(void)
        for_each_compatible_node(np, NULL, "ibm,ioda2-npu2-phb")
                pnv_pci_init_npu_phb(np);
 
+       /* Look for NPU2 OpenCAPI PHBs */
+       for_each_compatible_node(np, NULL, "ibm,ioda2-npu2-opencapi-phb")
+               pnv_pci_init_npu2_opencapi_phb(np);
+
        /* Configure IOMMU DMA hooks */
        set_pci_dma_ops(&dma_iommu_ops);
 }
index b772d747389634f9713d1d4f70aaabcfffca630c..eada4b6068cb172301ee89f08c25726355dfb2e6 100644 (file)
@@ -12,9 +12,10 @@ struct pci_dn;
 #define NV_NMMU_ATSD_REGS 8
 
 enum pnv_phb_type {
-       PNV_PHB_IODA1   = 0,
-       PNV_PHB_IODA2   = 1,
-       PNV_PHB_NPU     = 2,
+       PNV_PHB_IODA1           = 0,
+       PNV_PHB_IODA2           = 1,
+       PNV_PHB_NPU_NVLINK      = 2,
+       PNV_PHB_NPU_OCAPI       = 3,
 };
 
 /* Precise PHB model for error management */
@@ -227,6 +228,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
 extern void pnv_pci_init_ioda_hub(struct device_node *np);
 extern void pnv_pci_init_ioda2_phb(struct device_node *np);
 extern void pnv_pci_init_npu_phb(struct device_node *np);
+extern void pnv_pci_init_npu2_opencapi_phb(struct device_node *np);
 extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
 extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);