diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2015-04-28 09:59:22 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-04-29 09:44:58 +1000 |
commit | 713c65c871591bfbdab1801503c65362250ee4c6 (patch) | |
tree | 5fa11302a548cbcaf3c4c6f84d2443cdd4f6aa2f /hw/phb3.c | |
parent | 8631d0b8df27a1cbe01da8551508fdd2d10477a2 (diff) | |
download | skiboot-713c65c871591bfbdab1801503c65362250ee4c6.zip skiboot-713c65c871591bfbdab1801503c65362250ee4c6.tar.gz skiboot-713c65c871591bfbdab1801503c65362250ee4c6.tar.bz2 |
phb3: Disable write scope group in PHB for certain adapters
A performance issue on HPC workloads was identified with some network
adapters due to the specific DMA access patterns they use which hits
a worst-case scenario in the PHB.
Disabling the write scope group feature in the PHB works around this,
so let's do that when we detect such an adapter in a PCIe direct slot.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/phb3.c')
-rw-r--r-- | hw/phb3.c | 33 |
1 files changed, 33 insertions, 0 deletions
@@ -420,11 +420,44 @@ static void phb3_endpoint_init(struct phb *phb, pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32); } +static void phb3_check_device_quirks(struct phb *phb, struct pci_device *dev) +{ + struct phb3 *p = phb_to_phb3(phb); + u64 modectl; + u32 vdid; + u16 vendor, device; + + /* For these adapters, if they are directly under the PHB, we + * adjust some settings for performances + */ + xscom_read(p->chip_id, p->pe_xscom + 0x0b, &modectl); + + pci_cfg_read32(phb, dev->bdfn, 0, &vdid); + vendor = vdid & 0xffff; + device = vdid >> 16; + if (vendor == 0x15b3 && + (device == 0x1003 || /* Travis3-EN (CX3) */ + device == 0x1011 || /* HydePark (ConnectIB) */ + device == 0x1013)) { /* GlacierPark (CX4) */ + /* Set disable_wr_scope_group bit */ + modectl |= PPC_BIT(14); + } else { + /* Clear disable_wr_scope_group bit */ + modectl &= ~PPC_BIT(14); + } + + xscom_write(p->chip_id, p->pe_xscom + 0x0b, modectl); +} + static void phb3_device_init(struct phb *phb, struct pci_device *dev) { int ecap = 0; int aercap = 0; + /* Some special adapter tweaks for devices directly under the PHB */ + if (dev->primary_bus == 1) + phb3_check_device_quirks(phb, dev); + /* Figure out PCIe & AER capability */ if (pci_has_cap(dev, PCI_CFG_CAP_ID_EXP, false)) { ecap = pci_cap(dev, PCI_CFG_CAP_ID_EXP, false); |