mb/google/rauru: Implement regulator interface
[coreboot.git] / src / cpu / intel / model_2065x / model_2065x_init.c
blobcb748543468362e05e98a197f6fd6c86ce1bccda
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <assert.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <cpu/cpu.h>
7 #include <cpu/x86/mtrr.h>
8 #include <cpu/x86/msr.h>
9 #include <cpu/x86/lapic.h>
10 #include <cpu/x86/mp.h>
11 #include <cpu/intel/microcode.h>
12 #include <cpu/intel/speedstep.h>
13 #include <cpu/intel/turbo.h>
14 #include <cpu/x86/cache.h>
15 #include <cpu/x86/name.h>
16 #include "model_2065x.h"
17 #include "chip.h"
18 #include <cpu/intel/smm_reloc.h>
19 #include <cpu/intel/common/common.h>
20 #include <smp/node.h>
21 #include <types.h>
23 static void configure_thermal_target(struct device *dev)
25 struct cpu_intel_model_2065x_config *conf = dev->upstream->dev->chip_info;
26 msr_t msr;
28 /* Set TCC activation offset if supported */
29 msr = rdmsr(MSR_PLATFORM_INFO);
30 if ((msr.lo & (1 << 30)) && conf->tcc_offset) {
31 msr = rdmsr(MSR_TEMPERATURE_TARGET);
32 msr.lo &= ~(0xf << 24); /* Bits 27:24 */
33 msr.lo |= (conf->tcc_offset & 0xf) << 24;
34 wrmsr(MSR_TEMPERATURE_TARGET, msr);
38 static void configure_misc(void)
40 msr_t msr;
42 msr = rdmsr(IA32_MISC_ENABLE);
43 msr.lo |= (1 << 0); /* Fast String enable */
44 msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
45 msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
46 wrmsr(IA32_MISC_ENABLE, msr);
48 /* Disable Thermal interrupts */
49 msr.lo = 0;
50 msr.hi = 0;
51 wrmsr(IA32_THERM_INTERRUPT, msr);
54 static void set_max_ratio(void)
56 msr_t msr, perf_ctl;
58 perf_ctl.hi = 0;
60 /* Platform Info bits 15:8 give max ratio */
61 msr = rdmsr(MSR_PLATFORM_INFO);
62 perf_ctl.lo = msr.lo & 0xff00;
63 wrmsr(IA32_PERF_CTL, perf_ctl);
65 printk(BIOS_DEBUG, "model_x065x: frequency set to %d\n",
66 ((perf_ctl.lo >> 8) & 0xff) * IRONLAKE_BCLK);
69 static void model_2065x_init(struct device *cpu)
71 char processor_name[49];
73 /* Clear out pending MCEs */
74 /* This should only be done on a cold boot */
75 mca_clear_status();
77 /* Print processor name */
78 fill_processor_name(processor_name);
79 printk(BIOS_INFO, "CPU: %s.\n", processor_name);
80 printk(BIOS_INFO, "CPU:lapic=%d, boot_cpu=%d\n", lapicid(),
81 boot_cpu());
83 /* Setup Page Attribute Tables (PAT) */
84 // TODO set up PAT
86 enable_lapic_tpr();
88 /* Set virtualization based on Kconfig option */
89 set_vmx_and_lock();
91 set_aesni_lock();
93 /* Configure Enhanced SpeedStep and Thermal Sensors */
94 configure_misc();
96 /* Thermal throttle activation offset */
97 configure_thermal_target(cpu);
99 /* Set Max Ratio */
100 set_max_ratio();
102 /* Enable Turbo */
103 enable_turbo();
106 /* MP initialization support. */
107 static void pre_mp_init(void)
109 /* Setup MTRRs based on physical address size. */
110 x86_setup_mtrrs_with_detect();
111 x86_mtrr_check();
114 static int get_cpu_count(void)
116 msr_t msr;
117 unsigned int num_threads;
118 unsigned int num_cores;
120 msr = rdmsr(MSR_CORE_THREAD_COUNT);
121 num_threads = (msr.lo >> 0) & 0xffff;
122 num_cores = (msr.lo >> 16) & 0xffff;
123 printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
124 num_cores, num_threads);
126 return num_threads;
129 static void get_microcode_info(const void **microcode, int *parallel)
131 *microcode = intel_microcode_find();
132 *parallel = !intel_ht_supported();
135 static void per_cpu_smm_trigger(void)
137 /* Relocate the SMM handler. */
138 smm_relocate();
140 /* After SMM relocation a 2nd microcode load is required. */
141 const void *microcode_patch = intel_microcode_find();
142 intel_microcode_load_unlocked(microcode_patch);
145 static void post_mp_init(void)
147 /* Now that all APs have been relocated as well as the BSP let SMIs
148 * start flowing. */
149 global_smi_enable();
151 /* Lock down the SMRAM space. */
152 smm_lock();
155 static const struct mp_ops mp_ops = {
156 .pre_mp_init = pre_mp_init,
157 .get_cpu_count = get_cpu_count,
158 .get_smm_info = smm_info,
159 .get_microcode_info = get_microcode_info,
160 .pre_mp_smm_init = smm_initialize,
161 .per_cpu_smm_trigger = per_cpu_smm_trigger,
162 .relocation_handler = smm_relocation_handler,
163 .post_mp_init = post_mp_init,
166 void mp_init_cpus(struct bus *cpu_bus)
168 /* TODO: Handle mp_init_with_smm failure? */
169 mp_init_with_smm(cpu_bus, &mp_ops);
172 static struct device_operations cpu_dev_ops = {
173 .init = model_2065x_init,
176 /* Arrandale / Clarkdale CPU IDs */
177 static const struct cpu_device_id cpu_table[] = {
178 { X86_VENDOR_INTEL, 0x20650, CPUID_EXACT_MATCH_MASK },
179 { X86_VENDOR_INTEL, 0x20651, CPUID_EXACT_MATCH_MASK },
180 { X86_VENDOR_INTEL, 0x20652, CPUID_EXACT_MATCH_MASK },
181 { X86_VENDOR_INTEL, 0x20654, CPUID_EXACT_MATCH_MASK },
182 { X86_VENDOR_INTEL, 0x20655, CPUID_EXACT_MATCH_MASK },
183 CPU_TABLE_END
186 static const struct cpu_driver driver __cpu_driver = {
187 .ops = &cpu_dev_ops,
188 .id_table = cpu_table,