diff options
author | Matt Delco <delco@chromium.org> | 2018-08-13 13:49:02 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2018-08-20 15:53:28 +0000 |
commit | 9557a34abeb8c2101a853f49e20a3671c4551aef (patch) | |
tree | 06a5a30e7e49d4be6aa317b127c485c2e743e579 | |
parent | afa07f7ae48d9e9d79aef712933777a56551f5be (diff) |
cpu/intel/common: add function to init cppc_config
This change adds a method to init a cppc_config structure in a way that
should ideally work across Intel processors that support EIST.
Change-Id: Ib767df63d796bd1f21e36bcf575cf912e09090a1
Signed-off-by: Matt Delco <delco@chromium.org>
Reviewed-on: https://review.coreboot.org/28068
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r-- | src/cpu/intel/common/common.h | 8 | ||||
-rw-r--r-- | src/cpu/intel/common/common_init.c | 180 |
2 files changed, 188 insertions, 0 deletions
diff --git a/src/cpu/intel/common/common.h b/src/cpu/intel/common/common.h index 0d0b954886..81c9f16d19 100644 --- a/src/cpu/intel/common/common.h +++ b/src/cpu/intel/common/common.h @@ -17,4 +17,12 @@ void set_vmx(void); +/* + * Init CPPC block with MSRs for Intel Enhanced Speed Step Technology. + * Version 2 is suggested--this function's implementation of version 3 + * may have room for improvment. + */ +struct cppc_config; +void cpu_init_cppc_config(struct cppc_config *config, u32 version); + #endif diff --git a/src/cpu/intel/common/common_init.c b/src/cpu/intel/common/common_init.c index 44a316b641..8dd8559d23 100644 --- a/src/cpu/intel/common/common_init.c +++ b/src/cpu/intel/common/common_init.c @@ -15,6 +15,7 @@ * GNU General Public License for more details. */ +#include <arch/acpigen.h> #include <console/console.h> #include <cpu/x86/msr.h> #include "common.h" @@ -71,3 +72,182 @@ void set_vmx(void) enable ? "enabled" : "disabled", lock ? "locked" : "unlocked"); } + +/* + * Init cppc_config in a way that's appropriate for Intel + * processors with Intel Enhanced Speed Step Technology. + * NOTE: version 2 is expected to be the typical use case. + * For now this function 'punts' on version 3 and just + * populates the additional fields with 'unsupported'. + */ +void cpu_init_cppc_config(struct cppc_config *config, u32 version) +{ + acpi_addr_t msr = { + .space_id = ACPI_ADDRESS_SPACE_FIXED, + .bit_width = 8, + .bit_offset = 0, + { + .access_size = 4 + }, + .addrl = 0, + .addrh = 0, + }; + static const acpi_addr_t unsupported = { + .space_id = ACPI_ADDRESS_SPACE_MEMORY, + .bit_width = 0, + .bit_offset = 0, + { + .resv = 0 + }, + .addrl = 0, + .addrh = 0, + }; + + config->version = version; + + msr.addrl = MSR_IA32_HWP_CAPABILITIES; + + /* + * Highest Performance: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x00, 0x771, 0x04,)}, + */ + config->regs[CPPC_HIGHEST_PERF] = msr; + + /* + * Nominal Performance -> Guaranteed Performance: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x771, 0x04,)}, + */ + msr.bit_offset = 8; + config->regs[CPPC_NOMINAL_PERF] = msr; + + /* + * Lowest Nonlinear Performance -> Most Efficient Performance: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x10, 0x771, 0x04,)}, + */ + msr.bit_offset = 16; + config->regs[CPPC_LOWEST_NONL_PERF] = msr; + + /* + * Lowest Performance: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x18, 0x771, 0x04,)}, + */ + msr.bit_offset = 24; + config->regs[CPPC_LOWEST_PERF] = msr; + + /* + * Guaranteed Performance Register: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x771, 0x04,)}, + */ + msr.bit_offset = 8; + config->regs[CPPC_GUARANTEED_PERF] = msr; + + msr.addrl = MSR_IA32_HWP_REQUEST; + + /* + * Desired Performance Register: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x10, 0x774, 0x04,)}, + */ + msr.bit_offset = 16; + config->regs[CPPC_DESIRED_PERF] = msr; + + /* + * Minimum Performance Register: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x00, 0x774, 0x04,)}, + */ + msr.bit_offset = 0; + config->regs[CPPC_MIN_PERF] = msr; + + /* + * Maximum Performance Register: + * ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x774, 0x04,)}, + */ + msr.bit_offset = 8; + config->regs[CPPC_MAX_PERF] = msr; + + /* + * Performance Reduction Tolerance Register: + * ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)}, + */ + config->regs[CPPC_PERF_REDUCE_TOLERANCE] = unsupported; + + /* + * Time Window Register: + * ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)}, + */ + config->regs[CPPC_TIME_WINDOW] = unsupported; + + /* + * Counter Wraparound Time: + * ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)}, + */ + config->regs[CPPC_COUNTER_WRAP] = unsupported; + + msr.addrl = MSR_IA32_MPERF; + + /* + * Reference Performance Counter Register: + * ResourceTemplate(){Register(FFixedHW, 0x40, 0x00, 0x0E7, 0x04,)}, + */ + msr.bit_width = 64; + msr.bit_offset = 0; + config->regs[CPPC_REF_PERF_COUNTER] = msr; + + msr.addrl = MSR_IA32_APERF; + + /* + * Delivered Performance Counter Register: + * ResourceTemplate(){Register(FFixedHW, 0x40, 0x00, 0x0E8, 0x04,)}, + */ + config->regs[CPPC_DELIVERED_PERF_COUNTER] = msr; + + msr.addrl = MSR_IA32_HWP_STATUS; + + /* + * Performance Limited Register: + * ResourceTemplate(){Register(FFixedHW, 0x01, 0x02, 0x777, 0x04,)}, + */ + msr.bit_width = 1; + msr.bit_offset = 2; + config->regs[CPPC_PERF_LIMITED] = msr; + + msr.addrl = MSR_IA32_PM_ENABLE; + + /* + * CPPC Enable Register: + * ResourceTemplate(){Register(FFixedHW, 0x01, 0x00, 0x770, 0x04,)}, + */ + msr.bit_offset = 0; + config->regs[CPPC_ENABLE] = msr; + + if (version >= 2) { + /* Autonomous Selection Enable is populated below */ + + /* Autonomous Activity Window Register */ + config->regs[CPPC_AUTO_ACTIVITY_WINDOW] = unsupported; + + /* Energy Performance Preference Register */ + config->regs[CPPC_PERF_PREF] = unsupported; + + /* Reference Performance */ + config->regs[CPPC_REF_PERF] = unsupported; + + if (version >= 3) { + /* Lowest Frequency */ + config->regs[CPPC_LOWEST_FREQ] = unsupported; + /* Nominal Frequency */ + config->regs[CPPC_NOMINAL_FREQ] = unsupported; + } + + /* + * Autonomous Selection Enable = 1 + * This field is actually the first addition in version 2 but + * it's so unlike the others I'm populating it last. + */ + msr.space_id = ACPI_ADDRESS_SPACE_MEMORY; + msr.bit_width = 32; + msr.bit_offset = 0; + msr.access_size = 0; + msr.addrl = 1; + config->regs[CPPC_AUTO_SELECT] = msr; + } +} |