Lean Sheng Tan has submitted this change. ( https://review.coreboot.org/c/coreboot/+/81567?usp=email )
(
12 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: soc/intel/xeon_sp: Add PCIe root port driver ......................................................................
soc/intel/xeon_sp: Add PCIe root port driver
The driver sets ACPI names for PCIe root ports and its subordinate devices, and fill SSDT for them accordingly. SPR PCIe root port devices are initially supported.
TEST=Build and boot on intel/archercity CRB
Change-Id: I81bd5d5a2e62301543a332162a5a789e0793e18e Signed-off-by: Shuo Liu shuo.liu@intel.com Signed-off-by: Jincheng Li jincheng.li@intel.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/81567 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Lean Sheng Tan sheng.tan@9elements.com --- M src/soc/intel/xeon_sp/Makefile.mk A src/soc/intel/xeon_sp/pcie_root_port.c 2 files changed, 92 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Lean Sheng Tan: Looks good to me, approved
diff --git a/src/soc/intel/xeon_sp/Makefile.mk b/src/soc/intel/xeon_sp/Makefile.mk index 35b998c..4f87367 100644 --- a/src/soc/intel/xeon_sp/Makefile.mk +++ b/src/soc/intel/xeon_sp/Makefile.mk @@ -16,6 +16,7 @@ ramstage-y += memmap.c pch.c lockdown.c finalize.c ramstage-y += numa.c ramstage-y += config.c +ramstage-y += pcie_root_port.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PMC) += pmc.c pmutil.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += uncore_acpi.c acpi.c ramstage-$(CONFIG_SOC_INTEL_HAS_CXL) += uncore_acpi_cxl.c diff --git a/src/soc/intel/xeon_sp/pcie_root_port.c b/src/soc/intel/xeon_sp/pcie_root_port.c new file mode 100644 index 0000000..fb9abde --- /dev/null +++ b/src/soc/intel/xeon_sp/pcie_root_port.c @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <device/pci.h> +#include <device/pciexp.h> +#include <device/pci_ids.h> +#include <soc/acpi.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> + +static const char *pcie_device_get_acpi_name(const struct device *dev) +{ + /* + * dev->name cannot be assigned in this routine with const struct device *, + * instead, it is set up in pcie_device_set_acpi_name ahead of time. + */ + assert(dev->name); + return dev->name; +} + +static void soc_pciexp_scan_bridge(struct device *dev) +{ + if (CONFIG(PCIEXP_HOTPLUG)) { + unsigned int pciexpos = pci_find_capability(dev, PCI_CAP_ID_PCIE); + u16 sltcap = pci_read_config16(dev, pciexpos + PCI_EXP_SLTCAP); + if (sltcap & PCI_EXP_SLTCAP_HPC) { + pciexp_hotplug_scan_bridge(dev); + return; + } + } else + pciexp_scan_bridge(dev); +} + +static void pcie_device_set_acpi_name(struct device *dev, const char *prefix) +{ + assert(prefix != NULL && strlen(prefix) == 2); + if (!prefix || strlen(prefix) != 2) + return; + + char *name = xmalloc(ACPI_NAME_BUFFER_SIZE); + uint8_t slot = PCI_SLOT(dev->path.pci.devfn); + uint8_t func = PCI_FUNC(dev->path.pci.devfn); + snprintf(name, ACPI_NAME_BUFFER_SIZE, "%s%02X", prefix, PCI_DEVFN(slot, func)); + dev->name = name; +} + +static void pcie_root_port_init(struct device *rp) +{ + if (!is_pci_bridge(rp)) + return; + + pcie_device_set_acpi_name(rp, "RP"); + + struct device *dev = NULL; + while ((dev = dev_bus_each_child(rp->downstream, dev))) { + if (!is_pci(dev)) + continue; + pcie_device_set_acpi_name(dev, "DC"); + } + + pci_dev_init(rp); +} + +static const unsigned short pcie_root_port_ids[] = { + /* + * Refer to https://pcisig.com/developers/integrators-list?field_il_comp_product_type_va... + */ + 0x352a, + 0x352b, + 0x352c, + 0x352d, + 0x347a, + 0 +}; + +static struct device_operations pcie_root_port_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .scan_bus = soc_pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .init = pcie_root_port_init, + .ops_pci = &soc_pci_ops, + .acpi_fill_ssdt = &acpigen_write_pci_root_port, + .acpi_name = &pcie_device_get_acpi_name, +}; + +static const struct pci_driver pcie_root_port_driver __pci_driver = { + .ops = &pcie_root_port_ops, + .vendor = PCI_VID_INTEL, + .devices = pcie_root_port_ids, +};