diff options
Diffstat (limited to 'src/soc/intel/skylake')
-rw-r--r-- | src/soc/intel/skylake/chip.c | 139 |
1 files changed, 17 insertions, 122 deletions
diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index 7987f46954..1e0803c67b 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -15,10 +15,8 @@ #include <bootmode.h> #include <bootstate.h> -#include <device/pci.h> #include <fsp/api.h> #include <arch/acpi.h> -#include <device/pci_ops.h> #include <console/console.h> #include <device/device.h> #include <device/pci_ids.h> @@ -27,6 +25,7 @@ #include <intelblocks/itss.h> #include <intelblocks/lpc_lib.h> #include <intelblocks/mp_init.h> +#include <intelblocks/pcie_rp.h> #include <intelblocks/xdci.h> #include <intelblocks/p2sb.h> #include <intelpch/lockdown.h> @@ -44,129 +43,22 @@ #include "chip.h" -struct pcie_entry { - unsigned int devfn; - unsigned int func_count; +static const struct pcie_rp_group pch_lp_rp_groups[] = { + { .slot = PCH_DEV_SLOT_PCIE, .count = 8 }, + { .slot = PCH_DEV_SLOT_PCIE_1, .count = 4 }, + { 0 } }; -/* - * According to table 2-2 in doc#546717: - * PCI bus[function] ID - * D28:[F0 - F7] 0xA110 - 0xA117 - * D29:[F0 - F7] 0xA118 - 0xA11F - * D27:[F0 - F3] 0xA167 - 0xA16A - */ -static const struct pcie_entry pcie_table_skl_pch_h[] = { - {PCH_DEVFN_PCIE1, 8}, - {PCH_DEVFN_PCIE9, 8}, - {PCH_DEVFN_PCIE17, 4}, -}; - -/* - * According to table 2-2 in doc#564464: - * PCI bus[function] ID - * D28:[F0 - F7] 0xA290 - 0xA297 - * D29:[F0 - F7] 0xA298 - 0xA29F - * D27:[F0 - F7] 0xA2E7 - 0xA2EE - */ -static const struct pcie_entry pcie_table_kbl_pch_h[] = { - {PCH_DEVFN_PCIE1, 8}, - {PCH_DEVFN_PCIE9, 8}, - {PCH_DEVFN_PCIE17, 8}, -}; - -/* - * According to table 2-2 in doc#567995/545659: - * PCI bus[function] ID - * D28:[F0 - F7] 0x9D10 - 0x9D17 - * D29:[F0 - F3] 0x9D18 - 0x9D1B - */ -static const struct pcie_entry pcie_table_skl_pch_lp[] = { - {PCH_DEVFN_PCIE1, 8}, - {PCH_DEVFN_PCIE9, 4}, +static const struct pcie_rp_group pch_h_rp_groups[] = { + { .slot = PCH_DEV_SLOT_PCIE, .count = 8 }, + { .slot = PCH_DEV_SLOT_PCIE_1, .count = 8 }, + /* Sunrise Point PCH-H actually only has 4 ports in the + third group. But that would require a runtime check + and probing 4 non-existent ports shouldn't hurt. */ + { .slot = PCH_DEV_SLOT_PCIE_2, .count = 8 }, + { 0 } }; -/* - * 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(const struct pcie_entry *pcie_rp_group, - size_t pci_groups) -{ - struct device *func0; - unsigned int devfn, devfn0; - int i, group; - unsigned int inc = PCI_DEVFN(0, 1); - - for (group = 0; group < pci_groups; group++) { - devfn0 = pcie_rp_group[group].devfn; - func0 = pcidev_path_on_root(devfn0); - if (func0 == NULL) - continue; - - /* No more functions if function 0 is disabled. */ - if (pci_read_config32(func0, PCI_VENDOR_ID) == 0xffffffff) - continue; - - devfn = devfn0 + inc; - - /* - * Increase function by 1. - * Then find first enabled device to replace func0 - * as that port was move to func0. - */ - for (i = 1; i < pcie_rp_group[group].func_count; - i++, devfn += inc) { - struct device *dev = pcidev_path_on_root(devfn); - if (dev == NULL || !dev->enabled) - continue; - - /* - * Found the first enabled device in - * a given dev number. - */ - printk(BIOS_INFO, "PCI func %d was swapped" - " to func 0.\n", i); - func0->path.pci.devfn = dev->path.pci.devfn; - dev->path.pci.devfn = devfn0; - break; - } - } -} - -static void pcie_override_devicetree_after_silicon_init(void) -{ - uint16_t id, id_mask; - - id = pci_read_config16(PCH_DEV_PCIE1, PCI_DEVICE_ID); - /* - * We may read an ID other than func 0 after FSP-S. - * Strip out 4 least significant bits. - */ - id_mask = id & ~0xf; - printk(BIOS_INFO, "Override DT after FSP-S, PCH is "); - if (id_mask == (PCI_DEVICE_ID_INTEL_SPT_LP_PCIE_RP1 & ~0xf)) { - printk(BIOS_INFO, "KBL/SKL PCH-LP SKU\n"); - pcie_update_device_tree(&pcie_table_skl_pch_lp[0], - ARRAY_SIZE(pcie_table_skl_pch_lp)); - } else if (id_mask == (PCI_DEVICE_ID_INTEL_KBP_H_PCIE_RP1 & ~0xf)) { - printk(BIOS_INFO, "KBL PCH-H SKU\n"); - pcie_update_device_tree(&pcie_table_kbl_pch_h[0], - ARRAY_SIZE(pcie_table_kbl_pch_h)); - } else if (id_mask == (PCI_DEVICE_ID_INTEL_SPT_H_PCIE_RP1 & ~0xf)) { - printk(BIOS_INFO, "SKL PCH-H SKU\n"); - pcie_update_device_tree(&pcie_table_skl_pch_h[0], - ARRAY_SIZE(pcie_table_skl_pch_h)); - } else { - printk(BIOS_ERR, "[BUG] PCIE Root Port id 0x%x" - " is not found\n", id); - return; - } -} - void soc_init_pre_device(void *chip_info) { /* Snapshot the current GPIO IRQ polarities. FSP is setting a @@ -187,7 +79,10 @@ void soc_init_pre_device(void *chip_info) itss_restore_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); /* swap enabled PCI ports in device tree if needed */ - pcie_override_devicetree_after_silicon_init(); + if (CONFIG(SKYLAKE_SOC_PCH_H)) + pcie_rp_update_devicetree(pch_h_rp_groups); + else + pcie_rp_update_devicetree(pch_lp_rp_groups); } void soc_fsp_load(void) |