diff options
author | Jianjun Wang <jianjun.wang@mediatek.com> | 2021-07-24 14:50:36 +0800 |
---|---|---|
committer | Hung-Te Lin <hungte@chromium.org> | 2021-11-29 03:19:51 +0000 |
commit | 777ffff4421a9ab0961f2284e7448307f3c5154f (patch) | |
tree | f6108138ca5fe3f73025a2a8374c0588a386673b /src/device | |
parent | 60df92fdce147b56ba5e830f962435589dbd258b (diff) |
device/pci_device.c: Scan only one device for PCIe
Only scan one device if it's a PCIe downstream port.
A PCIe downstream port normally leads to a link with only device 0 on
it. As an optimization, scan only for device 0 in that case.
Signed-off-by: Jianjun Wang <jianjun.wang@mediatek.com>
Change-Id: Id184d03b33e1742b18efb3f11aa9b2f81fa03806
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56788
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Diffstat (limited to 'src/device')
-rw-r--r-- | src/device/pci_device.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/device/pci_device.c b/src/device/pci_device.c index 4b5e73b806..1075ef7e0e 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -1204,6 +1204,30 @@ static void pci_scan_hidden_device(struct device *dev) } /** + * A PCIe Downstream Port normally leads to a Link with only Device 0 on it + * (PCIe spec r5.0, sec 7.3.1). As an optimization, scan only for Device 0 in + * that situation. + * + * @param bus Pointer to the bus structure. + */ +static bool pci_bus_only_one_child(struct bus *bus) +{ + struct device *bridge = bus->dev; + u16 pcie_pos, pcie_flags_reg; + int pcie_type; + + pcie_pos = pci_find_capability(bridge, PCI_CAP_ID_PCIE); + if (!pcie_pos) + return false; + + pcie_flags_reg = pci_read_config16(bridge, pcie_pos + PCI_EXP_FLAGS); + + pcie_type = (pcie_flags_reg & PCI_EXP_FLAGS_TYPE) >> 4; + + return pciexp_is_downstream_port(pcie_type); +} + +/** * Scan a PCI bus. * * Determine the existence of devices and bridges on a PCI bus. If there are @@ -1232,6 +1256,9 @@ void pci_scan_bus(struct bus *bus, unsigned int min_devfn, post_code(0x24); + if (pci_bus_only_one_child(bus)) + max_devfn = MIN(max_devfn, 0x07); + /* * Probe all devices/functions on this bus with some optimization for * non-existence and single function devices. |