summaryrefslogtreecommitdiff
path: root/src/southbridge/intel/lynxpoint/pch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge/intel/lynxpoint/pch.c')
-rw-r--r--src/southbridge/intel/lynxpoint/pch.c187
1 files changed, 1 insertions, 186 deletions
diff --git a/src/southbridge/intel/lynxpoint/pch.c b/src/southbridge/intel/lynxpoint/pch.c
index f13efb0f7f..b4605f5c02 100644
--- a/src/southbridge/intel/lynxpoint/pch.c
+++ b/src/southbridge/intel/lynxpoint/pch.c
@@ -289,198 +289,13 @@ void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
pch_iobp_write(address, data);
}
-/* Check if any port in set X to X+3 is enabled */
-static int pch_pcie_check_set_enabled(device_t dev)
-{
- device_t port;
- int port_func;
- int dev_func = PCI_FUNC(dev->path.pci.devfn);
-
- printk(BIOS_DEBUG, "%s: check set enabled\n", dev_path(dev));
-
- /* Go through static device tree list of devices
- * because enumeration is still in progress */
- for (port = all_devices; port; port = port->next) {
- /* Only care about PCIe root ports */
- if (PCI_SLOT(port->path.pci.devfn) !=
- PCI_SLOT(dev->path.pci.devfn))
- continue;
-
- /* Check if port is in range and enabled */
- port_func = PCI_FUNC(port->path.pci.devfn);
- if (port_func >= dev_func &&
- port_func < (dev_func + 4) &&
- port->enabled)
- return 1;
- }
-
- /* None of the ports in this set are enabled */
- return 0;
-}
-
-/* RPFN is a write-once register so keep a copy until it is written */
-static u32 new_rpfn;
-
-/* Swap function numbers assigned to two PCIe Root Ports */
-static void pch_pcie_function_swap(u8 old_fn, u8 new_fn)
-{
- u32 old_rpfn = new_rpfn;
-
- printk(BIOS_DEBUG, "PCH: Remap PCIe function %d to %d\n",
- old_fn, new_fn);
-
- new_rpfn &= ~(RPFN_FNMASK(old_fn) | RPFN_FNMASK(new_fn));
-
- /* Old function set to new function and disabled */
- new_rpfn |= RPFN_FNSET(old_fn, RPFN_FNGET(old_rpfn, new_fn));
- new_rpfn |= RPFN_FNSET(new_fn, RPFN_FNGET(old_rpfn, old_fn));
-}
-
-/* Update devicetree with new Root Port function number assignment */
-static void pch_pcie_devicetree_update(void)
-{
- device_t dev;
-
- /* Update the function numbers in the static devicetree */
- for (dev = all_devices; dev; dev = dev->next) {
- u8 new_devfn;
-
- /* Only care about PCH PCIe root ports */
- if (PCI_SLOT(dev->path.pci.devfn) !=
- PCH_PCIE_DEV_SLOT)
- continue;
-
- /* Determine the new devfn for this port */
- new_devfn = PCI_DEVFN(PCH_PCIE_DEV_SLOT,
- RPFN_FNGET(new_rpfn,
- PCI_FUNC(dev->path.pci.devfn)));
-
- if (dev->path.pci.devfn != new_devfn) {
- printk(BIOS_DEBUG,
- "PCH: PCIe map %02x.%1x -> %02x.%1x\n",
- PCI_SLOT(dev->path.pci.devfn),
- PCI_FUNC(dev->path.pci.devfn),
- PCI_SLOT(new_devfn), PCI_FUNC(new_devfn));
-
- dev->path.pci.devfn = new_devfn;
- }
- }
-}
-
-/* Special handling for PCIe Root Port devices */
-static void pch_pcie_enable(device_t dev)
-{
- struct southbridge_intel_lynxpoint_config *config = dev->chip_info;
- u32 reg32;
-
- /*
- * Save a copy of the Root Port Function Number map when
- * starting to walk the list of PCIe Root Ports so it can
- * be updated locally and written out when the last port
- * has been processed.
- */
- if (PCI_FUNC(dev->path.pci.devfn) == 0) {
- new_rpfn = RCBA32(RPFN);
-
- /*
- * Enable Root Port coalescing if the first port is disabled
- * or the other devices will not be enumerated by the OS.
- */
- if (!dev->enabled)
- config->pcie_port_coalesce = 1;
-
- if (config->pcie_port_coalesce)
- printk(BIOS_INFO,
- "PCH: PCIe Root Port coalescing is enabled\n");
- }
-
- if (!dev->enabled) {
- printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
-
- /*
- * PCIE Power Savings for PantherPoint and CougarPoint/B1+
- *
- * If PCIe 0-3 disabled set Function 0 0xE2[0] = 1
- * If PCIe 4-7 disabled set Function 4 0xE2[0] = 1
- *
- * This check is done here instead of pcie driver
- * because the pcie driver enable() handler is not
- * called unless the device is enabled.
- */
- if ((PCI_FUNC(dev->path.pci.devfn) == 0 ||
- PCI_FUNC(dev->path.pci.devfn) == 4)) {
- /* Handle workaround for PPT and CPT/B1+ */
- if (!pch_pcie_check_set_enabled(dev)) {
- u8 reg8 = pci_read_config8(dev, 0xe2);
- reg8 |= 1;
- pci_write_config8(dev, 0xe2, reg8);
- }
-
- /*
- * Enable Clock Gating for shared PCIe resources
- * before disabling this particular port.
- */
- pci_write_config8(dev, 0xe1, 0x3c);
- }
-
- /* Ensure memory, io, and bus master are all disabled */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- reg32 &= ~(PCI_COMMAND_MASTER |
- PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
- pci_write_config32(dev, PCI_COMMAND, reg32);
-
- /* Do not claim downstream transactions for PCIe ports */
- new_rpfn |= RPFN_HIDE(PCI_FUNC(dev->path.pci.devfn));
-
- /* Disable this device if possible */
- pch_disable_devfn(dev);
- } else {
- int fn;
-
- /*
- * Check if there is a lower disabled port to swap with this
- * port in order to maintain linear order starting at zero.
- */
- if (config->pcie_port_coalesce) {
- for (fn=0; fn < PCI_FUNC(dev->path.pci.devfn); fn++) {
- if (!(new_rpfn & RPFN_HIDE(fn)))
- continue;
-
- /* Swap places with this function */
- pch_pcie_function_swap(
- PCI_FUNC(dev->path.pci.devfn), fn);
- break;
- }
- }
-
- /* Enable SERR */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- reg32 |= PCI_COMMAND_SERR;
- pci_write_config32(dev, PCI_COMMAND, reg32);
- }
-
- /*
- * When processing the last PCIe root port we can now
- * update the Root Port Function Number and Hide register.
- */
- if (PCI_FUNC(dev->path.pci.devfn) == 7) {
- printk(BIOS_SPEW, "PCH: RPFN 0x%08x -> 0x%08x\n",
- RCBA32(RPFN), new_rpfn);
- RCBA32(RPFN) = new_rpfn;
-
- /* Update static devictree with new function numbers */
- if (config->pcie_port_coalesce)
- pch_pcie_devicetree_update();
- }
-}
-
void pch_enable(device_t dev)
{
u32 reg32;
/* PCH PCIe Root Ports get special handling */
if (PCI_SLOT(dev->path.pci.devfn) == PCH_PCIE_DEV_SLOT)
- return pch_pcie_enable(dev);
+ return pch_pcie_enable_dev(dev);
if (!dev->enabled) {
printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));