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>
This commit is contained in:
parent
f373188e64
commit
5e521d7e62
2 changed files with 92 additions and 0 deletions
|
|
@ -16,6 +16,7 @@ ramstage-y += uncore.c reset.c util.c lpc.c spi.c ramstage.c chip_common.c
|
|||
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
|
||||
|
|
|
|||
91
src/soc/intel/xeon_sp/pcie_root_port.c
Normal file
91
src/soc/intel/xeon_sp/pcie_root_port.c
Normal file
|
|
@ -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_value=All&keys=Intel
|
||||
*/
|
||||
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,
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue