Attention is currently required from: Patrick Rudolph. Sridhar Siricilla has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/59359 )
Change subject: soc/intel/common: Implements ACPI CPPCv3 package to support hybrid core ......................................................................
soc/intel/common: Implements ACPI CPPCv3 package to support hybrid core
The patch implements ACPI CPPCv3 package. It implements and updates the following methods: core_fill_gnvs(): It update GNVS hybrid core specific elements
generate_cppc_entries(): Updates method to support CPPCv3 package
acpigen_write_CPPC_hybrid_method(): It generates ACPI code to implement _CPC method and calls XPPPC method.
acpi_write_xppc_method(): It generate ACPI code if cpu supports Nominal Frequency. It generates ACPI code which sets Nominal Frequency and update Nominal Performance. It uses below calculation to update the Nominal Frequency and Nominal Performance: Nominal Frequency = Max non-turbo ratio * cpu_bus_frequency Nominal Performance = Max non-turn ratio * cpu scaling factor Cpu scaling factor varies in the hybrid core environment. So, the generated ACPI code updates Nominal based on the cpu's scaling factor.
It also updates GNVS structure.
TEST=Verified on Brya
Signed-off-by: Sridhar Siricilla sridhar.siricilla@intel.com Change-Id: I12205df9085b51061df5bb7069e6d3ea45535d3d
methods to generate ACPI code.
Change-Id: Icd5ea9e70bebd1e66d3cea2bcf8a6678e5cc95ca --- M src/soc/intel/common/block/acpi/Kconfig M src/soc/intel/common/block/acpi/Makefile.inc M src/soc/intel/common/block/acpi/acpi.c M src/soc/intel/common/block/acpi/acpi/globalnvs.asl A src/soc/intel/common/block/acpi/cpu_hybrid.c M src/soc/intel/common/block/include/intelblocks/acpi.h M src/soc/intel/common/block/include/intelblocks/nvs.h 7 files changed, 117 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/59359/1
diff --git a/src/soc/intel/common/block/acpi/Kconfig b/src/soc/intel/common/block/acpi/Kconfig index 07e9bea..9c21849 100644 --- a/src/soc/intel/common/block/acpi/Kconfig +++ b/src/soc/intel/common/block/acpi/Kconfig @@ -8,6 +8,9 @@ config SOC_INTEL_COMMON_BLOCK_ACPI_GPIO bool
+config SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID + bool + config SOC_INTEL_COMMON_BLOCK_ACPI_LPIT bool depends on HAVE_ACPI_TABLES diff --git a/src/soc/intel/common/block/acpi/Makefile.inc b/src/soc/intel/common/block/acpi/Makefile.inc index a6eb80d..0286d94 100644 --- a/src/soc/intel/common/block/acpi/Makefile.inc +++ b/src/soc/intel/common/block/acpi/Makefile.inc @@ -5,3 +5,4 @@ ramstage-$(CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE) += acpi_wake_source.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_PEP) += pep.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_ENABLE) += sgx.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID) += cpu_hybrid.c diff --git a/src/soc/intel/common/block/acpi/acpi.c b/src/soc/intel/common/block/acpi/acpi.c index b827c58..21d5d1e 100644 --- a/src/soc/intel/common/block/acpi/acpi.c +++ b/src/soc/intel/common/block/acpi/acpi.c @@ -21,6 +21,7 @@ #include <soc/iomap.h> #include <soc/pm.h> #include <cpu/x86/lapic.h> +#include <stdlib.h>
#define CPUID_6_EAX_ISST (1 << 7)
@@ -372,19 +373,31 @@
static void generate_cppc_entries(int core_id) { + int version = CPPC_VERSION_2; + + if (CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID)) + version = CPPC_VERSION_3; + if (!(CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPPC) && cpuid_eax(6) & CPUID_6_EAX_ISST)) return;
- /* Generate GCPC package in first logical core */ + /* Generate CPPC package & XPPC method in first logical core */ if (core_id == 0) { struct cppc_config cppc_config; - cpu_init_cppc_config(&cppc_config, CPPC_VERSION_2); + + cpu_init_cppc_config(&cppc_config, version); acpigen_write_CPPC_package(&cppc_config); + + if (CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID)) + acpi_write_xppc_method(core_id); }
/* Write _CPC entry for each logical core */ - acpigen_write_CPPC_method(); + if (CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID)) + acpigen_write_CPPC_hybrid_method(core_id); + else + acpigen_write_CPPC_method(); }
__weak void soc_power_states_generation(int core_id, diff --git a/src/soc/intel/common/block/acpi/acpi/globalnvs.asl b/src/soc/intel/common/block/acpi/acpi/globalnvs.asl index ab63a5c..001ca19 100644 --- a/src/soc/intel/common/block/acpi/acpi/globalnvs.asl +++ b/src/soc/intel/common/block/acpi/acpi/globalnvs.asl @@ -25,4 +25,9 @@ A4GB, 64, // 0x30 - 0x37 Base of above 4GB MMIO Resource A4GS, 64, // 0x38 - 0x3f Length of above 4GB MMIO Resource , 64, // 0x40 - 0x47 Hest log buffer (used in SMM, not ASL code) + SFBC, 16, // 0x48 - 0x49 Indicates Scaling factor for Big core + SFSC, 16, // 0x50 - 0x51 Indicates Scaling Factor for Small Core + NMFQ, 16, // 0x52 - 0x53 Indicates Nominal Frequency + CORE, 32, // 0x54 - 0x57 Each marked bit indicates Big Core corresponding to core index + INFS, 8, // 0x58 - Nominal Frequency is supported } diff --git a/src/soc/intel/common/block/acpi/cpu_hybrid.c b/src/soc/intel/common/block/acpi/cpu_hybrid.c new file mode 100644 index 0000000..83b9c47 --- /dev/null +++ b/src/soc/intel/common/block/acpi/cpu_hybrid.c @@ -0,0 +1,79 @@ +#include <acpi/acpigen.h> +#include <intelblocks/acpi.h> +#include <soc/cpu.h> +#include <stdlib.h> + +#define XPPC_PACKAGE_NAME "XCPC" + +void core_fill_gnvs(struct global_nvs *gnvs) +{ + uint16_t big_core_scal_factor, small_core_scal_factor; + uint8_t max_non_turbo_ratio = cpu_get_max_non_turbo_ratio(); + get_cpu_scaling_factor(&big_core_scal_factor, &small_core_scal_factor); + + /* ADL supports Nominal Frequency */ + gnvs->infs = cpu_is_nominal_freq_supported(); + gnvs->nmfq = max_non_turbo_ratio * cpu_get_bus_frequency(); + gnvs->core = get_cpu_type_bitmask(); + + /* Update big core scaling frequency */ + gnvs->sfbc = (uint16_t)(max_non_turbo_ratio * big_core_scal_factor); + + /* Update small core scaling frequency */ + gnvs->sfsc = (uint16_t)(max_non_turbo_ratio * small_core_scal_factor); +} + +void acpi_write_xppc_method(int core_id) +{ + acpigen_write_method(XPPC_PACKAGE_NAME, 1); + + /* + * If nominal frequency is supported, then set core's nominal performance to + * a scaling factor based on core_id is big or small core. + */ + + acpigen_write_if_lequal_namestr_int("INFS", 1); + acpigen_set_package_element_namestr(CPPC_PACKAGE_NAME, 22, "NMFQ"); + + /* LOCAL2_OP = (CORE >> core_id) & 1 */ + acpigen_emit_byte(SHIFT_RIGHT_OP); + acpigen_emit_namestring("CORE"); + acpigen_emit_byte(ARG0_OP); + acpigen_emit_byte(LOCAL1_OP); + acpigen_write_and(LOCAL1_OP, ONE_OP, LOCAL2_OP); + + /* + * If core id is big Core, then set big core's scaling factor + * to core's nominal frequency otherwise set small core's scaling factor. + */ + acpigen_write_if_lequal_op_int(LOCAL2_OP, 1); + acpigen_set_package_element_namestr(CPPC_PACKAGE_NAME, 3, "SFBC"); + acpigen_write_else(); + acpigen_set_package_element_namestr(CPPC_PACKAGE_NAME, 3, "SFSC"); + acpigen_pop_len(); + acpigen_pop_len(); /* if (INFS == 1) */ + + acpigen_emit_byte(RETURN_OP); + acpigen_emit_namestring(CPPC_PACKAGE_NAME); + acpigen_pop_len(); +} + +void acpigen_write_CPPC_hybrid_method(int core_id) +{ + char *pscope; + + if (core_id == 0) { + pscope = (char *) malloc(12); + snprintf(pscope, 12, XPPC_PACKAGE_NAME, 0); + } else { + pscope = (char *) malloc(16); + snprintf(pscope, 16, CONFIG_ACPI_CPU_STRING "." XPPC_PACKAGE_NAME, 0); + } + + acpigen_write_method("_CPC", 0); + acpigen_emit_byte(RETURN_OP); + acpigen_emit_namestring(pscope); + acpigen_write_dword(core_id); + acpigen_pop_len(); + free(pscope); +} diff --git a/src/soc/intel/common/block/include/intelblocks/acpi.h b/src/soc/intel/common/block/include/intelblocks/acpi.h index 2d3136e..516c66f 100644 --- a/src/soc/intel/common/block/include/intelblocks/acpi.h +++ b/src/soc/intel/common/block/include/intelblocks/acpi.h @@ -9,12 +9,20 @@ #include <soc/pm.h> #include <stdint.h>
+/* It generates ACPI code to set Nominal Frequency and Nominal Performance */ +void acpi_write_xppc_method(int core_id); + +/* It generates ACPI code to define _CPC control method */ +void acpigen_write_CPPC_hybrid_method(int core_id); + /* Forward declare the power state struct here */ struct chipset_power_state;
/* Forward declare the global nvs structure here */ struct global_nvs;
+void core_fill_gnvs(struct global_nvs *gnvs); + /* Return ACPI name for this device */ const char *soc_acpi_name(const struct device *dev);
diff --git a/src/soc/intel/common/block/include/intelblocks/nvs.h b/src/soc/intel/common/block/include/intelblocks/nvs.h index 5adbdb8..47522fd 100644 --- a/src/soc/intel/common/block/include/intelblocks/nvs.h +++ b/src/soc/intel/common/block/include/intelblocks/nvs.h @@ -27,6 +27,11 @@ u64 a4gb; /* 0x30 - 0x37 Base of above 4GB MMIO Resource */ u64 a4gs; /* 0x38 - 0x3f Length of above 4GB MMIO Resource */ u64 hest_log_addr; /* 0x40 - 47 err log addr (used in SMM, not ASL code) */ + u16 sfbc; /* Indicates the Scaling Factor for Big Core */ + u16 sfsc; /* Indicates the Scaling Factor for Small Core */ + u16 nmfq; /* Nominal Frequency */ + u32 core; /* Each marked bit indicates a Big Core corresponding to core index */ + u8 infs; /* Indicates if the processor supports nominal frequency */ };
#endif