xref: /aosp_15_r20/external/coreboot/src/cpu/intel/model_6fx/model_6fx_init.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <cpu/cpu.h>
6 #include <cpu/x86/msr.h>
7 #include <cpu/intel/speedstep.h>
8 #include <cpu/x86/cache.h>
9 #include <cpu/x86/name.h>
10 
11 #define HIGHEST_CLEVEL		3
configure_c_states(void)12 static void configure_c_states(void)
13 {
14 	msr_t msr;
15 
16 	msr = rdmsr(MSR_PKG_CST_CONFIG_CONTROL);
17 	msr.lo |= (1 << 15); // config lock until next reset
18 	msr.lo |= (1 << 14); // Deeper Sleep
19 	msr.lo |= (1 << 10); // Enable I/O MWAIT redirection for C-States
20 	msr.lo &= ~(1 << 9); // Issue a single stop grant cycle upon stpclk
21 	msr.lo |= (1 << 3); // dynamic L2
22 
23 	/* Number of supported C-States */
24 	msr.lo &= ~7;
25 	msr.lo |= HIGHEST_CLEVEL; // support at most C3
26 
27 	wrmsr(MSR_PKG_CST_CONFIG_CONTROL, msr);
28 
29 	/* Set Processor MWAIT IO BASE (P_BLK) */
30 	msr.hi = 0;
31 	msr.lo = ((PMB0_BASE + 4) & 0xffff) | (((PMB1_BASE + 9) & 0xffff)
32 		<< 16);
33 	wrmsr(MSR_PMG_IO_BASE_ADDR, msr);
34 
35 	/* Set C_LVL controls and IO Capture Address */
36 	msr.hi = 0;
37 	// -2 because LVL0+1 aren't counted
38 	msr.lo = (PMB0_BASE + 4) | ((HIGHEST_CLEVEL - 2) << 16);
39 	wrmsr(MSR_PMG_IO_CAPTURE_ADDR, msr);
40 }
41 
42 #define IA32_PECI_CTL		0x5a0
43 
configure_misc(void)44 static void configure_misc(void)
45 {
46 	msr_t msr;
47 
48 	msr = rdmsr(IA32_MISC_ENABLE);
49 	msr.lo |= (1 << 3);	/* TM1 enable */
50 	msr.lo |= (1 << 13);	/* TM2 enable */
51 	msr.lo |= (1 << 17);	/* Bidirectional PROCHOT# */
52 
53 	msr.lo |= (1 << 10);	/* FERR# multiplexing */
54 
55 	// TODO: Only if  IA32_PLATFORM_ID[17] = 0 and IA32_PLATFORM_ID[50] = 1
56 	msr.lo |= (1 << 16);	/* Enhanced SpeedStep Enable */
57 
58 	/* Enable C2E */
59 	msr.lo |= (1 << 26);
60 
61 	/* Enable C4E */
62 	/* TODO This should only be done on mobile CPUs, see cpuid 5 */
63 	msr.hi |= (1 << (32 - 32)); // C4E
64 	msr.hi |= (1 << (33 - 32)); // Hard C4E
65 
66 	/* Enable EMTTM. */
67 	/* NOTE: We leave the EMTTM_CR_TABLE0-5 at their default values */
68 	msr.hi |= (1 << (36 - 32));
69 
70 	wrmsr(IA32_MISC_ENABLE, msr);
71 
72 	msr.lo |= (1 << 20);	/* Lock Enhanced SpeedStep Enable */
73 	wrmsr(IA32_MISC_ENABLE, msr);
74 
75 	// set maximum CPU speed
76 	msr = rdmsr(IA32_PERF_STATUS);
77 	int busratio_max = (msr.hi >> (40-32)) & 0x1f;
78 
79 	msr = rdmsr(IA32_PLATFORM_ID);
80 	int vid_max = msr.lo & 0x3f;
81 
82 	msr.lo &= ~0xffff;
83 	msr.lo |= busratio_max << 8;
84 	msr.lo |= vid_max;
85 
86 	wrmsr(IA32_PERF_CTL, msr);
87 
88 	/* Enable PECI */
89 	msr = rdmsr(IA32_PECI_CTL);
90 	msr.lo |= 1;
91 	wrmsr(IA32_PECI_CTL, msr);
92 }
93 
94 #define PIC_SENS_CFG	0x1aa
configure_pic_thermal_sensors(void)95 static void configure_pic_thermal_sensors(void)
96 {
97 	msr_t msr;
98 
99 	msr = rdmsr(PIC_SENS_CFG);
100 
101 	msr.lo |= (1 << 21); // inter-core lock TM1
102 	msr.lo |= (1 << 4); // Enable bypass filter
103 
104 	wrmsr(PIC_SENS_CFG, msr);
105 }
106 
model_6fx_init(struct device * cpu)107 static void model_6fx_init(struct device *cpu)
108 {
109 	char processor_name[49];
110 
111 	/* Turn on caching if we haven't already */
112 	enable_cache();
113 
114 	/* Print processor name */
115 	fill_processor_name(processor_name);
116 	printk(BIOS_INFO, "CPU: %s.\n", processor_name);
117 
118 	/* Setup Page Attribute Tables (PAT) */
119 	// TODO set up PAT
120 
121 	/* Configure C States */
122 	configure_c_states();
123 
124 	/* Configure Enhanced SpeedStep and Thermal Sensors */
125 	configure_misc();
126 
127 	/* PIC thermal sensor control */
128 	configure_pic_thermal_sensors();
129 }
130 
131 static struct device_operations cpu_dev_ops = {
132 	.init     = model_6fx_init,
133 };
134 
135 static const struct cpu_device_id cpu_table[] = {
136 	{ X86_VENDOR_INTEL, 0x06f0, CPUID_EXACT_MATCH_MASK }, /* Intel Core 2 Solo/Core Duo */
137 	{ X86_VENDOR_INTEL, 0x06f2, CPUID_EXACT_MATCH_MASK }, /* Intel Core 2 Solo/Core Duo */
138 	{ X86_VENDOR_INTEL, 0x06f6, CPUID_EXACT_MATCH_MASK }, /* Intel Core 2 Solo/Core Duo */
139 	{ X86_VENDOR_INTEL, 0x06f7, CPUID_EXACT_MATCH_MASK }, /* Intel Core 2 Solo/Core Duo */
140 	{ X86_VENDOR_INTEL, 0x06fa, CPUID_EXACT_MATCH_MASK }, /* Intel Core 2 Solo/Core Duo */
141 	{ X86_VENDOR_INTEL, 0x06fb, CPUID_EXACT_MATCH_MASK }, /* Intel Core 2 Solo/Core Duo */
142 	{ X86_VENDOR_INTEL, 0x06fd, CPUID_EXACT_MATCH_MASK }, /* Intel Core 2 Solo/Core Duo */
143 	/* Intel Core 2 Celeron Conroe-L */
144 	{ X86_VENDOR_INTEL, 0x10661, CPUID_EXACT_MATCH_MASK },
145 	CPU_TABLE_END
146 };
147 
148 static const struct cpu_driver driver __cpu_driver = {
149 	.ops      = &cpu_dev_ops,
150 	.id_table = cpu_table,
151 };
152