blob: 66db16b6ed1d001ad77aa03446e92664a8df9f27 [file] [log] [blame]
Subrata Banik2871e0e2020-09-27 11:30:58 +05301/* SPDX-License-Identifier: GPL-2.0-only */
2
3/*
4 * This file is created based on Intel Alder Lake Processor CPU Datasheet
5 * Document number: 619501
6 * Chapter number: 14
7 */
8
Subrata Banik2871e0e2020-09-27 11:30:58 +05309#include <console/console.h>
10#include <device/pci.h>
Tim Wawrzynczak6cf79d92021-07-30 10:37:55 -060011#include <device/pci_ids.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053012#include <cpu/x86/mp.h>
13#include <cpu/x86/msr.h>
14#include <cpu/intel/smm_reloc.h>
15#include <cpu/intel/turbo.h>
Michael Niewöhner10ae1cf2020-10-11 14:05:32 +020016#include <cpu/intel/common/common.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053017#include <fsp/api.h>
18#include <intelblocks/cpulib.h>
19#include <intelblocks/mp_init.h>
20#include <intelblocks/msr.h>
Sridhar Siricilla23e2cde2022-01-14 19:20:15 +053021#include <intelblocks/acpi.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053022#include <soc/cpu.h>
23#include <soc/msr.h>
24#include <soc/pci_devs.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053025#include <soc/soc_chip.h>
Felix Heldd27ef5b2021-10-20 20:18:12 +020026#include <types.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053027
Sridhar Siricilla23e2cde2022-01-14 19:20:15 +053028enum alderlake_model {
29 ADL_MODEL_P_M = 0x9A,
30 ADL_MODEL_N = 0xBE,
31};
32
Subrata Banik56ab8e22022-01-07 13:40:19 +000033bool cpu_soc_is_in_untrusted_mode(void)
34{
35 msr_t msr;
36
37 msr = rdmsr(MSR_BIOS_DONE);
38 return !!(msr.lo & ENABLE_IA_UNTRUSTED);
39}
40
Subrata Banik2871e0e2020-09-27 11:30:58 +053041static void soc_fsp_load(void)
42{
Kyösti Mälkkicc93c6e2021-01-09 22:53:52 +020043 fsps_load();
Subrata Banik2871e0e2020-09-27 11:30:58 +053044}
45
Subrata Banik2871e0e2020-09-27 11:30:58 +053046static void configure_misc(void)
47{
48 msr_t msr;
49
Tim Wawrzynczakb0d3a012021-12-02 16:19:29 -070050 const config_t *conf = config_of_soc();
Subrata Banik2871e0e2020-09-27 11:30:58 +053051
52 msr = rdmsr(IA32_MISC_ENABLE);
53 msr.lo |= (1 << 0); /* Fast String enable */
54 msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
55 wrmsr(IA32_MISC_ENABLE, msr);
56
57 /* Set EIST status */
58 cpu_set_eist(conf->eist_enable);
59
60 /* Disable Thermal interrupts */
61 msr.lo = 0;
62 msr.hi = 0;
63 wrmsr(IA32_THERM_INTERRUPT, msr);
64
65 /* Enable package critical interrupt only */
66 msr.lo = 1 << 4;
67 msr.hi = 0;
68 wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
69
70 /* Enable PROCHOT */
71 msr = rdmsr(MSR_POWER_CTL);
Angel Pons4d794bd2021-10-11 14:00:54 +020072 msr.lo |= (1 << 0); /* Enable Bi-directional PROCHOT as an input */
Subrata Banik2871e0e2020-09-27 11:30:58 +053073 msr.lo |= (1 << 23); /* Lock it */
74 wrmsr(MSR_POWER_CTL, msr);
75}
76
Sridhar Siricilla23e2cde2022-01-14 19:20:15 +053077enum core_type get_soc_cpu_type(void)
78{
79 struct cpuinfo_x86 cpuinfo;
80
81 if (cpu_is_hybrid_supported())
82 return cpu_get_cpu_type();
83
84 get_fms(&cpuinfo, cpuid_eax(1));
85
86 if (cpuinfo.x86 == 0x6 && cpuinfo.x86_model == ADL_MODEL_N)
87 return CPUID_CORE_TYPE_INTEL_ATOM;
88 else
89 return CPUID_CORE_TYPE_INTEL_CORE;
90}
91
Sridahr Siricilla73b90c62021-11-11 01:10:16 +053092void soc_get_scaling_factor(u16 *big_core_scal_factor, u16 *small_core_scal_factor)
93{
94 *big_core_scal_factor = 127;
95 *small_core_scal_factor = 100;
96}
97
98bool soc_is_nominal_freq_supported(void)
99{
100 return true;
101}
102
Subrata Banik2871e0e2020-09-27 11:30:58 +0530103/* All CPUs including BSP will run the following function. */
104void soc_core_init(struct device *cpu)
105{
106 /* Clear out pending MCEs */
107 /* TODO(adurbin): This should only be done on a cold boot. Also, some
108 * of these banks are core vs package scope. For now every CPU clears
109 * every bank. */
110 mca_configure();
111
Subrata Banik2871e0e2020-09-27 11:30:58 +0530112 enable_lapic_tpr();
Subrata Banik2871e0e2020-09-27 11:30:58 +0530113
114 /* Configure Enhanced SpeedStep and Thermal Sensors */
115 configure_misc();
116
Subrata Banik2871e0e2020-09-27 11:30:58 +0530117 enable_pm_timer_emulation();
118
119 /* Enable Direct Cache Access */
120 configure_dca_cap();
121
122 /* Set energy policy */
123 set_energy_perf_bias(ENERGY_POLICY_NORMAL);
124
125 /* Enable Turbo */
126 enable_turbo();
127}
128
129static void per_cpu_smm_trigger(void)
130{
131 /* Relocate the SMM handler. */
132 smm_relocate();
133}
134
135static void post_mp_init(void)
136{
137 /* Set Max Ratio */
138 cpu_set_max_ratio();
139
140 /*
Kane Chen3aee3ad2021-05-04 09:53:38 +0800141 * 1. Now that all APs have been relocated as well as the BSP let SMIs
Subrata Banik2871e0e2020-09-27 11:30:58 +0530142 * start flowing.
Kane Chen3aee3ad2021-05-04 09:53:38 +0800143 * 2. Skip enabling power button SMI and enable it after BS_CHIPS_INIT
144 * to avoid shutdown hang due to lack of init on certain IP in FSP-S.
Subrata Banik2871e0e2020-09-27 11:30:58 +0530145 */
Kane Chen3aee3ad2021-05-04 09:53:38 +0800146 global_smi_enable_no_pwrbtn();
Subrata Banik2871e0e2020-09-27 11:30:58 +0530147}
148
149static const struct mp_ops mp_ops = {
150 /*
151 * Skip Pre MP init MTRR programming as MTRRs are mirrored from BSP,
152 * that are set prior to ramstage.
153 * Real MTRRs programming are being done after resource allocation.
154 */
155 .pre_mp_init = soc_fsp_load,
156 .get_cpu_count = get_cpu_count,
157 .get_smm_info = smm_info,
158 .get_microcode_info = get_microcode_info,
159 .pre_mp_smm_init = smm_initialize,
160 .per_cpu_smm_trigger = per_cpu_smm_trigger,
161 .relocation_handler = smm_relocation_handler,
162 .post_mp_init = post_mp_init,
163};
164
165void soc_init_cpus(struct bus *cpu_bus)
166{
Felix Held4dd7d112021-10-20 23:31:43 +0200167 /* TODO: Handle mp_init_with_smm failure? */
168 mp_init_with_smm(cpu_bus, &mp_ops);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530169
170 /* Thermal throttle activation offset */
171 configure_tcc_thermal_target();
172}
Tim Wawrzynczak6cf79d92021-07-30 10:37:55 -0600173
174enum adl_cpu_type get_adl_cpu_type(void)
175{
176 const uint16_t adl_m_mch_ids[] = {
Felix Singer43b7f412022-03-07 04:34:52 +0100177 PCI_DID_INTEL_ADL_M_ID_1,
178 PCI_DID_INTEL_ADL_M_ID_2,
Tim Wawrzynczak6cf79d92021-07-30 10:37:55 -0600179 };
180 const uint16_t adl_p_mch_ids[] = {
Felix Singer43b7f412022-03-07 04:34:52 +0100181 PCI_DID_INTEL_ADL_P_ID_1,
182 PCI_DID_INTEL_ADL_P_ID_3,
183 PCI_DID_INTEL_ADL_P_ID_4,
184 PCI_DID_INTEL_ADL_P_ID_5,
185 PCI_DID_INTEL_ADL_P_ID_6,
186 PCI_DID_INTEL_ADL_P_ID_7,
187 PCI_DID_INTEL_ADL_P_ID_8,
188 PCI_DID_INTEL_ADL_P_ID_9,
189 PCI_DID_INTEL_ADL_P_ID_10
Tim Wawrzynczak6cf79d92021-07-30 10:37:55 -0600190 };
191 const uint16_t adl_s_mch_ids[] = {
Felix Singer43b7f412022-03-07 04:34:52 +0100192 PCI_DID_INTEL_ADL_S_ID_1,
193 PCI_DID_INTEL_ADL_S_ID_2,
194 PCI_DID_INTEL_ADL_S_ID_3,
195 PCI_DID_INTEL_ADL_S_ID_4,
196 PCI_DID_INTEL_ADL_S_ID_5,
197 PCI_DID_INTEL_ADL_S_ID_6,
198 PCI_DID_INTEL_ADL_S_ID_7,
199 PCI_DID_INTEL_ADL_S_ID_8,
200 PCI_DID_INTEL_ADL_S_ID_9,
201 PCI_DID_INTEL_ADL_S_ID_10,
202 PCI_DID_INTEL_ADL_S_ID_11,
203 PCI_DID_INTEL_ADL_S_ID_12,
204 PCI_DID_INTEL_ADL_S_ID_13,
205 PCI_DID_INTEL_ADL_S_ID_14,
206 PCI_DID_INTEL_ADL_S_ID_15,
Tim Wawrzynczak6cf79d92021-07-30 10:37:55 -0600207 };
208
Usha P93f50b32021-12-02 14:18:10 +0530209 const uint16_t adl_n_mch_ids[] = {
Felix Singer43b7f412022-03-07 04:34:52 +0100210 PCI_DID_INTEL_ADL_N_ID_1,
211 PCI_DID_INTEL_ADL_N_ID_2,
212 PCI_DID_INTEL_ADL_N_ID_3,
213 PCI_DID_INTEL_ADL_N_ID_4,
Usha P93f50b32021-12-02 14:18:10 +0530214 };
215
Tim Wawrzynczak6cf79d92021-07-30 10:37:55 -0600216 const uint16_t mchid = pci_s_read_config16(PCI_DEV(0, PCI_SLOT(SA_DEVFN_ROOT),
217 PCI_FUNC(SA_DEVFN_ROOT)),
218 PCI_DEVICE_ID);
219
220 for (size_t i = 0; i < ARRAY_SIZE(adl_p_mch_ids); i++) {
221 if (adl_p_mch_ids[i] == mchid)
222 return ADL_P;
223 }
224
225 for (size_t i = 0; i < ARRAY_SIZE(adl_m_mch_ids); i++) {
226 if (adl_m_mch_ids[i] == mchid)
227 return ADL_M;
228 }
229
230 for (size_t i = 0; i < ARRAY_SIZE(adl_s_mch_ids); i++) {
231 if (adl_s_mch_ids[i] == mchid)
232 return ADL_S;
233 }
234
Usha P93f50b32021-12-02 14:18:10 +0530235 for (size_t i = 0; i < ARRAY_SIZE(adl_n_mch_ids); i++) {
236 if (adl_n_mch_ids[i] == mchid)
237 return ADL_N;
238 }
239
Tim Wawrzynczak6cf79d92021-07-30 10:37:55 -0600240 return ADL_UNKNOWN;
241}
Tim Wawrzynczake2b8f302021-07-19 15:35:47 -0600242
243uint8_t get_supported_lpm_mask(void)
244{
245 enum adl_cpu_type type = get_adl_cpu_type();
246 switch (type) {
247 case ADL_M: /* fallthrough */
Usha P93f50b32021-12-02 14:18:10 +0530248 case ADL_N:
Tim Wawrzynczake2b8f302021-07-19 15:35:47 -0600249 case ADL_P:
250 return LPM_S0i2_0 | LPM_S0i3_0;
251 case ADL_S:
252 return LPM_S0i2_0 | LPM_S0i2_1;
253 default:
254 printk(BIOS_ERR, "Unknown ADL CPU type: %d\n", type);
255 return 0;
256 }
257}