aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/phb4.c53
-rw-r--r--include/phb4.h2
-rw-r--r--platforms/astbmc/witherspoon.c47
3 files changed, 78 insertions, 24 deletions
diff --git a/hw/phb4.c b/hw/phb4.c
index f17625b..60e797c 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -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,