[coreboot] New patch to review for coreboot: 538ad1f CPU: Set flex ratio to nominal TDP ratio in bootblock

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Jul 24 01:42:29 CEST 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1329

-gerrit

commit 538ad1f6c7fcba133931d2d2673c0bf50b5f9aad
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Mon Jul 9 09:58:35 2012 -0700

    CPU: Set flex ratio to nominal TDP ratio in bootblock
    
    CPUs with configurable TDP will run the TSC at the max non-turbo
    ratio for the maximum TDP value, which can cause issues if another
    TDP is desired.  To deal with this we set the flex ratio to the
    nominal TDP ratio early in the boot and then configure the Soft
    Reset Data registers so the PCH can tell the CPU what frequency
    to run at after a reset.
    
    This is done very early in the bootblock because it is necessary
    to reset the system after setting a flex ratio.
    
    The end result is that the TSC will now increment at the max
    non-turbo frequency for the nominal TDP.
    
    On some system with 1.8GHz CPU ensure that the kernel
    detects the CPU speed as ~1800mhz rather than ~2300mhz:
    
    > dmesg | grep "MHz processor"
    [    0.004000] Detected 1795.801 MHz processor.
    
    Change-Id: I8436dced9199003b6423186a2b041e3f7b84ab8c
    Signed-off-by: Duncan Laurie <dlaurie at google.com>
---
 src/cpu/intel/model_206ax/bootblock.c   |   62 +++++++++++++++++++++++++++++++
 src/cpu/intel/model_206ax/model_206ax.h |    5 ++
 src/southbridge/intel/bd82x6x/pch.h     |    2 +
 3 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/src/cpu/intel/model_206ax/bootblock.c b/src/cpu/intel/model_206ax/bootblock.c
index 4061bb7..dbc3591 100644
--- a/src/cpu/intel/model_206ax/bootblock.c
+++ b/src/cpu/intel/model_206ax/bootblock.c
@@ -22,6 +22,8 @@
 #include <cpu/x86/cache.h>
 #include <cpu/x86/msr.h>
 #include <cpu/x86/mtrr.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
 
 #if !CONFIG_MICROCODE_IN_CBFS
 static const uint32_t microcode_updates[] = {
@@ -30,6 +32,14 @@ static const uint32_t microcode_updates[] = {
 #endif
 
 #include <cpu/intel/microcode/microcode.c>
+#include "model_206ax.h"
+
+#if CONFIG_SOUTHBRIDGE_INTEL_BD82X6X || CONFIG_SOUTHBRIDGE_INTEL_C216
+/* Needed for RCBA access to set Soft Reset Data register */
+#include <southbridge/intel/bd82x6x/pch.h>
+#else
+#error "CPU must be paired with Intel BD82X6X or C216 southbridge"
+#endif
 
 static void set_var_mtrr(
 	unsigned reg, unsigned base, unsigned size, unsigned type)
@@ -60,8 +70,60 @@ static void enable_rom_caching(void)
 	wrmsr(MTRRdefType_MSR, msr);
 }
 
+static void set_flex_ratio_to_tdp_nominal(void)
+{
+	msr_t flex_ratio, msr;
+	u32 soft_reset;
+	u8 nominal_ratio;
+
+	/* Minimum CPU revision for configurable TDP support */
+	if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
+		return;
+
+	/* Check for Flex Ratio support */
+	flex_ratio = rdmsr(MSR_FLEX_RATIO);
+	if (!(flex_ratio.lo & FLEX_RATIO_EN))
+		return;
+
+	/* Check for >0 configurable TDPs */
+	msr = rdmsr(MSR_PLATFORM_INFO);
+	if (((msr.hi >> 1) & 3) == 0)
+		return;
+
+	/* Use nominal TDP ratio for flex ratio */
+	msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+	nominal_ratio = msr.lo & 0xff;
+
+	/* See if flex ratio is already set to nominal TDP ratio */
+	if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
+		return;
+
+	/* Set flex ratio to nominal TDP ratio */
+	flex_ratio.lo &= ~0xff00;
+	flex_ratio.lo |= nominal_ratio << 8;
+	flex_ratio.lo |= FLEX_RATIO_LOCK;
+	wrmsr(MSR_FLEX_RATIO, flex_ratio);
+
+	/* Set flex ratio in soft reset data register bits 11:6.
+	 * RCBA region is enabled in southbridge bootblock */
+	soft_reset = RCBA32(SOFT_RESET_DATA);
+	soft_reset &= ~(0x3f << 6);
+	soft_reset |= (nominal_ratio & 0x3f) << 6;
+	RCBA32(SOFT_RESET_DATA) = soft_reset;
+
+	/* Set soft reset control to use register value */
+	RCBA32_OR(SOFT_RESET_CTRL, 1);
+
+	/* Issue warm reset, will be "CPU only" due to soft reset data */
+	outb(0x0, 0xcf9);
+	outb(0x6, 0xcf9);
+	asm("hlt");
+}
+
 static void bootblock_cpu_init(void)
 {
+	/* Set flex ratio and reset if needed */
+	set_flex_ratio_to_tdp_nominal();
 	enable_rom_caching();
 #if CONFIG_MICROCODE_IN_CBFS
 	intel_update_microcode_from_cbfs();
diff --git a/src/cpu/intel/model_206ax/model_206ax.h b/src/cpu/intel/model_206ax/model_206ax.h
index fbd57a5..8259d89 100644
--- a/src/cpu/intel/model_206ax/model_206ax.h
+++ b/src/cpu/intel/model_206ax/model_206ax.h
@@ -29,6 +29,9 @@
 #define  CPUID_VMX			(1 << 5)
 #define  CPUID_SMX			(1 << 6)
 #define MSR_FEATURE_CONFIG		0x13c
+#define MSR_FLEX_RATIO			0x194
+#define  FLEX_RATIO_LOCK		(1 << 20)
+#define  FLEX_RATIO_EN			(1 << 16)
 #define IA32_PLATFORM_DCA_CAP		0x1f8
 #define IA32_MISC_ENABLE		0x1a0
 #define IA32_PERF_CTL 			0x199
@@ -95,6 +98,7 @@
 #define PSS_LATENCY_TRANSITION		10
 #define PSS_LATENCY_BUSMASTER		10
 
+#ifndef __ROMCC__
 #ifdef __SMM__
 /* Lock MSRs */
 void intel_model_206ax_finalize_smm(void);
@@ -103,5 +107,6 @@ void intel_model_206ax_finalize_smm(void);
 void set_power_limits(u8 power_limit_1_time);
 int cpu_config_tdp_levels(void);
 #endif
+#endif
 
 #endif
diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h
index d6dd5f0..0a16308 100644
--- a/src/southbridge/intel/bd82x6x/pch.h
+++ b/src/southbridge/intel/bd82x6x/pch.h
@@ -368,6 +368,8 @@ int smbus_read_byte(unsigned device, unsigned address);
 #define D25IR		0x3150	/* 16bit */
 #define D22IR		0x315c	/* 16bit */
 #define OIC		0x31fe	/* 16bit */
+#define SOFT_RESET_CTRL 0x38f4
+#define SOFT_RESET_DATA 0x38f8
 
 #define DIR_ROUTE(x,a,b,c,d) \
   RCBA32(x) = (((d) << DIR_IDR) | ((c) << DIR_ICR) | \




More information about the coreboot mailing list