diff options
-rw-r--r-- | hw/phb4.c | 53 | ||||
-rw-r--r-- | include/phb4.h | 2 | ||||
-rw-r--r-- | platforms/astbmc/witherspoon.c | 47 |
3 files changed, 78 insertions, 24 deletions
@@ -809,6 +809,33 @@ static int64_t phb4_pcicfg_no_dstate(void *dev __unused, return OPAL_PARTIAL; } +void phb4_pec2_dma_engine_realloc(struct phb4 *p) +{ + uint64_t reg; + + /* + * Allocate 16 extra dma read engines to stack 0, to boost dma + * performance for devices on stack 0 of PEC2, i.e PHB3. + * It comes at a price of reduced read engine allocation for + * devices on stack 1 and 2. The engine allocation becomes + * 48/8/8 instead of the default 32/16/16. + * + * The reallocation magic value should be 0xffff0000ff008000, + * but per the PCI designers, dma engine 32 (bit 0) has a + * quirk, and 0x7fff80007F008000 has the same effect (engine + * 32 goes to PHB4). + */ + if (p->index != 3) /* shared slot on PEC2 */ + return; + + PHBINF(p, "Allocating an extra 16 dma read engines on PEC2 stack0\n"); + reg = 0x7fff80007F008000ULL; + xscom_write(p->chip_id, + p->pci_xscom + XPEC_PCI_PRDSTKOVR, reg); + xscom_write(p->chip_id, + p->pe_xscom + XPEC_NEST_READ_STACK_OVERRIDE, reg); +} + static void phb4_check_device_quirks(struct pci_device *dev) { /* Some special adapter tweaks for devices directly under the PHB */ @@ -4415,30 +4442,8 @@ static int64_t enable_capi_mode(struct phb4 *p, uint64_t pe_number, * dma-read engines allocations to maximize the DMA read performance */ if ((p->index == CAPP1_PHB_INDEX) && - (capp_eng & CAPP_MAX_DMA_READ_ENGINES)) { - - /* - * Allocate Additional 16/8 dma read engines to stack0/stack1 - * respectively. Read engines 0:31 are anyways always assigned - * to stack0. Also skip allocating DMA Read Engine-32 by - * enabling Bit[0] in XPEC_NEST_READ_STACK_OVERRIDE register. - * Enabling this bit seems cause a parity error reported in - * NFIR[1]-nonbar_pe. - */ - reg = 0x7fff80007F008000ULL; - - xscom_write(p->chip_id, p->pci_xscom + XPEC_PCI_PRDSTKOVR, reg); - xscom_write(p->chip_id, p->pe_xscom + - XPEC_NEST_READ_STACK_OVERRIDE, reg); - - /* Log this reallocation as it may impact dma performance of - * other slots connected to PEC2 - */ - PHBINF(p, "CAPP: Set %d dma-read engines for PEC2/stack-0\n", - 32 + __builtin_popcountll(reg & PPC_BITMASK(0, 31))); - PHBDBG(p, "CAPP: XPEC_NEST_READ_STACK_OVERRIDE: %016llx\n", - reg); - } + (capp_eng & CAPP_MAX_DMA_READ_ENGINES)) + phb4_pec2_dma_engine_realloc(p); /* PCI to PB data movement ignores the PB init signal. */ xscom_write_mask(p->chip_id, p->pe_xscom + XPEC_NEST_PBCQ_HW_CONFIG, diff --git a/include/phb4.h b/include/phb4.h index 6d5fd51..abba2d9 100644 --- a/include/phb4.h +++ b/include/phb4.h @@ -257,4 +257,6 @@ static inline int phb4_get_opal_id(unsigned int chip_id, unsigned int index) return chip_id * PHB4_MAX_PHBS_PER_CHIP_P9P + index; } +void phb4_pec2_dma_engine_realloc(struct phb4 *p); + #endif /* __PHB4_H */ diff --git a/platforms/astbmc/witherspoon.c b/platforms/astbmc/witherspoon.c index 6387af4..39c3f16 100644 --- a/platforms/astbmc/witherspoon.c +++ b/platforms/astbmc/witherspoon.c @@ -192,6 +192,52 @@ static void witherspoon_shared_slot_fixup(void) } } +static int check_mlx_cards(struct phb *phb __unused, struct pci_device *dev, + void *userdata __unused) +{ + uint16_t mlx_cards[] = { + 0x1017, /* ConnectX-5 */ + 0x1019, /* ConnectX-5 Ex */ + 0x101b, /* ConnectX-6 */ + 0x101d, /* ConnectX-6 Dx */ + 0x101f, /* ConnectX-6 Lx */ + 0x1021, /* ConnectX-7 */ + }; + + if (PCI_VENDOR_ID(dev->vdid) == 0x15b3) { /* Mellanox */ + for (int i = 0; i < ARRAY_SIZE(mlx_cards); i++) { + if (mlx_cards[i] == PCI_DEVICE_ID(dev->vdid)) + return 1; + } + } + return 0; +} + +static void witherspoon_pci_probe_complete(void) +{ + struct pci_device *dev; + struct phb *phb; + struct phb4 *p; + + /* + * Reallocate dma engines between stacks in PEC2 if a Mellanox + * card is found on the shared slot, as it is required to get + * good GPU direct performance. + */ + for_each_phb(phb) { + /* skip the virtual PHBs */ + if (phb->phb_type != phb_type_pcie_v4) + continue; + p = phb_to_phb4(phb); + /* Keep only the first PHB on PEC2 */ + if (p->index != 3) + continue; + dev = pci_walk_dev(phb, NULL, check_mlx_cards, NULL); + if (dev) + phb4_pec2_dma_engine_realloc(p); + } +} + static void set_link_details(struct npu2 *npu, uint32_t link_index, uint32_t brick_index, enum npu2_dev_type type) { @@ -533,6 +579,7 @@ DECLARE_PLATFORM(witherspoon) = { .probe = witherspoon_probe, .init = astbmc_init, .pre_pci_fixup = witherspoon_shared_slot_fixup, + .pci_probe_complete = witherspoon_pci_probe_complete, .start_preload_resource = flash_start_preload_resource, .resource_loaded = flash_resource_loaded, .bmc = &bmc_plat_ast2500_openbmc, |