mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 08:01:08 +00:00
x86: Add common functions for TDP and perf control
These functions are the same on modern Intel CPUs, so use common code to set them. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> [bmeng: return false instead of 0 in cpu_ivybridge_config_tdp_levels(); fix 'muiltiplier' and 'desgn' typos] Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
parent
55a6b13a75
commit
2f0c2f03e7
7 changed files with 52 additions and 33 deletions
|
@ -41,12 +41,9 @@ int arch_cpu_init_dm(void)
|
|||
|
||||
void set_max_freq(void)
|
||||
{
|
||||
msr_t msr, perf_ctl, platform_info;
|
||||
msr_t msr, perf_ctl;
|
||||
|
||||
/* Check for configurable TDP option */
|
||||
platform_info = msr_read(MSR_PLATFORM_INFO);
|
||||
|
||||
if ((platform_info.hi >> 1) & 3) {
|
||||
if (cpu_config_tdp_levels()) {
|
||||
/* Set to nominal TDP ratio */
|
||||
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
|
||||
perf_ctl.lo = (msr.lo & 0xff) << 8;
|
||||
|
|
|
@ -329,15 +329,6 @@ static int bsp_init_before_ap_bringup(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_config_tdp_levels(void)
|
||||
{
|
||||
msr_t platform_info;
|
||||
|
||||
/* Bits 34:33 indicate how many levels supported */
|
||||
platform_info = msr_read(MSR_PLATFORM_INFO);
|
||||
return (platform_info.hi >> 1) & 3;
|
||||
}
|
||||
|
||||
static void set_max_ratio(void)
|
||||
{
|
||||
msr_t msr, perf_ctl;
|
||||
|
|
|
@ -145,3 +145,23 @@ int cpu_configure_thermal_target(struct udevice *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cpu_set_perf_control(uint clk_ratio)
|
||||
{
|
||||
msr_t perf_ctl;
|
||||
|
||||
perf_ctl.lo = (clk_ratio & 0xff) << 8;
|
||||
perf_ctl.hi = 0;
|
||||
msr_write(MSR_IA32_PERF_CTL, perf_ctl);
|
||||
debug("CPU: frequency set to %d MHz\n", clk_ratio * INTEL_BCLK_MHZ);
|
||||
}
|
||||
|
||||
bool cpu_config_tdp_levels(void)
|
||||
{
|
||||
msr_t platform_info;
|
||||
|
||||
/* Bits 34:33 indicate how many levels supported */
|
||||
platform_info = msr_read(MSR_PLATFORM_INFO);
|
||||
|
||||
return ((platform_info.hi >> 1) & 3) != 0;
|
||||
}
|
||||
|
|
|
@ -140,19 +140,16 @@ static const u8 power_limit_time_msr_to_sec[] = {
|
|||
[0x11] = 128,
|
||||
};
|
||||
|
||||
int cpu_config_tdp_levels(void)
|
||||
bool cpu_ivybridge_config_tdp_levels(void)
|
||||
{
|
||||
struct cpuid_result result;
|
||||
msr_t platform_info;
|
||||
|
||||
/* Minimum CPU revision */
|
||||
result = cpuid(1);
|
||||
if (result.eax < IVB_CONFIG_TDP_MIN_CPUID)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
/* Bits 34:33 indicate how many levels supported */
|
||||
platform_info = msr_read(MSR_PLATFORM_INFO);
|
||||
return (platform_info.hi >> 1) & 3;
|
||||
return cpu_config_tdp_levels();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -213,7 +210,7 @@ void set_power_limits(u8 power_limit_1_time)
|
|||
msr_write(MSR_PKG_POWER_LIMIT, limit);
|
||||
|
||||
/* Use nominal TDP values for CPUs with configurable TDP */
|
||||
if (cpu_config_tdp_levels()) {
|
||||
if (cpu_ivybridge_config_tdp_levels()) {
|
||||
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
|
||||
limit.hi = 0;
|
||||
limit.lo = msr.lo & 0xff;
|
||||
|
@ -329,24 +326,20 @@ static void configure_dca_cap(void)
|
|||
|
||||
static void set_max_ratio(void)
|
||||
{
|
||||
msr_t msr, perf_ctl;
|
||||
|
||||
perf_ctl.hi = 0;
|
||||
msr_t msr;
|
||||
uint ratio;
|
||||
|
||||
/* Check for configurable TDP option */
|
||||
if (cpu_config_tdp_levels()) {
|
||||
if (cpu_ivybridge_config_tdp_levels()) {
|
||||
/* Set to nominal TDP ratio */
|
||||
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
|
||||
perf_ctl.lo = (msr.lo & 0xff) << 8;
|
||||
ratio = msr.lo & 0xff;
|
||||
} else {
|
||||
/* Platform Info bits 15:8 give max ratio */
|
||||
msr = msr_read(MSR_PLATFORM_INFO);
|
||||
perf_ctl.lo = msr.lo & 0xff00;
|
||||
ratio = (msr.lo & 0xff00) >> 8;
|
||||
}
|
||||
msr_write(MSR_IA32_PERF_CTL, perf_ctl);
|
||||
|
||||
debug("model_x06ax: frequency set to %d\n",
|
||||
((perf_ctl.lo >> 8) & 0xff) * INTEL_BCLK_MHZ);
|
||||
cpu_set_perf_control(ratio);
|
||||
}
|
||||
|
||||
static void set_energy_perf_bias(u8 policy)
|
||||
|
|
|
@ -141,7 +141,7 @@ static void northbridge_init(struct udevice *dev, int rev)
|
|||
* CPUs with configurable TDP also need power limits set
|
||||
* in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT.
|
||||
*/
|
||||
if (cpu_config_tdp_levels()) {
|
||||
if (cpu_ivybridge_config_tdp_levels()) {
|
||||
msr_t msr = msr_read(MSR_PKG_POWER_LIMIT);
|
||||
|
||||
writel(msr.lo, MCHBAR_REG(0x59A0));
|
||||
|
|
|
@ -58,6 +58,6 @@
|
|||
|
||||
/* Configure power limits for turbo mode */
|
||||
void set_power_limits(u8 power_limit_1_time);
|
||||
int cpu_config_tdp_levels(void);
|
||||
bool cpu_ivybridge_config_tdp_levels(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Common code for Intel CPUs
|
||||
*
|
||||
* Copyright (c) 2016 Google, Inc
|
||||
*/
|
||||
|
||||
|
@ -61,4 +63,20 @@ int cpu_intel_get_info(struct cpu_info *info, int bclk_mz);
|
|||
*/
|
||||
int cpu_configure_thermal_target(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* cpu_set_perf_control() - Set the nominal CPU clock speed
|
||||
*
|
||||
* This sets the clock speed as a multiplier of BCLK
|
||||
*
|
||||
* @clk_ratio: Ratio to use
|
||||
*/
|
||||
void cpu_set_perf_control(uint clk_ratio);
|
||||
|
||||
/**
|
||||
* cpu_config_tdp_levels() - Check for configurable TDP option
|
||||
*
|
||||
* @return true if the CPU has configurable TDP (Thermal-design power)
|
||||
*/
|
||||
bool cpu_config_tdp_levels(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue