x86: Add common functions for TDP and perf control
authorSimon Glass <sjg@chromium.org>
Wed, 25 Sep 2019 14:56:38 +0000 (08:56 -0600)
committerBin Meng <bmeng.cn@gmail.com>
Tue, 8 Oct 2019 05:57:47 +0000 (13:57 +0800)
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>
arch/x86/cpu/broadwell/cpu.c
arch/x86/cpu/broadwell/cpu_full.c
arch/x86/cpu/intel_common/cpu.c
arch/x86/cpu/ivybridge/model_206ax.c
arch/x86/cpu/ivybridge/northbridge.c
arch/x86/include/asm/arch-ivybridge/model_206ax.h
arch/x86/include/asm/cpu_common.h

index 586a2e8f05a1ff9e98559acadc59b6ee39def541..55a7439f1c103b0dacda17b27437c65c5ffd62cf 100644 (file)
@@ -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;
index 58cc2f362ccbc7dcc665f7842eb47fc439742695..169b5b02a6ac764ff4abba3e44691cdbdb139965 100644 (file)
@@ -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;
index 7d0ed73b4b6bf933fa66bb082a7e20f0b1cc0a4e..1898903853fec0198a6c78671a72863771bcdd48 100644 (file)
@@ -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;
+}
index 3177ba3297fb419ea2f1286f12160861d80086e4..56ab6bf4acf5c7db82c94cb03d69aacd4aabd509 100644 (file)
@@ -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)
index a809b823b3bcf8997756527c09834d32b5c4be2b..0f427afcb826b8be6e04c10929899df7ccb1b98d 100644 (file)
@@ -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));
index 10caaa242263af2f899c4d21058b1f547e4e2b33..4839ebc3124413805f6b0076c11ab00a1db04fd1 100644 (file)
@@ -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
index f42eb323089994156494f0a99b25bf5ae2e1e33f..c61d74e4a006306a05e9c8872c9c989864832be7 100644 (file)
@@ -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