• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/bootblock.h>
4 #include <arch/io.h>
5 #include <cpu/cpu.h>
6 #include <cpu/x86/msr.h>
7 #include <halt.h>
8 #include <stdint.h>
9 
10 #include "model_206ax.h"
11 
12 #if CONFIG(SOUTHBRIDGE_INTEL_BD82X6X) || \
13 	CONFIG(SOUTHBRIDGE_INTEL_C216)
14 /* Needed for RCBA access to set Soft Reset Data register */
15 #include <southbridge/intel/bd82x6x/pch.h>
16 #else
17 #error "CPU must be paired with Intel BD82X6X or C216 southbridge"
18 #endif
19 
set_flex_ratio_to_tdp_nominal(void)20 static void set_flex_ratio_to_tdp_nominal(void)
21 {
22 	msr_t flex_ratio, msr;
23 	u32 soft_reset;
24 	u8 nominal_ratio;
25 
26 	/* Minimum CPU revision for configurable TDP support */
27 	if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
28 		return;
29 
30 	/* Check for Flex Ratio support */
31 	flex_ratio = rdmsr(MSR_FLEX_RATIO);
32 	if (!(flex_ratio.lo & FLEX_RATIO_EN))
33 		return;
34 
35 	/* Check for >0 configurable TDPs */
36 	msr = rdmsr(MSR_PLATFORM_INFO);
37 	if (((msr.hi >> 1) & 3) == 0)
38 		return;
39 
40 	/* Use nominal TDP ratio for flex ratio */
41 	msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
42 	nominal_ratio = msr.lo & 0xff;
43 
44 	/* See if flex ratio is already set to nominal TDP ratio */
45 	if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
46 		return;
47 
48 	/* Set flex ratio to nominal TDP ratio */
49 	flex_ratio.lo &= ~0xff00;
50 	flex_ratio.lo |= nominal_ratio << 8;
51 	flex_ratio.lo |= FLEX_RATIO_LOCK;
52 	wrmsr(MSR_FLEX_RATIO, flex_ratio);
53 
54 	/* Set flex ratio in soft reset data register bits 11:6.
55 	 * RCBA region is enabled in southbridge bootblock */
56 	soft_reset = RCBA32(SOFT_RESET_DATA);
57 	soft_reset &= ~(0x3f << 6);
58 	soft_reset |= (nominal_ratio & 0x3f) << 6;
59 	RCBA32(SOFT_RESET_DATA) = soft_reset;
60 
61 	/* Set soft reset control to use register value */
62 	RCBA32_OR(SOFT_RESET_CTRL, 1);
63 
64 	/* Issue warm reset, will be "CPU only" due to soft reset data */
65 	outb(0x0, 0xcf9);
66 	outb(0x6, 0xcf9);
67 	halt();
68 }
69 
bootblock_early_cpu_init(void)70 void bootblock_early_cpu_init(void)
71 {
72 	/* Set flex ratio and reset if needed */
73 	set_flex_ratio_to_tdp_nominal();
74 }
75