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:
parent
60df92fdce
commit
777ffff442
|
@ -1203,6 +1203,30 @@ static void pci_scan_hidden_device(struct device *dev)
|
||||||
dev->device, dev->ops ? "" : " No operations");
|
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.
|
* Scan a PCI bus.
|
||||||
*
|
*
|
||||||
|
@ -1232,6 +1256,9 @@ void pci_scan_bus(struct bus *bus, unsigned int min_devfn,
|
||||||
|
|
||||||
post_code(0x24);
|
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
|
* Probe all devices/functions on this bus with some optimization for
|
||||||
* non-existence and single function devices.
|
* non-existence and single function devices.
|
||||||
|
|
|
@ -385,6 +385,7 @@
|
||||||
#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
|
#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
|
||||||
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
|
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
|
||||||
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
|
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
|
||||||
|
#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIe Bridge */
|
||||||
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
|
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
|
||||||
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
|
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
|
||||||
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
|
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
|
||||||
|
|
|
@ -31,4 +31,12 @@ void pciexp_hotplug_scan_bridge(struct device *dev);
|
||||||
extern struct device_operations default_pciexp_hotplug_ops_bus;
|
extern struct device_operations default_pciexp_hotplug_ops_bus;
|
||||||
|
|
||||||
unsigned int pciexp_find_extended_cap(struct device *dev, unsigned int cap);
|
unsigned int pciexp_find_extended_cap(struct device *dev, unsigned int cap);
|
||||||
|
|
||||||
|
static inline bool pciexp_is_downstream_port(int type)
|
||||||
|
{
|
||||||
|
return type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||||
|
type == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||||
|
type == PCI_EXP_TYPE_PCIE_BRIDGE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* DEVICE_PCIEXP_H */
|
#endif /* DEVICE_PCIEXP_H */
|
||||||
|
|
Loading…
Reference in New Issue