summaryrefslogtreecommitdiff
path: root/src/soc/intel/xeon_sp
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/xeon_sp')
-rw-r--r--src/soc/intel/xeon_sp/acpi.c54
-rw-r--r--src/soc/intel/xeon_sp/include/soc/acpi.h1
2 files changed, 55 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();
+}
diff --git a/src/soc/intel/xeon_sp/include/soc/acpi.h b/src/soc/intel/xeon_sp/include/soc/acpi.h
index 7c7aee0ad4..fd693c809d 100644
--- a/src/soc/intel/xeon_sp/include/soc/acpi.h
+++ b/src/soc/intel/xeon_sp/include/soc/acpi.h
@@ -38,5 +38,6 @@ void acpigen_write_OSC_pci_domain_fixed_caps(const struct device *domain,
const uint32_t granted_pcie_features,
const bool is_cxl_domain,
const uint32_t granted_cxl_features);
+void acpigen_write_pci_root_port(const struct device *rp);
#endif /* _SOC_ACPI_H_ */