summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKane Chen <kane.chen@intel.com>2016-07-11 12:17:13 +0800
committerAaron Durbin <adurbin@chromium.org>2016-07-15 18:20:54 +0200
commitd779605c29a1630a256c8a1c4966214c580481ec (patch)
tree7a256924f020fe35004cb4288bd126fb116ac5c5
parent97fc426070887ecfcaf3988ea8df02d1c682317a (diff)
soc/intel/apollolake: Properly disable PCIe root ports
1. The hotplug feature needs to be disabled so that pcie root ports will be disabled by fsp 2. Correct PcieRootPortEn mapping. The correct mapping should be like below PcieRootPortEn[0] ==> 00:14.0 PcieRootPortEn[1] ==> 00:14.1 PcieRootPortEn[2] ==> 00:13.0 PcieRootPortEn[3] ==> 00:13.1 PcieRootPortEn[4] ==> 00:13.2 PcieRootPortEn[5] ==> 00:13.3 BUG=chrome-os-partner:54288 BRANCH=None TEST=Checked pcie root port is disabled properly and make sure pcie ports are coalesced. Also make sure the device will still be enabled after coalescence when pcie on function 0 is disabled devicetree Change-Id: I39c482a0c068ddc2cc573499480c3fe6a52dd5eb Signed-off-by: Kane Chen <kane.chen@intel.com> Reviewed-on: https://review.coreboot.org/15595 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/soc/intel/apollolake/chip.c70
1 files changed, 64 insertions, 6 deletions
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c
index 0d4cfce475..9d08c57015 100644
--- a/src/soc/intel/apollolake/chip.c
+++ b/src/soc/intel/apollolake/chip.c
@@ -141,6 +141,55 @@ static void enable_dev(device_t dev)
}
}
+/*
+ * If the PCIe root port at function 0 is disabled,
+ * the PCIe root ports might be coalesced after FSP silicon init.
+ * The below function will swap the devfn of the first enabled device
+ * in devicetree and function 0 resides a pci device
+ * so that it won't confuse coreboot.
+ */
+static void pcie_update_device_tree(unsigned int devfn0, int num_funcs)
+{
+ device_t func0;
+ unsigned int devfn;
+ int i;
+ unsigned int inc = PCI_DEVFN(0, 1);
+
+ func0 = dev_find_slot(0, devfn0);
+ if (func0 == NULL)
+ return;
+
+ /* No more functions if function 0 is disabled. */
+ if (pci_read_config32(func0, PCI_VENDOR_ID) == 0xffffffff)
+ return;
+
+ devfn = devfn0 + inc;
+
+ /*
+ * Increase funtion by 1.
+ * Then find first enabled device to replace func0
+ * as that port was move to func0.
+ */
+ for (i = 1; i < num_funcs; i++, devfn += inc) {
+ device_t dev = dev_find_slot(0, devfn);
+ if (dev == NULL)
+ continue;
+
+ if (!dev->enabled)
+ continue;
+ /* Found the first enabled device in given dev number */
+ func0->path.pci.devfn = dev->path.pci.devfn;
+ dev->path.pci.devfn = devfn0;
+ break;
+ }
+}
+
+static void pcie_override_devicetree_after_silicon_init(void)
+{
+ pcie_update_device_tree(PCIEA0_DEVFN, 4);
+ pcie_update_device_tree(PCIEB0_DEVFN, 2);
+}
+
static void soc_init(void *data)
{
struct range_entry range;
@@ -162,6 +211,9 @@ static void soc_init(void *data)
/* Restore GPIO IRQ polarities back to previous settings. */
itss_restore_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
+ /* override 'enabled' setting in device tree if needed */
+ pcie_override_devicetree_after_silicon_init();
+
/*
* Keep the P2SB device visible so it and the other devices are
* visible in coreboot for driver support and PCI resource allocation.
@@ -194,23 +246,29 @@ static void disable_dev(struct device *dev, struct FSP_S_CONFIG *silconfig) {
case SATA_DEVFN:
silconfig->EnableSata = 0;
break;
- case PCIEA0_DEVFN:
+ case PCIEB0_DEVFN:
silconfig->PcieRootPortEn[0] = 0;
+ silconfig->PcieRpHotPlug[0] = 0;
break;
- case PCIEA1_DEVFN:
+ case PCIEB1_DEVFN:
silconfig->PcieRootPortEn[1] = 0;
+ silconfig->PcieRpHotPlug[1] = 0;
break;
- case PCIEA2_DEVFN:
+ case PCIEA0_DEVFN:
silconfig->PcieRootPortEn[2] = 0;
+ silconfig->PcieRpHotPlug[2] = 0;
break;
- case PCIEA3_DEVFN:
+ case PCIEA1_DEVFN:
silconfig->PcieRootPortEn[3] = 0;
+ silconfig->PcieRpHotPlug[3] = 0;
break;
- case PCIEB0_DEVFN:
+ case PCIEA2_DEVFN:
silconfig->PcieRootPortEn[4] = 0;
+ silconfig->PcieRpHotPlug[4] = 0;
break;
- case PCIEB1_DEVFN:
+ case PCIEA3_DEVFN:
silconfig->PcieRootPortEn[5] = 0;
+ silconfig->PcieRpHotPlug[5] = 0;
break;
case XHCI_DEVFN:
silconfig->Usb30Mode = 0;