summaryrefslogtreecommitdiff
path: root/src/soc/intel/xeon_sp/acpi.c
diff options
context:
space:
mode:
authorLu, Pen-ChunX <pen-chunx.lu@intel.com>2024-05-07 22:42:12 +0800
committerFelix Held <felix-coreboot@felixheld.de>2024-08-01 15:32:25 +0000
commit00d538b562f2be74a9b65df3cc68b0ec68417a7f (patch)
tree0bf651520f8b7fa05a73f5ec2692db219e0c5107 /src/soc/intel/xeon_sp/acpi.c
parent188909aad4ba3eeadba2c7ad6fc08858800b8f7d (diff)
soc/intel/xeon_sp: Add acpigen_write_pci_root_port
acpigen_write_pci_root_port writes SSDT device objects for PCIe root port, _ADR and _BBN are provided. SSDT objects for direct subordinate devices will also be created (if detected), _ADR and _SUN are provided. TEST=Build and boot on intel/archercity CRB Change-Id: I434fea7880a463c2027abfa22ba2b3bb985815c0 Signed-off-by: Lu, Pen-ChunX <pen-chunx.lu@intel.com> Signed-off-by: Jincheng Li <jincheng.li@intel.com> Signed-off-by: Shuo Liu <shuo.liu@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/82252 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Diffstat (limited to 'src/soc/intel/xeon_sp/acpi.c')
-rw-r--r--src/soc/intel/xeon_sp/acpi.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/soc/intel/xeon_sp/acpi.c b/src/soc/intel/xeon_sp/acpi.c
index e5cf9076ec..e0c2f3bfb2 100644
--- a/src/soc/intel/xeon_sp/acpi.c
+++ b/src/soc/intel/xeon_sp/acpi.c
@@ -1,7 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <acpi/acpigen.h>
+#include <acpi/acpigen_pci.h>
#include <assert.h>
+#include <device/pci_ops.h>
#include <intelblocks/acpi.h>
#include <soc/chip_common.h>
#include <soc/pci_devs.h>
@@ -139,3 +141,55 @@ void acpigen_write_OSC_pci_domain_fixed_caps(const struct device *domain,
acpigen_pop_len();
}
+
+static bool read_physical_slot_number(const struct device *dev, uint8_t *psn)
+{
+ if (!is_pci(dev))
+ return false;
+
+ const size_t pos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
+ if (!pos)
+ return false;
+
+ u32 sltcap = pci_read_config32(dev, pos + PCI_EXP_SLTCAP);
+ *psn = ((sltcap >> 19) & 0x1FF);
+ return true;
+}
+
+static void acpigen_write_pci_root_port_devices(const struct device *rp)
+{
+ uint8_t psn;
+ bool have_psn = read_physical_slot_number(rp, &psn);
+
+ struct device *dev = NULL;
+ while ((dev = dev_bus_each_child(rp->downstream, dev))) {
+ if (!is_pci(dev))
+ continue;
+ const char *name = acpi_device_name(dev);
+ if (!name)
+ continue;
+ acpigen_write_device(name);
+ acpigen_write_ADR_pci_device(dev);
+ if (have_psn)
+ acpigen_write_name_integer("_SUN", psn);
+ acpigen_pop_len();
+ }
+}
+
+void acpigen_write_pci_root_port(const struct device *rp)
+{
+ const char *acpi_scope = acpi_device_scope(rp);
+ if (!acpi_scope)
+ return;
+ acpigen_write_scope(acpi_scope);
+
+ const char *acpi_name = acpi_device_name(rp);
+ if (!acpi_name)
+ return;
+ acpigen_write_device(acpi_name);
+ acpigen_write_ADR_pci_device(rp);
+ acpigen_write_pci_root_port_devices(rp);
+
+ acpigen_pop_len();
+ acpigen_pop_len();
+}