Commit 7f2c39e9 authored by Frederic Barrat's avatar Frederic Barrat Committed by Michael Ellerman

powerpc/powernv: Introduce new PHB type for opencapi links

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: default avatarFrederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: default avatarAndrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent bdcb1aef
...@@ -277,7 +277,7 @@ static int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe) ...@@ -277,7 +277,7 @@ static int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe)
int64_t rc = 0; int64_t rc = 0;
phys_addr_t top = memblock_end_of_DRAM(); 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; return -EINVAL;
rc = pnv_npu_unset_window(npe, 0); rc = pnv_npu_unset_window(npe, 0);
......
...@@ -54,7 +54,8 @@ ...@@ -54,7 +54,8 @@
#define POWERNV_IOMMU_DEFAULT_LEVELS 1 #define POWERNV_IOMMU_DEFAULT_LEVELS 1
#define POWERNV_IOMMU_MAX_LEVELS 5 #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); 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, void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
...@@ -933,7 +934,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) ...@@ -933,7 +934,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 * Configure PELTV. NPUs don't have a PELTV table so skip
* configuration on them. * 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); pnv_ioda_set_peltv(phb, pe, true);
/* Setup reverse map */ /* Setup reverse map */
...@@ -1281,16 +1282,23 @@ static void pnv_pci_ioda_setup_PEs(void) ...@@ -1281,16 +1282,23 @@ static void pnv_pci_ioda_setup_PEs(void)
{ {
struct pci_controller *hose, *tmp; struct pci_controller *hose, *tmp;
struct pnv_phb *phb; struct pnv_phb *phb;
struct pci_bus *bus;
struct pci_dev *pdev;
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
phb = hose->private_data; phb = hose->private_data;
if (phb->type == PNV_PHB_NPU) { if (phb->type == PNV_PHB_NPU_NVLINK) {
/* PE#0 is needed for error reporting */ /* PE#0 is needed for error reporting */
pnv_ioda_reserve_pe(phb, 0); pnv_ioda_reserve_pe(phb, 0);
pnv_ioda_setup_npu_PEs(hose->bus); pnv_ioda_setup_npu_PEs(hose->bus);
if (phb->model == PNV_PHB_MODEL_NPU2) if (phb->model == PNV_PHB_MODEL_NPU2)
pnv_npu2_init(phb); 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);
}
} }
} }
...@@ -2648,7 +2656,7 @@ static int gpe_table_group_to_npe_cb(struct device *dev, void *opaque) ...@@ -2648,7 +2656,7 @@ static int gpe_table_group_to_npe_cb(struct device *dev, void *opaque)
hose = pci_bus_to_host(pdev->bus); hose = pci_bus_to_host(pdev->bus);
phb = hose->private_data; phb = hose->private_data;
if (phb->type != PNV_PHB_NPU) if (phb->type != PNV_PHB_NPU_NVLINK)
return 0; return 0;
*ptmppe = &phb->ioda.pe_array[pdn->pe_number]; *ptmppe = &phb->ioda.pe_array[pdn->pe_number];
...@@ -2732,7 +2740,7 @@ static void pnv_pci_ioda_setup_iommu_api(void) ...@@ -2732,7 +2740,7 @@ static void pnv_pci_ioda_setup_iommu_api(void)
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
phb = hose->private_data; phb = hose->private_data;
if (phb->type != PNV_PHB_NPU) if (phb->type != PNV_PHB_NPU_NVLINK)
continue; continue;
list_for_each_entry(pe, &phb->ioda.pe_list, list) { list_for_each_entry(pe, &phb->ioda.pe_list, list) {
...@@ -3782,6 +3790,13 @@ static const struct pci_controller_ops pnv_npu_ioda_controller_ops = { ...@@ -3782,6 +3790,13 @@ static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
.shutdown = pnv_pci_ioda_shutdown, .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 #ifdef CONFIG_CXL_BASE
const struct pci_controller_ops pnv_cxl_cx4_ioda_controller_ops = { const struct pci_controller_ops pnv_cxl_cx4_ioda_controller_ops = {
.dma_dev_setup = pnv_pci_dma_dev_setup, .dma_dev_setup = pnv_pci_dma_dev_setup,
...@@ -4015,9 +4030,14 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, ...@@ -4015,9 +4030,14 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
*/ */
ppc_md.pcibios_fixup = pnv_pci_ioda_fixup; 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; 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; phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
hose->controller_ops = pnv_pci_ioda_controller_ops; hose->controller_ops = pnv_pci_ioda_controller_ops;
} }
...@@ -4063,7 +4083,12 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np) ...@@ -4063,7 +4083,12 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np)
void __init pnv_pci_init_npu_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) void __init pnv_pci_init_ioda_hub(struct device_node *np)
......
...@@ -1142,6 +1142,10 @@ void __init pnv_pci_init(void) ...@@ -1142,6 +1142,10 @@ void __init pnv_pci_init(void)
for_each_compatible_node(np, NULL, "ibm,ioda2-npu2-phb") for_each_compatible_node(np, NULL, "ibm,ioda2-npu2-phb")
pnv_pci_init_npu_phb(np); 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 */ /* Configure IOMMU DMA hooks */
set_pci_dma_ops(&dma_iommu_ops); set_pci_dma_ops(&dma_iommu_ops);
} }
......
...@@ -14,7 +14,8 @@ struct pci_dn; ...@@ -14,7 +14,8 @@ struct pci_dn;
enum pnv_phb_type { enum pnv_phb_type {
PNV_PHB_IODA1 = 0, PNV_PHB_IODA1 = 0,
PNV_PHB_IODA2 = 1, PNV_PHB_IODA2 = 1,
PNV_PHB_NPU = 2, PNV_PHB_NPU_NVLINK = 2,
PNV_PHB_NPU_OCAPI = 3,
}; };
/* Precise PHB model for error management */ /* Precise PHB model for error management */
...@@ -227,6 +228,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, ...@@ -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_ioda_hub(struct device_node *np);
extern void pnv_pci_init_ioda2_phb(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_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 void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option); extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment