blob: 4029f723df4046a0d8924735f650bb7aa19a1689 [file] [log] [blame]
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +02001/*
2 * This file is part of the coreboot project.
3 *
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +02004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +020012 */
13
14#include <console/console.h>
Timothy Pearson83abd812015-06-08 19:35:06 -050015#include <option.h>
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +020016#include <cpu/x86/msr.h>
Elyes HAOUAS400ce552018-10-12 10:54:30 +020017#include <cpu/amd/msr.h>
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +020018#include <arch/acpigen.h>
19#include <cpu/amd/powernow.h>
Timothy Pearson6300b032015-01-26 17:53:22 -060020#include <device/pci.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Timothy Pearson6300b032015-01-26 17:53:22 -060022#include <cpu/amd/mtrr.h>
23#include <cpu/amd/amdfam10_sysconf.h>
24#include <arch/cpu.h>
25#include <northbridge/amd/amdht/AsPsDefs.h>
Timothy Pearsonead87512015-02-20 12:47:52 -060026#include <northbridge/amd/amdmct/mct/mct.h>
27#include <northbridge/amd/amdmct/amddefs.h>
Elyes HAOUASb12ece92019-05-15 21:01:02 +020028#include <types.h>
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +020029
Timothy Pearson83abd812015-06-08 19:35:06 -050030static inline uint8_t is_fam15h(void)
31{
32 uint8_t fam15h = 0;
33 uint32_t family;
34
35 family = cpuid_eax(0x80000001);
36 family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
37
38 if (family >= 0x6f)
39 /* Family 15h or later */
40 fam15h = 1;
41
42 return fam15h;
43}
44
Timothy Pearson6300b032015-01-26 17:53:22 -060045static void write_pstates_for_core(u8 pstate_num, u16 *pstate_feq, u32 *pstate_power,
46 u32 *pstate_latency, u32 *pstate_control,
47 u32 *pstate_status, int coreID,
Timothy Pearsonef33db02015-05-08 00:32:47 -050048 uint8_t single_link)
Timothy Pearson6300b032015-01-26 17:53:22 -060049{
50 int i;
Timothy Pearsonef33db02015-05-08 00:32:47 -050051 struct cpuid_result cpuid1;
Timothy Pearson6300b032015-01-26 17:53:22 -060052
Timothy Pearson6300b032015-01-26 17:53:22 -060053 acpigen_write_empty_PCT();
54 acpigen_write_name("_PSS");
55
56 /* add later to total sum */
57 acpigen_write_package(pstate_num);
58
59 for (i = 0;i < pstate_num; i++)
60 acpigen_write_PSS_package(pstate_feq[i],
61 pstate_power[i],
62 pstate_latency[i],
63 pstate_latency[i],
64 pstate_control[i],
65 pstate_status[i]);
66
67 /* update the package size */
68 acpigen_pop_len();
69
Timothy Pearsonef33db02015-05-08 00:32:47 -050070 /* Write PPC object */
Timothy Pearson6300b032015-01-26 17:53:22 -060071 acpigen_write_PPC(pstate_num);
Timothy Pearsonef33db02015-05-08 00:32:47 -050072
73 /* Write PSD indicating coordination type */
74 if ((single_link) && (mctGetLogicalCPUID(0) & AMD_DR_GT_Bx)) {
75 /* Revision C or greater single-link processor */
76 cpuid1 = cpuid(0x80000008);
77 acpigen_write_PSD_package(0, (cpuid1.ecx & 0xff) + 1, SW_ALL);
Timothy Pearson730a0432015-10-16 13:51:51 -050078 } else {
Timothy Pearsonef33db02015-05-08 00:32:47 -050079 /* Find the local APIC ID for the specified core ID */
80 struct device* cpu;
81 int cpu_index = 0;
82 for (cpu = all_devices; cpu; cpu = cpu->next) {
83 if ((cpu->path.type != DEVICE_PATH_APIC) ||
84 (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER))
85 continue;
86 if (!cpu->enabled)
87 continue;
88 if (cpu_index == coreID)
89 break;
90 cpu_index++;
91 }
92
93 if (cpu)
94 acpigen_write_PSD_package(cpu->path.apic.apic_id, 1, SW_ANY);
95 }
Timothy Pearson83abd812015-06-08 19:35:06 -050096}
Timothy Pearsonef33db02015-05-08 00:32:47 -050097
Timothy Pearson83abd812015-06-08 19:35:06 -050098static void write_cstates_for_core(int coreID)
99{
100 /* Generate C state entries */
101 uint8_t cstate_count = 1;
102 acpi_cstate_t cstate;
103
104 if (is_fam15h()) {
105 cstate.ctype = 2;
106 cstate.latency = 100;
107 cstate.power = 0;
108 cstate.resource.space_id = ACPI_ADDRESS_SPACE_IO;
109 cstate.resource.bit_width = 8;
110 cstate.resource.bit_offset = 0;
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200111 cstate.resource.addrl = rdmsr(MSR_CSTATE_ADDRESS).lo + 1;
Timothy Pearson83abd812015-06-08 19:35:06 -0500112 cstate.resource.addrh = 0;
Elyes HAOUAS8ee161d2019-03-03 12:49:56 +0100113 cstate.resource.access_size = 1;
Timothy Pearson83abd812015-06-08 19:35:06 -0500114 } else {
115 cstate.ctype = 2;
116 cstate.latency = 75;
117 cstate.power = 0;
118 cstate.resource.space_id = ACPI_ADDRESS_SPACE_IO;
119 cstate.resource.bit_width = 8;
120 cstate.resource.bit_offset = 0;
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200121 cstate.resource.addrl = rdmsr(MSR_CSTATE_ADDRESS).lo;
Timothy Pearson83abd812015-06-08 19:35:06 -0500122 cstate.resource.addrh = 0;
Elyes HAOUAS8ee161d2019-03-03 12:49:56 +0100123 cstate.resource.access_size = 1;
Timothy Pearson83abd812015-06-08 19:35:06 -0500124 }
125
126 acpigen_write_CST_package(&cstate, cstate_count);
127
128 /* Find the local APIC ID for the specified core ID */
129 if (is_fam15h()) {
130 struct device* cpu;
131 int cpu_index = 0;
132 for (cpu = all_devices; cpu; cpu = cpu->next) {
133 if ((cpu->path.type != DEVICE_PATH_APIC) ||
134 (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER))
135 continue;
136 if (!cpu->enabled)
137 continue;
138 if (cpu_index == coreID)
139 break;
140 cpu_index++;
141 }
142
143 if (cpu) {
144 /* TODO
145 * Detect dual core status and skip CSD generation if dual core is disabled
146 */
147
148 /* Generate C state dependency entries */
149 acpigen_write_CSD_package((cpu->path.apic.apic_id >> 1) & 0x7f, 2, CSD_HW_ALL, 0);
150 }
151 }
Timothy Pearson6300b032015-01-26 17:53:22 -0600152}
153
154/*
Timothy Pearson730a0432015-10-16 13:51:51 -0500155* For details of this algorithm, please refer to:
156* Family 10h BDKG 3.62 page 69
157* Family 15h BDKG 3.14 page 74
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600158*
159* WARNING: The core count algorithm below assumes that all processors
160* are identical, with the same number of active cores. While the BKDG
161* states the BIOS must enforce this coreboot does not currently do so.
162* As a result it is possible that this code may break if an illegal
163* processor combination is installed. If it does break please fix the
164* code in the proper locations!
Timothy Pearson6300b032015-01-26 17:53:22 -0600165*/
Patrick Georgia425b962015-03-05 20:18:21 +0100166void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
Timothy Pearson6300b032015-01-26 17:53:22 -0600167{
168 u8 processor_brand[49];
169 u32 *v;
170 struct cpuid_result cpuid1;
171
172 u16 Pstate_feq[10];
173 u32 Pstate_power[10];
174 u32 Pstate_latency[10];
175 u32 Pstate_control[10];
176 u32 Pstate_status[10];
177 u8 Pstate_num;
178 u8 cmp_cap;
179 u8 index;
180 msr_t msr;
181
Timothy Pearson83abd812015-06-08 19:35:06 -0500182 uint8_t nvram;
183 uint8_t enable_c_states;
184
185 enable_c_states = 0;
Julius Wernercd49cce2019-03-05 16:53:33 -0800186#if CONFIG(HAVE_ACPI_TABLES)
Timothy Pearson83abd812015-06-08 19:35:06 -0500187 if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS)
188 enable_c_states = !!nvram;
189#endif
190
Timothy Pearson6300b032015-01-26 17:53:22 -0600191 /* Get the Processor Brand String using cpuid(0x8000000x) command x=2,3,4 */
192 cpuid1 = cpuid(0x80000002);
193 v = (u32 *) processor_brand;
194 v[0] = cpuid1.eax;
195 v[1] = cpuid1.ebx;
196 v[2] = cpuid1.ecx;
197 v[3] = cpuid1.edx;
198 cpuid1 = cpuid(0x80000003);
199 v[4] = cpuid1.eax;
200 v[5] = cpuid1.ebx;
201 v[6] = cpuid1.ecx;
202 v[7] = cpuid1.edx;
203 cpuid1 = cpuid(0x80000004);
204 v[8] = cpuid1.eax;
205 v[9] = cpuid1.ebx;
206 v[10] = cpuid1.ecx;
207 v[11] = cpuid1.edx;
208 processor_brand[48] = 0;
209 printk(BIOS_INFO, "processor_brand=%s\n", processor_brand);
210
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600211 uint32_t dtemp;
Timothy Pearson066980c2015-05-08 17:17:44 -0500212 uint8_t node_index;
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600213 uint8_t node_count;
Timothy Pearson066980c2015-05-08 17:17:44 -0500214 uint8_t cores_per_node;
215 uint8_t total_core_count;
Timothy Pearson730a0432015-10-16 13:51:51 -0500216 uint8_t fam15h;
217 uint8_t fam10h_rev_e = 0;
218
219 /* Detect Revision E processors via method used in fidvid.c */
220 if ((cpuid_edx(0x80000007) & CPB_MASK)
221 && ((cpuid_ecx(0x80000008) & NC_MASK) == 5))
222 fam10h_rev_e = 1;
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600223
Timothy Pearson6300b032015-01-26 17:53:22 -0600224 /*
Elyes HAOUASa342f392018-10-17 10:56:26 +0200225 * Based on the CPU socket type, cmp_cap and pwr_lmt, get the power limit.
Elyes HAOUAS90ba1892016-10-02 10:23:01 +0200226 * socket_type : 0x10 SocketF; 0x11 AM2/ASB1; 0x12 S1G1
227 * cmp_cap : 0x0 SingleCore; 0x1 DualCore; 0x2 TripleCore; 0x3 QuadCore; 0x4 QuintupleCore; 0x5 HexCore
Timothy Pearson6300b032015-01-26 17:53:22 -0600228 */
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600229 printk(BIOS_INFO, "Pstates algorithm ...\n");
Timothy Pearson730a0432015-10-16 13:51:51 -0500230 fam15h = !!(mctGetLogicalCPUID(0) & AMD_FAM15_ALL);
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600231 /* Get number of cores */
Timothy Pearson730a0432015-10-16 13:51:51 -0500232 if (fam15h) {
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300233 cmp_cap = pci_read_config32(pcidev_on_root(0x18, 5), 0x84) &
234 0xff;
Timothy Pearson730a0432015-10-16 13:51:51 -0500235 } else {
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300236 dtemp = pci_read_config32(pcidev_on_root(0x18, 3), 0xe8);
Timothy Pearson730a0432015-10-16 13:51:51 -0500237 cmp_cap = (dtemp & 0x3000) >> 12;
238 if (mctGetLogicalCPUID(0) & (AMD_FAM10_REV_D | AMD_FAM15_ALL)) /* revision D or higher */
239 cmp_cap |= (dtemp & 0x8000) >> 13;
240 }
241
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600242 /* Get number of nodes */
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300243 dtemp = pci_read_config32(pcidev_on_root(0x18, 0), 0x60);
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600244 node_count = ((dtemp & 0x70) >> 4) + 1;
Timothy Pearson066980c2015-05-08 17:17:44 -0500245 cores_per_node = cmp_cap + 1;
246
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600247 /* Compute total number of cores installed in system */
Timothy Pearson066980c2015-05-08 17:17:44 -0500248 total_core_count = cores_per_node * node_count;
Timothy Pearson6300b032015-01-26 17:53:22 -0600249
Timothy Pearson730a0432015-10-16 13:51:51 -0500250 /* Get number of boost states */
251 uint8_t boost_count = 0;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300252 dtemp = pci_read_config32(pcidev_on_root(0x18, 4), 0x15c);
Timothy Pearson730a0432015-10-16 13:51:51 -0500253 if (fam10h_rev_e)
254 boost_count = (dtemp >> 2) & 0x1;
255 else if (mctGetLogicalCPUID(0) & AMD_FAM15_ALL)
256 boost_count = (dtemp >> 2) & 0x7;
257
Timothy Pearson6300b032015-01-26 17:53:22 -0600258 /* See if the CPUID(0x80000007) returned EDX[7]==1b */
259 cpuid1 = cpuid(0x80000007);
260 if ((cpuid1.edx & 0x80) != 0x80) {
261 printk(BIOS_INFO, "No valid set of P-states\n");
Patrick Georgi477b4c52015-02-22 16:21:01 +0100262 return;
Timothy Pearson6300b032015-01-26 17:53:22 -0600263 }
264
Timothy Pearson83abd812015-06-08 19:35:06 -0500265 if (fam15h)
266 /* Set P_LVL2 P_BLK entry */
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200267 *(((uint8_t *)pcontrol_blk) + 0x04) =
268 (rdmsr(MSR_CSTATE_ADDRESS).lo + 1) & 0xff;
Timothy Pearson83abd812015-06-08 19:35:06 -0500269
Timothy Pearson6300b032015-01-26 17:53:22 -0600270 uint8_t pviModeFlag;
271 uint8_t Pstate_max;
272 uint8_t cpufid;
273 uint8_t cpudid;
274 uint8_t cpuvid;
275 uint8_t cpuidd;
276 uint8_t cpuidv;
277 uint8_t power_step_up;
278 uint8_t power_step_down;
279 uint8_t pll_lock_time;
280 uint32_t expanded_cpuidv;
281 uint32_t core_frequency;
282 uint32_t core_power;
283 uint32_t core_latency;
284 uint32_t core_voltage; /* multiplied by 10000 */
Timothy Pearsonef33db02015-05-08 00:32:47 -0500285 uint8_t single_link;
286
Timothy Pearson6300b032015-01-26 17:53:22 -0600287 /* Determine if this is a PVI or SVI system */
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300288 dtemp = pci_read_config32(pcidev_on_root(0x18, 3), 0xA0);
Timothy Pearson6300b032015-01-26 17:53:22 -0600289
290 if (dtemp & PVI_MODE)
291 pviModeFlag = 1;
292 else
293 pviModeFlag = 0;
294
295 /* Get PSmax's index */
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200296 msr = rdmsr(PS_LIM_REG);
Timothy Pearson730a0432015-10-16 13:51:51 -0500297 Pstate_max = (uint8_t) ((msr.lo >> PS_MAX_VAL_SHFT) & ((fam15h)?BIT_MASK_7:BIT_MASK_3));
Timothy Pearson6300b032015-01-26 17:53:22 -0600298
299 /* Determine if all enabled Pstates have the same fidvid */
300 uint8_t i;
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200301 uint8_t cpufid_prev = (rdmsr(PSTATE_0_MSR).lo & 0x3f);
Timothy Pearson6300b032015-01-26 17:53:22 -0600302 uint8_t all_enabled_cores_have_same_cpufid = 1;
303 for (i = 1; i < Pstate_max; i++) {
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200304 cpufid = rdmsr(PSTATE_0_MSR + i).lo & 0x3f;
Timothy Pearson6300b032015-01-26 17:53:22 -0600305 if (cpufid != cpufid_prev) {
306 all_enabled_cores_have_same_cpufid = 0;
307 break;
308 }
309 }
310
Timothy Pearson730a0432015-10-16 13:51:51 -0500311 /* Family 15h uses slightly different PSmax numbering */
312 if (fam15h)
313 Pstate_max++;
314
Timothy Pearson6300b032015-01-26 17:53:22 -0600315 /* Populate tables with all Pstate information */
316 for (Pstate_num = 0; Pstate_num < Pstate_max; Pstate_num++) {
317 /* Get power state information */
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200318 msr = rdmsr(PSTATE_0_MSR + Pstate_num + boost_count);
Timothy Pearson6300b032015-01-26 17:53:22 -0600319 cpufid = (msr.lo & 0x3f);
320 cpudid = (msr.lo & 0x1c0) >> 6;
321 cpuvid = (msr.lo & 0xfe00) >> 9;
322 cpuidd = (msr.hi & 0xff);
323 cpuidv = (msr.hi & 0x300) >> 8;
324 core_frequency = (100 * (cpufid + 0x10)) / (0x01 << cpudid);
325 if (pviModeFlag) {
326 if (cpuvid >= 0x20) {
327 core_voltage = 7625 - (((cpuvid - 0x20) * 10000) / 80);
Timothy Pearson730a0432015-10-16 13:51:51 -0500328 } else {
Timothy Pearson6300b032015-01-26 17:53:22 -0600329 core_voltage = 15500 - ((cpuvid * 10000) / 40);
330 }
Timothy Pearson730a0432015-10-16 13:51:51 -0500331 } else {
Timothy Pearson6300b032015-01-26 17:53:22 -0600332 cpuvid = cpuvid & 0x7f;
333 if (cpuvid >= 0x7c)
334 core_voltage = 0;
335 else
336 core_voltage = 15500 - ((cpuvid * 10000) / 80);
337 }
338 switch (cpuidv) {
339 case 0x0:
340 expanded_cpuidv = 1;
341 break;
342 case 0x1:
343 expanded_cpuidv = 10;
344 break;
345 case 0x2:
346 expanded_cpuidv = 100;
347 break;
348 case 0x3:
349 expanded_cpuidv = 1000;
350 break;
Patrick Georgiaab66b12015-02-22 16:27:56 +0100351 default:
352 printk(BIOS_ERR, "%s:%s:%d: Invalid cpuidv, "
353 "not generating pstate tables.\n",
354 __FILE__, __func__, __LINE__);
355 return;
Timothy Pearson6300b032015-01-26 17:53:22 -0600356 }
357 core_power = (core_voltage * cpuidd) / (expanded_cpuidv * 10);
358
359 /* Calculate transition latency */
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300360 dtemp = pci_read_config32(pcidev_on_root(0x18, 3), 0xD4);
Timothy Pearson6300b032015-01-26 17:53:22 -0600361 power_step_up = (dtemp & 0xf000000) >> 24;
362 power_step_down = (dtemp & 0xf00000) >> 20;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300363 dtemp = pci_read_config32(pcidev_on_root(0x18, 3), 0xA0);
Timothy Pearsonc1f47c12015-02-06 16:07:53 -0600364 pll_lock_time = (dtemp & 0x3800) >> 11;
Timothy Pearson6300b032015-01-26 17:53:22 -0600365 if (all_enabled_cores_have_same_cpufid)
366 core_latency = ((12 * power_step_down) + power_step_up) / 1000;
367 else
368 core_latency = (12 * (power_step_down + power_step_up) / 1000)
369 + pll_lock_time;
370
371 Pstate_feq[Pstate_num] = core_frequency;
372 Pstate_power[Pstate_num] = core_power;
373 Pstate_latency[Pstate_num] = core_latency;
374 Pstate_control[Pstate_num] = Pstate_num;
375 Pstate_status[Pstate_num] = Pstate_num;
376 }
377
378 /* Print Pstate frequency, power, and latency */
379 for (index = 0; index < Pstate_num; index++) {
380 printk(BIOS_INFO, "Pstate_freq[%d] = %dMHz\t", index,
381 Pstate_feq[index]);
382 printk(BIOS_INFO, "Pstate_power[%d] = %dmw\n", index,
383 Pstate_power[index]);
384 printk(BIOS_INFO, "Pstate_latency[%d] = %dus\n", index,
385 Pstate_latency[index]);
386 }
387
Timothy Pearson83abd812015-06-08 19:35:06 -0500388 /* Enter processor block scope */
Patrick Georgia425b962015-03-05 20:18:21 +0100389 char pscope[] = "\\_PR";
Patrick Georgia425b962015-03-05 20:18:21 +0100390 acpigen_write_scope(pscope);
Timothy Pearson83abd812015-06-08 19:35:06 -0500391
Timothy Pearson066980c2015-05-08 17:17:44 -0500392 for (index = 0; index < total_core_count; index++) {
393 /* Determine if this is a single-link processor */
394 node_index = 0x18 + (index / cores_per_node);
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300395 dtemp = pci_read_config32(pcidev_on_root(node_index, 0), 0x80);
Timothy Pearson066980c2015-05-08 17:17:44 -0500396 single_link = !!(((dtemp & 0xff00) >> 8) == 0);
397
Timothy Pearson83abd812015-06-08 19:35:06 -0500398 /* Enter processor core scope */
399 uint8_t plen_cur = plen;
400 uint32_t pcontrol_blk_cur = pcontrol_blk;
401 if ((onlyBSP) && (index != 0)) {
402 plen_cur = 0;
403 pcontrol_blk_cur = 0;
404 }
405 acpigen_write_processor(index, pcontrol_blk_cur, plen_cur);
406
407 /* Write P-state status and dependency objects */
Timothy Pearson6300b032015-01-26 17:53:22 -0600408 write_pstates_for_core(Pstate_num, Pstate_feq, Pstate_power,
409 Pstate_latency, Pstate_control, Pstate_status,
Timothy Pearson83abd812015-06-08 19:35:06 -0500410 index, single_link);
411
412 /* Write C-state status and dependency objects */
413 if (fam15h && enable_c_states)
414 write_cstates_for_core(index);
415
416 /* Exit processor core scope */
417 acpigen_pop_len();
Timothy Pearson066980c2015-05-08 17:17:44 -0500418 }
Timothy Pearson83abd812015-06-08 19:35:06 -0500419
420 /* Exit processor block scope */
Timothy Pearson6300b032015-01-26 17:53:22 -0600421 acpigen_pop_len();
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +0200422}
Timothy Pearson83abd812015-06-08 19:35:06 -0500423
424void amd_powernow_update_fadt(acpi_fadt_t * fadt)
425{
426 if (is_fam15h()) {
427 fadt->p_lvl2_lat = 101; /* NOTE: While the BKDG states this should
428 * be set to 100, there is no way to meet
429 * the other FADT requirements. I suspect
430 * there is an error in the BKDG for ACPI
431 * 1.x support; disable all FADT-based C
432 * states > 2... */
433 fadt->p_lvl3_lat = 1001;
434 fadt->flags |= 0x1 << 2; /* FLAGS.PROC_C1 = 1 */
435 fadt->flags |= 0x1 << 3; /* FLAGS.P_LVL2_UP = 1 */
436 } else {
437 fadt->cst_cnt = 0;
438 }
439 fadt->pstate_cnt = 0;
440}