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>
This commit is contained in:
Jianjun Wang
2021-07-24 14:50:36 +08:00
committed by Hung-Te Lin
parent 60df92fdce
commit 777ffff442
3 changed files with 36 additions and 0 deletions

View File

@@ -1203,6 +1203,30 @@ static void pci_scan_hidden_device(struct device *dev)
dev->device, dev->ops ? "" : " No operations");
}
/**
* 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.
*
@@ -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.