From 359d8a63fcb752d212a10b97b7d312aacc1be469 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 1 Oct 2023 21:25:04 +0200 Subject: sb/intel/bd82x6x: Improve SLCAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use pci_find_capability() and defines from pci_def.h - Set the 'Hotplug Capable' bit and 'Hot Plug Surprise' bit in SLCAP for hotplugable PCIe slots. - Assign unique slot number and set power limit for PCIe root ports that have a slot connected. For integrated devices clear slot number and power limit. Test: System still boots and all PCIe devices are working. Change-Id: I03aeb0a1ff0041901acc20fe700d3f7995d22366 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/78228 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/southbridge/intel/bd82x6x/pcie.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'src/southbridge/intel') diff --git a/src/southbridge/intel/bd82x6x/pcie.c b/src/southbridge/intel/bd82x6x/pcie.c index 206894d8a4..da6e007501 100644 --- a/src/southbridge/intel/bd82x6x/pcie.c +++ b/src/southbridge/intel/bd82x6x/pcie.c @@ -42,8 +42,10 @@ static bool pci_is_hotplugable(struct device *dev) static void pch_pcie_pm_early(struct device *dev) { u16 link_width_p0, link_width_p4; + struct device *child = NULL; u8 slot_power_limit = 10; /* 10W for x1 */ - u32 reg32; + static u8 slot_number = 1; + u32 reg32, cap; u8 reg8; reg32 = RCBA32(RPC); @@ -136,12 +138,31 @@ static void pch_pcie_pm_early(struct device *dev) } pci_write_config32(dev, 0x4c, reg32); + /* + * PCI device enumeration hasn't started yet, thus any downstream device here + * must be a static device from devicetree.cb. + * If one is found assume it's an integrated device and not a PCIe slot. + */ + if (dev->link_list) + child = pcidev_path_behind(dev->link_list, PCI_DEVFN(0, 0)); + /* Set slot power limit as configured above */ - reg32 = pci_read_config32(dev, 0x54); - reg32 &= ~((1 << 15) | (1 << 16)); /* 16:15 = Slot power scale */ - reg32 &= ~(0xff << 7); /* 14:7 = Slot power limit */ - reg32 |= (slot_power_limit << 7); - pci_write_config32(dev, 0x54, reg32); + cap = pci_find_capability(dev, PCI_CAP_ID_PCIE); + + reg32 = pci_read_config32(dev, cap + PCI_EXP_SLTCAP); + if (pci_is_hotplugable(dev)) + reg32 |= (PCI_EXP_SLTCAP_HPS | PCI_EXP_SLTCAP_HPC); + else + reg32 &= ~(PCI_EXP_SLTCAP_HPS | PCI_EXP_SLTCAP_HPC); + reg32 &= ~PCI_EXP_SLTCAP_SPLS; /* 16:15 = Slot power scale */ + reg32 &= ~PCI_EXP_SLTCAP_SPLV; /* 14:7 = Slot power limit */ + reg32 &= ~PCI_EXP_SLTCAP_PSN; + if (!child || !child->on_mainboard) { + /* Only PCIe slots have a power limit and slot number */ + reg32 |= (slot_power_limit << 7); + reg32 |= (slot_number++ << 19); + } + pci_write_config32(dev, cap + PCI_EXP_SLTCAP, reg32); } static void pch_pcie_pm_late(struct device *dev) -- cgit v1.2.3