aboutsummaryrefslogtreecommitdiff
path: root/hw/phb3.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-04-28 09:59:22 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-04-29 09:44:58 +1000
commit713c65c871591bfbdab1801503c65362250ee4c6 (patch)
tree5fa11302a548cbcaf3c4c6f84d2443cdd4f6aa2f /hw/phb3.c
parent8631d0b8df27a1cbe01da8551508fdd2d10477a2 (diff)
downloadskiboot-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.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/hw/phb3.c b/hw/phb3.c
index add3d59..2f6ab05 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -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);