mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-02 04:37:44 +08:00
Merge branch 'pci/enumeration'
- Use PCI_HEADER_TYPE_* defines, not hard-coded values (Ilpo Järvinen) - Clean up early_dump_pci_device() to avoid hard-coded values (Ilpo Järvinen) - Clean up pci_scan_child_bus_extend() loop to avoid hard-coded values (Ilpo Järvinen) - Add a Xeon 6 quirk to disable Extended Tags and limit Max Read Request Size to 128B to avoid a performance issue (Ilpo Järvinen) * pci/enumeration: PCI: Add Extended Tag + MRRS quirk for Xeon 6 PCI: Clean up pci_scan_child_bus_extend() loop PCI: Clean up early_dump_pci_device() PCI: Use header type defines in pci_setup_device()
This commit is contained in:
@@ -294,6 +294,46 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB1, pcie_r
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk);
|
||||
|
||||
/*
|
||||
* PCIe devices underneath Xeon 6 PCIe Root Port bifurcated to x2 have lower
|
||||
* performance with Extended Tags and MRRS > 128B. Work around the performance
|
||||
* problems by disabling Extended Tags and limiting MRRS to 128B.
|
||||
*
|
||||
* https://cdrdv2.intel.com/v1/dl/getContent/837176
|
||||
*/
|
||||
static int limit_mrrs_to_128(struct pci_host_bridge *b, struct pci_dev *pdev)
|
||||
{
|
||||
int readrq = pcie_get_readrq(pdev);
|
||||
|
||||
if (readrq > 128)
|
||||
pcie_set_readrq(pdev, 128);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pci_xeon_x2_bifurc_quirk(struct pci_dev *pdev)
|
||||
{
|
||||
struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
|
||||
u32 linkcap;
|
||||
|
||||
pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &linkcap);
|
||||
if (FIELD_GET(PCI_EXP_LNKCAP_MLW, linkcap) != 0x2)
|
||||
return;
|
||||
|
||||
bridge->no_ext_tags = 1;
|
||||
bridge->enable_device = limit_mrrs_to_128;
|
||||
pci_info(pdev, "Disabling Extended Tags and limiting MRRS to 128B (performance reasons due to x2 PCIe link)\n");
|
||||
}
|
||||
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db0, pci_xeon_x2_bifurc_quirk);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db1, pci_xeon_x2_bifurc_quirk);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db2, pci_xeon_x2_bifurc_quirk);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db3, pci_xeon_x2_bifurc_quirk);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db6, pci_xeon_x2_bifurc_quirk);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db7, pci_xeon_x2_bifurc_quirk);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db8, pci_xeon_x2_bifurc_quirk);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db9, pci_xeon_x2_bifurc_quirk);
|
||||
|
||||
/*
|
||||
* Fixup to mark boot BIOS video selected by BIOS before it changes
|
||||
*
|
||||
|
||||
@@ -8,6 +8,7 @@ struct pcie_tlp_log;
|
||||
|
||||
/* Number of possible devfns: 0.0 to 1f.7 inclusive */
|
||||
#define MAX_NR_DEVFNS 256
|
||||
#define PCI_MAX_NR_DEVS 32
|
||||
|
||||
#define MAX_NR_LANES 16
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* PCI detection and setup code
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
@@ -1912,16 +1913,16 @@ static int pci_intx_mask_broken(struct pci_dev *dev)
|
||||
|
||||
static void early_dump_pci_device(struct pci_dev *pdev)
|
||||
{
|
||||
u32 value[256 / 4];
|
||||
u32 value[PCI_CFG_SPACE_SIZE / sizeof(u32)];
|
||||
int i;
|
||||
|
||||
pci_info(pdev, "config space:\n");
|
||||
|
||||
for (i = 0; i < 256; i += 4)
|
||||
pci_read_config_dword(pdev, i, &value[i / 4]);
|
||||
for (i = 0; i < ARRAY_SIZE(value); i++)
|
||||
pci_read_config_dword(pdev, i * sizeof(u32), &value[i]);
|
||||
|
||||
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
value, 256, false);
|
||||
value, ARRAY_SIZE(value) * sizeof(u32), false);
|
||||
}
|
||||
|
||||
static const char *pci_type_str(struct pci_dev *dev)
|
||||
@@ -1985,8 +1986,8 @@ int pci_setup_device(struct pci_dev *dev)
|
||||
dev->sysdata = dev->bus->sysdata;
|
||||
dev->dev.parent = dev->bus->bridge;
|
||||
dev->dev.bus = &pci_bus_type;
|
||||
dev->hdr_type = hdr_type & 0x7f;
|
||||
dev->multifunction = !!(hdr_type & 0x80);
|
||||
dev->hdr_type = FIELD_GET(PCI_HEADER_TYPE_MASK, hdr_type);
|
||||
dev->multifunction = FIELD_GET(PCI_HEADER_TYPE_MFD, hdr_type);
|
||||
dev->error_state = pci_channel_io_normal;
|
||||
set_pcie_port_type(dev);
|
||||
|
||||
@@ -3045,14 +3046,14 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
|
||||
{
|
||||
unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0;
|
||||
unsigned int start = bus->busn_res.start;
|
||||
unsigned int devfn, cmax, max = start;
|
||||
unsigned int devnr, cmax, max = start;
|
||||
struct pci_dev *dev;
|
||||
|
||||
dev_dbg(&bus->dev, "scanning bus\n");
|
||||
|
||||
/* Go find them, Rover! */
|
||||
for (devfn = 0; devfn < 256; devfn += 8)
|
||||
pci_scan_slot(bus, devfn);
|
||||
for (devnr = 0; devnr < PCI_MAX_NR_DEVS; devnr++)
|
||||
pci_scan_slot(bus, PCI_DEVFN(devnr, 0));
|
||||
|
||||
/* Reserve buses for SR-IOV capability */
|
||||
used_buses = pci_iov_bus_range(bus);
|
||||
|
||||
Reference in New Issue
Block a user