soc/intel/common: Implement ACPI CPPCv3 package to support hybrid core
The patch implements ACPI CPPCv3 package. It implements and updates the following methods: generate_cppc_entries(): Updates method to support CPPCv3 package acpi_get_cpu_nominal_freq(): Calculates CPU's nominal frequency acpi_get_cpu_nomi_perf(): Calculates nominal performance for big and small cores. acpigen_write_CPPC_hybrid_method(): It generates ACPI code to implement _CPC method. acpigen_cppc_update_nominal_freq_perf(): It updates CPPC3 package if cpu supports Nominal Frequency. It generates ACPI code which sets Nominal Frequency and updates 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 Performance based on the CPU's scaling factor. TEST=Verified CPPCv3 package is getting created in the SSDT table. Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com> Signed-off-by: ravindr1 <ravindra@intel.com> Change-Id: Icd5ea9e70bebd1e66d3cea2bcf8a6678e5cc95ca Reviewed-on: https://review.coreboot.org/c/coreboot/+/59359 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: Rizwan Qureshi <rizwan.qureshi@intel.com>
This commit is contained in:
parent
49f0f9a422
commit
117361278f
|
@ -372,6 +372,11 @@ void generate_t_state_entries(int core, int cores_per_package)
|
||||||
|
|
||||||
static void generate_cppc_entries(int core_id)
|
static void generate_cppc_entries(int core_id)
|
||||||
{
|
{
|
||||||
|
u32 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) &&
|
if (!(CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPPC) &&
|
||||||
cpuid_eax(6) & CPUID_6_EAX_ISST))
|
cpuid_eax(6) & CPUID_6_EAX_ISST))
|
||||||
return;
|
return;
|
||||||
|
@ -379,12 +384,15 @@ static void generate_cppc_entries(int core_id)
|
||||||
/* Generate GCPC package in first logical core */
|
/* Generate GCPC package in first logical core */
|
||||||
if (core_id == 0) {
|
if (core_id == 0) {
|
||||||
struct cppc_config cppc_config;
|
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);
|
acpigen_write_CPPC_package(&cppc_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write _CPC entry for each logical core */
|
/* 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,
|
__weak void soc_power_states_generation(int core_id,
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include <cpu/x86/lapic.h>
|
#include <cpu/x86/lapic.h>
|
||||||
#include <cpu/x86/mp.h>
|
#include <cpu/x86/mp.h>
|
||||||
|
|
||||||
|
#define CPPC_NOM_FREQ_IDX 22
|
||||||
|
#define CPPC_NOM_PERF_IDX 3
|
||||||
|
|
||||||
DECLARE_SPIN_LOCK(cpu_lock);
|
DECLARE_SPIN_LOCK(cpu_lock);
|
||||||
static u8 global_cpu_type[CONFIG_MAX_CPUS];
|
static u8 global_cpu_type[CONFIG_MAX_CPUS];
|
||||||
|
|
||||||
|
@ -56,4 +59,61 @@ static void run_set_cpu_type(void *unused)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void acpi_get_cpu_nomi_perf(u16 *small_core_nom_perf, u16 *big_core_nom_perf)
|
||||||
|
{
|
||||||
|
u16 big_core_scal_factor, small_core_scal_factor;
|
||||||
|
u8 max_non_turbo_ratio = cpu_get_max_non_turbo_ratio();
|
||||||
|
|
||||||
|
soc_get_scaling_factor(&big_core_scal_factor, &small_core_scal_factor);
|
||||||
|
|
||||||
|
*big_core_nom_perf = (u16)((max_non_turbo_ratio * big_core_scal_factor) / 100);
|
||||||
|
|
||||||
|
*small_core_nom_perf = (u16)((max_non_turbo_ratio * small_core_scal_factor) / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 acpi_get_cpu_nominal_freq(void)
|
||||||
|
{
|
||||||
|
return cpu_get_max_non_turbo_ratio() * cpu_get_bus_frequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Updates Nominal Frequency and Nominal Performance */
|
||||||
|
static void acpigen_cppc_update_nominal_freq_perf(const char *pkg_path, s32 core_id)
|
||||||
|
{
|
||||||
|
u16 small_core_nom_perf, big_core_nom_perf;
|
||||||
|
|
||||||
|
if (!soc_is_nominal_freq_supported())
|
||||||
|
return;
|
||||||
|
|
||||||
|
acpi_get_cpu_nomi_perf(&small_core_nom_perf, &big_core_nom_perf);
|
||||||
|
|
||||||
|
if (global_cpu_type[core_id])
|
||||||
|
acpigen_set_package_element_int(pkg_path, CPPC_NOM_PERF_IDX, big_core_nom_perf);
|
||||||
|
else
|
||||||
|
acpigen_set_package_element_int(pkg_path, CPPC_NOM_PERF_IDX,
|
||||||
|
small_core_nom_perf);
|
||||||
|
|
||||||
|
/* Update CPU's nominal frequency */
|
||||||
|
acpigen_set_package_element_int(pkg_path, CPPC_NOM_FREQ_IDX,
|
||||||
|
acpi_get_cpu_nominal_freq());
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_CPPC_hybrid_method(s32 core_id)
|
||||||
|
{
|
||||||
|
char pkg_path[16];
|
||||||
|
|
||||||
|
if (core_id == 0)
|
||||||
|
snprintf(pkg_path, sizeof(pkg_path), CPPC_PACKAGE_NAME, 0);
|
||||||
|
else
|
||||||
|
snprintf(pkg_path, sizeof(pkg_path),
|
||||||
|
CONFIG_ACPI_CPU_STRING "." CPPC_PACKAGE_NAME, 0);
|
||||||
|
|
||||||
|
acpigen_write_method("_CPC", 0);
|
||||||
|
|
||||||
|
/* Update nominal performance and nominal frequency */
|
||||||
|
acpigen_cppc_update_nominal_freq_perf(pkg_path, core_id);
|
||||||
|
acpigen_emit_byte(RETURN_OP);
|
||||||
|
acpigen_emit_namestring(pkg_path);
|
||||||
|
acpigen_pop_len();
|
||||||
|
}
|
||||||
|
|
||||||
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, run_set_cpu_type, NULL);
|
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, run_set_cpu_type, NULL);
|
||||||
|
|
|
@ -18,6 +18,12 @@ enum core_type {
|
||||||
CPUID_UNKNOWN = 0xff,
|
CPUID_UNKNOWN = 0xff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Gets the scaling factor for small and big core */
|
||||||
|
void soc_get_scaling_factor(u16 *big_core_scal_factor, u16 *small_core_scal_factor);
|
||||||
|
|
||||||
|
/* Generates ACPI code to define _CPC control method */
|
||||||
|
void acpigen_write_CPPC_hybrid_method(int core_id);
|
||||||
|
|
||||||
/* Forward declare the power state struct here */
|
/* Forward declare the power state struct here */
|
||||||
struct chipset_power_state;
|
struct chipset_power_state;
|
||||||
|
|
||||||
|
@ -125,4 +131,6 @@ void sgx_fill_ssdt(void);
|
||||||
*/
|
*/
|
||||||
enum core_type get_soc_cpu_type(void);
|
enum core_type get_soc_cpu_type(void);
|
||||||
|
|
||||||
|
/* Check if CPU supports Nominal frequency or not */
|
||||||
|
bool soc_is_nominal_freq_supported(void);
|
||||||
#endif /* _SOC_INTEL_COMMON_BLOCK_ACPI_H_ */
|
#endif /* _SOC_INTEL_COMMON_BLOCK_ACPI_H_ */
|
||||||
|
|
Loading…
Reference in New Issue