summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/intel/model_206ax/bootblock.c62
-rw-r--r--src/cpu/intel/model_206ax/model_206ax.h5
2 files changed, 67 insertions, 0 deletions
diff --git a/src/cpu/intel/model_206ax/bootblock.c b/src/cpu/intel/model_206ax/bootblock.c
index 4061bb7b5a..dbc35914cb 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 fbd57a5c19..8259d89880 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