Eran Mitrani has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/70166 )
Change subject: soc/intel/common: provide a list of D-states to enter LPM ......................................................................
soc/intel/common: provide a list of D-states to enter LPM
This was done previously for ADL. moving the code to common so it can be leveraged for other platforms (e.g. MTL)
Signed-off-by: Eran Mitrani mitrani@google.com Change-Id: I45eded3868a4987cb5eb0676c50378ac52ec3752 --- M src/include/acpi/acpi.h M src/soc/intel/alderlake/acpi.c M src/soc/intel/common/block/acpi/acpi.c M src/soc/intel/common/block/include/intelblocks/acpi.h 4 files changed, 193 insertions(+), 156 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/70166/1
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h index 57dbc65..e95c0a0 100644 --- a/src/include/acpi/acpi.h +++ b/src/include/acpi/acpi.h @@ -51,6 +51,7 @@ ACPI_DEVICE_SLEEP_D3 = 3, ACPI_DEVICE_SLEEP_D3_HOT = ACPI_DEVICE_SLEEP_D3, ACPI_DEVICE_SLEEP_D3_COLD = 4, + ACPI_DEVICE_SLEEP_NONE = 5, };
#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */ @@ -1283,7 +1284,6 @@ acpi_einj_action_table_t action_table[ACTION_COUNT]; } __packed acpi_einj_t;
- uintptr_t get_coreboot_rsdp(void); void acpi_create_einj(acpi_einj_t *einj, uintptr_t addr, u8 actions);
diff --git a/src/soc/intel/alderlake/acpi.c b/src/soc/intel/alderlake/acpi.c index c874067..60a2992 100644 --- a/src/soc/intel/alderlake/acpi.c +++ b/src/soc/intel/alderlake/acpi.c @@ -21,13 +21,6 @@ #include <cpu/cpu.h> #include <types.h>
- -#define DEFAULT_CPU_D_STATE D0 -#define LPI_STATES_ALL 0xff -#define LPI_REVISION 0 -#define LPI_ENABLED 1 - - /* * List of supported C-states in this processor. */ @@ -118,14 +111,6 @@ C_STATE_C10 };
-enum dev_sleep_states { - D0, /* 0 */ - D1, /* 1 */ - D2, /* 2 */ - D3, /* 3 */ - NONE -}; - const acpi_cstate_t *soc_get_cstate_map(size_t *entries) { static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix), @@ -180,153 +165,74 @@ fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0; }
-static const struct { - uint8_t pci_dev; - enum dev_sleep_states min_sleep_state; -} min_pci_sleep_states[] = { - { SA_DEVFN_ROOT, D3 }, - { SA_DEVFN_CPU_PCIE1_0, D3 }, - { SA_DEVFN_IGD, D3 }, - { SA_DEVFN_DPTF, D3 }, - { SA_DEVFN_IPU, D3 }, - { SA_DEVFN_CPU_PCIE6_0, D3 }, - { SA_DEVFN_CPU_PCIE6_2, D3 }, - { SA_DEVFN_TBT0, D3 }, - { SA_DEVFN_TBT1, D3 }, - { SA_DEVFN_TBT2, D3 }, - { SA_DEVFN_TBT3, D3 }, - { SA_DEVFN_GNA, D3 }, - { SA_DEVFN_TCSS_XHCI, D3 }, - { SA_DEVFN_TCSS_XDCI, D3 }, - { SA_DEVFN_TCSS_DMA0, D3 }, - { SA_DEVFN_TCSS_DMA1, D3 }, - { SA_DEVFN_VMD, D3 }, - { PCH_DEVFN_I2C6, D3 }, - { PCH_DEVFN_I2C7, D3 }, - { PCH_DEVFN_THC0, D3 }, - { PCH_DEVFN_THC1, D3 }, - { PCH_DEVFN_XHCI, D3 }, - { PCH_DEVFN_USBOTG, D3 }, - { PCH_DEVFN_SRAM, D3 }, - { PCH_DEVFN_CNVI_WIFI, D3 }, - { PCH_DEVFN_I2C0, D3 }, - { PCH_DEVFN_I2C1, D3 }, - { PCH_DEVFN_I2C2, D3 }, - { PCH_DEVFN_I2C3, D3 }, - { PCH_DEVFN_CSE, D0 }, - { PCH_DEVFN_SATA, D3 }, - { PCH_DEVFN_I2C4, D3 }, - { PCH_DEVFN_I2C5, D3 }, - { PCH_DEVFN_UART2, D3 }, - { PCH_DEVFN_PCIE1, D0 }, - { PCH_DEVFN_PCIE2, D0 }, - { PCH_DEVFN_PCIE3, D0 }, - { PCH_DEVFN_PCIE4, D0 }, - { PCH_DEVFN_PCIE5, D0 }, - { PCH_DEVFN_PCIE6, D0 }, - { PCH_DEVFN_PCIE7, D0 }, - { PCH_DEVFN_PCIE8, D0 }, - { PCH_DEVFN_PCIE9, D0 }, - { PCH_DEVFN_PCIE10, D0 }, - { PCH_DEVFN_PCIE11, D0 }, - { PCH_DEVFN_PCIE12, D0 }, - { PCH_DEVFN_UART0, D3 }, - { PCH_DEVFN_UART1, D3 }, - { PCH_DEVFN_GSPI0, D3 }, - { PCH_DEVFN_GSPI1, D3 }, - { PCH_DEVFN_ESPI, D0 }, - { PCH_DEVFN_PMC, D0 }, - { PCH_DEVFN_HDA, D0 }, - { PCH_DEVFN_SPI, D3 }, - { PCH_DEVFN_GBE, D3 }, +min_sleep_state_t min_pci_sleep_states[] = { + { SA_DEVFN_ROOT, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_CPU_PCIE1_0, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_IGD, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_DPTF, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_IPU, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_CPU_PCIE6_0, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_CPU_PCIE6_2, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TBT0, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TBT1, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TBT2, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TBT3, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_GNA, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TCSS_XHCI, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TCSS_XDCI, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TCSS_DMA0, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_TCSS_DMA1, ACPI_DEVICE_SLEEP_D3 }, + { SA_DEVFN_VMD, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C6, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C7, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_THC0, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_THC1, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_XHCI, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_USBOTG, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_SRAM, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_CNVI_WIFI, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C0, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C1, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C2, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C3, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_CSE, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_SATA, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C4, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_I2C5, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_UART2, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_PCIE1, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE2, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE3, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE4, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE5, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE6, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE7, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE8, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE9, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE10, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE11, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PCIE12, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_UART0, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_UART1, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_GSPI0, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_GSPI1, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_ESPI, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_PMC, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_HDA, ACPI_DEVICE_SLEEP_D0 }, + { PCH_DEVFN_SPI, ACPI_DEVICE_SLEEP_D3 }, + { PCH_DEVFN_GBE, ACPI_DEVICE_SLEEP_D3 }, };
-static enum dev_sleep_states get_min_sleep_state(const struct device *dev) +min_sleep_state_t **get_min_sleep_state_array(int *size) { - if (!is_dev_enabled(dev)) - return NONE; - - switch (dev->path.type) { - case DEVICE_PATH_APIC: - return DEFAULT_CPU_D_STATE; - - case DEVICE_PATH_PCI: - for (size_t i = 0; i < ARRAY_SIZE(min_pci_sleep_states); i++) - if (min_pci_sleep_states[i].pci_dev == dev->path.pci.devfn) - return min_pci_sleep_states[i].min_sleep_state; - printk(BIOS_WARNING, "Unknown min d_state for %x\n", dev->path.pci.devfn); - return NONE; - - default: - return NONE; - } + *size = ARRAY_SIZE(min_pci_sleep_states); + return (&min_pci_sleep_states); }
/* Generate the LPI constraint table and return the number of devices included */ void soc_lpi_get_constraints(void *unused) { - unsigned int num_entries; - const struct device *dev; - enum dev_sleep_states min_sleep_state; - - num_entries = 0; - - for (dev = all_devices; dev; dev = dev->next) { - if (get_min_sleep_state(dev) != NONE) - num_entries++; - } - - acpigen_emit_byte(RETURN_OP); - acpigen_write_package(num_entries); - - size_t cpu_index = 0; - for (dev = all_devices; dev; dev = dev->next) { - min_sleep_state = get_min_sleep_state(dev); - if (min_sleep_state == NONE) - continue; - - acpigen_write_package(3); - { - char path[32] = { 0 }; - /* Emit the device path */ - switch (dev->path.type) { - case DEVICE_PATH_PCI: - acpigen_emit_namestring(acpi_device_path(dev)); - break; - - case DEVICE_PATH_APIC: - snprintf(path, sizeof(path), CONFIG_ACPI_CPU_STRING, - cpu_index++); - acpigen_emit_namestring(path); - break; - - default: - /* Unhandled */ - printk(BIOS_WARNING, - "Unhandled device path type %d\n", dev->path.type); - acpigen_emit_namestring(NULL); - break; - } - - acpigen_write_integer(LPI_ENABLED); - acpigen_write_package(2); - { - acpigen_write_integer(LPI_REVISION); - acpigen_write_package(2); /* no optional device info */ - { - /* Assume constraints apply to all entries */ - acpigen_write_integer(LPI_STATES_ALL); - acpigen_write_integer(min_sleep_state); /* min D-state */ - } - acpigen_write_package_end(); - } - acpigen_write_package_end(); - } - acpigen_write_package_end(); - } - - acpigen_write_package_end(); - printk(BIOS_INFO, "Returning SoC specific constraint package for %d devices\n", num_entries); + acpi_generate_lpi_constraint_table(); }
uint32_t soc_read_sci_irq_select(void) diff --git a/src/soc/intel/common/block/acpi/acpi.c b/src/soc/intel/common/block/acpi/acpi.c index 860c868..82cd89f 100644 --- a/src/soc/intel/common/block/acpi/acpi.c +++ b/src/soc/intel/common/block/acpi/acpi.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <acpi/acpi.h> #include <acpi/acpi_pm.h> #include <acpi/acpigen.h> #include <arch/ioapic.h> @@ -23,6 +24,11 @@
#define CPUID_6_EAX_ISST (1 << 7)
+#define DEFAULT_CPU_D_STATE ACPI_DEVICE_SLEEP_D0 +#define LPI_STATES_ALL 0xff +#define LPI_REVISION 0 +#define LPI_ENABLED 1 + static int acpi_sci_irq(void) { int sci_irq = 9; @@ -69,7 +75,6 @@ current += acpi_create_madt_irqoverride((void *)current, 0, sci, sci, flags);
- return current; }
@@ -431,3 +436,103 @@ if (CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_ENABLE)) sgx_fill_ssdt(); } + +__weak min_sleep_state_t **get_min_sleep_state_array(int *size) +{ + printk(BIOS_ERR, "%s is called without a proper implementation\n", __func__); + return NULL; +} + +static enum acpi_device_sleep_states get_min_sleep_state(const struct device *dev) +{ + min_sleep_state_t ** min_pci_sleep_states; + int array_size; + min_pci_sleep_states = get_min_sleep_state_array(&array_size); + + if (!is_dev_enabled(dev)) + return ACPI_DEVICE_SLEEP_NONE; + + switch (dev->path.type) { + case DEVICE_PATH_APIC: + return DEFAULT_CPU_D_STATE; + + case DEVICE_PATH_PCI: + /* skip external buses*/ + if (dev->bus->secondary != 0) + return NONE; + for (size_t i = 0; i < array_size; i++) + if ((*min_pci_sleep_states)[i].pci_dev == dev->path.pci.devfn) + return (*min_pci_sleep_states)[i].min_sleep_state; + printk(BIOS_WARNING, "Unknown min d_state for %x\n", dev->path.pci.devfn); + return ACPI_DEVICE_SLEEP_NONE; + + default: + return ACPI_DEVICE_SLEEP_NONE; + } +} + +void acpi_generate_lpi_constraint_table(void) +{ + unsigned int num_entries; + const struct device *dev; + enum acpi_device_sleep_states min_sleep_state; + + num_entries = 0; + + for (dev = all_devices; dev; dev = dev->next) { + if (get_min_sleep_state(dev) != ACPI_DEVICE_SLEEP_NONE) + num_entries++; + } + + acpigen_emit_byte(RETURN_OP); + acpigen_write_package(num_entries); + + size_t cpu_index = 0; + for (dev = all_devices; dev; dev = dev->next) { + min_sleep_state = get_min_sleep_state(dev); + if (min_sleep_state == ACPI_DEVICE_SLEEP_NONE) + continue; + + acpigen_write_package(3); + { + char path[32] = { 0 }; + /* Emit the device path */ + switch (dev->path.type) { + case DEVICE_PATH_PCI: + acpigen_emit_namestring(acpi_device_path(dev)); + break; + + case DEVICE_PATH_APIC: + snprintf(path, sizeof(path), CONFIG_ACPI_CPU_STRING, + cpu_index++); + acpigen_emit_namestring(path); + break; + + default: + /* Unhandled */ + printk(BIOS_WARNING, + "Unhandled device path type %d\n", dev->path.type); + acpigen_emit_namestring(NULL); + break; + } + + acpigen_write_integer(LPI_ENABLED); + acpigen_write_package(2); + { + acpigen_write_integer(LPI_REVISION); + acpigen_write_package(2); /* no optional device info */ + { + /* Assume constraints apply to all entries */ + acpigen_write_integer(LPI_STATES_ALL); + acpigen_write_integer(min_sleep_state); /* min D-state */ + } + acpigen_write_package_end(); + } + acpigen_write_package_end(); + } + acpigen_write_package_end(); + } + + acpigen_write_package_end(); + printk(BIOS_INFO, "Returning SoC specific constraint package for %d devices\n", num_entries); +} \ No newline at end of file diff --git a/src/soc/intel/common/block/include/intelblocks/acpi.h b/src/soc/intel/common/block/include/intelblocks/acpi.h index d05ddf3..6399dd2 100644 --- a/src/soc/intel/common/block/include/intelblocks/acpi.h +++ b/src/soc/intel/common/block/include/intelblocks/acpi.h @@ -133,4 +133,17 @@
/* Check if CPU supports Nominal frequency or not */ bool soc_is_nominal_freq_supported(void); + +/* Min sleep state per device*/ +typedef struct min_sleep_state { + uint8_t pci_dev; + enum acpi_device_sleep_states min_sleep_state; +} min_sleep_state_t; + +/* Returns an array that maps devices to their min sleep state*/ +min_sleep_state_t **get_min_sleep_state_array(int *size); + +/* Generates an ACPI table for LPI constraints*/ +void acpi_generate_lpi_constraint_table(void); + #endif /* _SOC_INTEL_COMMON_BLOCK_ACPI_H_ */