blob: a7cc9dad5b561374eb230f110e45633b52f9c14c [file] [log] [blame]
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +02001/*
2 * This file is part of the coreboot project.
3 *
Timothy Pearson6300b032015-01-26 17:53:22 -06004 * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +02005 * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz>
Timothy Pearson6300b032015-01-26 17:53:22 -06006 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +02007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +020016 */
17
18#include <console/console.h>
19#include <stdint.h>
Timothy Pearson83abd812015-06-08 19:35:06 -050020#include <option.h>
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +020021#include <cpu/x86/msr.h>
22#include <arch/acpigen.h>
23#include <cpu/amd/powernow.h>
Timothy Pearson6300b032015-01-26 17:53:22 -060024#include <device/pci.h>
25#include <device/pci_ids.h>
26#include <cpu/x86/msr.h>
27#include <cpu/amd/mtrr.h>
28#include <cpu/amd/amdfam10_sysconf.h>
29#include <arch/cpu.h>
30#include <northbridge/amd/amdht/AsPsDefs.h>
Timothy Pearsonead87512015-02-20 12:47:52 -060031#include <northbridge/amd/amdmct/mct/mct.h>
32#include <northbridge/amd/amdmct/amddefs.h>
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +020033
Timothy Pearson83abd812015-06-08 19:35:06 -050034static inline uint8_t is_fam15h(void)
35{
36 uint8_t fam15h = 0;
37 uint32_t family;
38
39 family = cpuid_eax(0x80000001);
40 family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
41
42 if (family >= 0x6f)
43 /* Family 15h or later */
44 fam15h = 1;
45
46 return fam15h;
47}
48
Timothy Pearson6300b032015-01-26 17:53:22 -060049static void write_pstates_for_core(u8 pstate_num, u16 *pstate_feq, u32 *pstate_power,
50 u32 *pstate_latency, u32 *pstate_control,
51 u32 *pstate_status, int coreID,
Timothy Pearsonef33db02015-05-08 00:32:47 -050052 uint8_t single_link)
Timothy Pearson6300b032015-01-26 17:53:22 -060053{
54 int i;
Timothy Pearsonef33db02015-05-08 00:32:47 -050055 struct cpuid_result cpuid1;
Timothy Pearson6300b032015-01-26 17:53:22 -060056
Timothy Pearson6300b032015-01-26 17:53:22 -060057 acpigen_write_empty_PCT();
58 acpigen_write_name("_PSS");
59
60 /* add later to total sum */
61 acpigen_write_package(pstate_num);
62
63 for (i = 0;i < pstate_num; i++)
64 acpigen_write_PSS_package(pstate_feq[i],
65 pstate_power[i],
66 pstate_latency[i],
67 pstate_latency[i],
68 pstate_control[i],
69 pstate_status[i]);
70
71 /* update the package size */
72 acpigen_pop_len();
73
Timothy Pearsonef33db02015-05-08 00:32:47 -050074 /* Write PPC object */
Timothy Pearson6300b032015-01-26 17:53:22 -060075 acpigen_write_PPC(pstate_num);
Timothy Pearsonef33db02015-05-08 00:32:47 -050076
77 /* Write PSD indicating coordination type */
78 if ((single_link) && (mctGetLogicalCPUID(0) & AMD_DR_GT_Bx)) {
79 /* Revision C or greater single-link processor */
80 cpuid1 = cpuid(0x80000008);
81 acpigen_write_PSD_package(0, (cpuid1.ecx & 0xff) + 1, SW_ALL);
Timothy Pearson730a0432015-10-16 13:51:51 -050082 } else {
Timothy Pearsonef33db02015-05-08 00:32:47 -050083 /* Find the local APIC ID for the specified core ID */
84 struct device* cpu;
85 int cpu_index = 0;
86 for (cpu = all_devices; cpu; cpu = cpu->next) {
87 if ((cpu->path.type != DEVICE_PATH_APIC) ||
88 (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER))
89 continue;
90 if (!cpu->enabled)
91 continue;
92 if (cpu_index == coreID)
93 break;
94 cpu_index++;
95 }
96
97 if (cpu)
98 acpigen_write_PSD_package(cpu->path.apic.apic_id, 1, SW_ANY);
99 }
Timothy Pearson83abd812015-06-08 19:35:06 -0500100}
Timothy Pearsonef33db02015-05-08 00:32:47 -0500101
Timothy Pearson83abd812015-06-08 19:35:06 -0500102static void write_cstates_for_core(int coreID)
103{
104 /* Generate C state entries */
105 uint8_t cstate_count = 1;
106 acpi_cstate_t cstate;
107
108 if (is_fam15h()) {
109 cstate.ctype = 2;
110 cstate.latency = 100;
111 cstate.power = 0;
112 cstate.resource.space_id = ACPI_ADDRESS_SPACE_IO;
113 cstate.resource.bit_width = 8;
114 cstate.resource.bit_offset = 0;
115 cstate.resource.addrl = rdmsr(0xc0010073).lo + 1;
116 cstate.resource.addrh = 0;
117 cstate.resource.resv = 1;
118 } else {
119 cstate.ctype = 2;
120 cstate.latency = 75;
121 cstate.power = 0;
122 cstate.resource.space_id = ACPI_ADDRESS_SPACE_IO;
123 cstate.resource.bit_width = 8;
124 cstate.resource.bit_offset = 0;
125 cstate.resource.addrl = rdmsr(0xc0010073).lo;
126 cstate.resource.addrh = 0;
127 cstate.resource.resv = 1;
128 }
129
130 acpigen_write_CST_package(&cstate, cstate_count);
131
132 /* Find the local APIC ID for the specified core ID */
133 if (is_fam15h()) {
134 struct device* cpu;
135 int cpu_index = 0;
136 for (cpu = all_devices; cpu; cpu = cpu->next) {
137 if ((cpu->path.type != DEVICE_PATH_APIC) ||
138 (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER))
139 continue;
140 if (!cpu->enabled)
141 continue;
142 if (cpu_index == coreID)
143 break;
144 cpu_index++;
145 }
146
147 if (cpu) {
148 /* TODO
149 * Detect dual core status and skip CSD generation if dual core is disabled
150 */
151
152 /* Generate C state dependency entries */
153 acpigen_write_CSD_package((cpu->path.apic.apic_id >> 1) & 0x7f, 2, CSD_HW_ALL, 0);
154 }
155 }
Timothy Pearson6300b032015-01-26 17:53:22 -0600156}
157
158/*
Timothy Pearson730a0432015-10-16 13:51:51 -0500159* For details of this algorithm, please refer to:
160* Family 10h BDKG 3.62 page 69
161* Family 15h BDKG 3.14 page 74
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600162*
163* WARNING: The core count algorithm below assumes that all processors
164* are identical, with the same number of active cores. While the BKDG
165* states the BIOS must enforce this coreboot does not currently do so.
166* As a result it is possible that this code may break if an illegal
167* processor combination is installed. If it does break please fix the
168* code in the proper locations!
Timothy Pearson6300b032015-01-26 17:53:22 -0600169*/
Patrick Georgia425b962015-03-05 20:18:21 +0100170void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
Timothy Pearson6300b032015-01-26 17:53:22 -0600171{
172 u8 processor_brand[49];
173 u32 *v;
174 struct cpuid_result cpuid1;
175
176 u16 Pstate_feq[10];
177 u32 Pstate_power[10];
178 u32 Pstate_latency[10];
179 u32 Pstate_control[10];
180 u32 Pstate_status[10];
181 u8 Pstate_num;
182 u8 cmp_cap;
183 u8 index;
184 msr_t msr;
185
Timothy Pearson83abd812015-06-08 19:35:06 -0500186 uint8_t nvram;
187 uint8_t enable_c_states;
188
189 enable_c_states = 0;
190#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
191 if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS)
192 enable_c_states = !!nvram;
193#endif
194
Timothy Pearson6300b032015-01-26 17:53:22 -0600195 /* Get the Processor Brand String using cpuid(0x8000000x) command x=2,3,4 */
196 cpuid1 = cpuid(0x80000002);
197 v = (u32 *) processor_brand;
198 v[0] = cpuid1.eax;
199 v[1] = cpuid1.ebx;
200 v[2] = cpuid1.ecx;
201 v[3] = cpuid1.edx;
202 cpuid1 = cpuid(0x80000003);
203 v[4] = cpuid1.eax;
204 v[5] = cpuid1.ebx;
205 v[6] = cpuid1.ecx;
206 v[7] = cpuid1.edx;
207 cpuid1 = cpuid(0x80000004);
208 v[8] = cpuid1.eax;
209 v[9] = cpuid1.ebx;
210 v[10] = cpuid1.ecx;
211 v[11] = cpuid1.edx;
212 processor_brand[48] = 0;
213 printk(BIOS_INFO, "processor_brand=%s\n", processor_brand);
214
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600215 uint32_t dtemp;
Timothy Pearson066980c2015-05-08 17:17:44 -0500216 uint8_t node_index;
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600217 uint8_t node_count;
Timothy Pearson066980c2015-05-08 17:17:44 -0500218 uint8_t cores_per_node;
219 uint8_t total_core_count;
Timothy Pearson730a0432015-10-16 13:51:51 -0500220 uint8_t fam15h;
221 uint8_t fam10h_rev_e = 0;
222
223 /* Detect Revision E processors via method used in fidvid.c */
224 if ((cpuid_edx(0x80000007) & CPB_MASK)
225 && ((cpuid_ecx(0x80000008) & NC_MASK) == 5))
226 fam10h_rev_e = 1;
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600227
Timothy Pearson6300b032015-01-26 17:53:22 -0600228 /*
229 * Based on the CPU socket type,cmp_cap and pwr_lmt , get the power limit.
230 * socket_type : 0x10 SocketF; 0x11 AM2/ASB1 ; 0x12 S1G1
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600231 * cmp_cap : 0x0 SingleCore ; 0x1 DualCore ; 0x2 TripleCore ; 0x3 QuadCore ; 0x4 QuintupleCore ; 0x5 HexCore
Timothy Pearson6300b032015-01-26 17:53:22 -0600232 */
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600233 printk(BIOS_INFO, "Pstates algorithm ...\n");
Timothy Pearson730a0432015-10-16 13:51:51 -0500234 fam15h = !!(mctGetLogicalCPUID(0) & AMD_FAM15_ALL);
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600235 /* Get number of cores */
Timothy Pearson730a0432015-10-16 13:51:51 -0500236 if (fam15h) {
237 cmp_cap = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 5)), 0x84) & 0xff;
238 } else {
239 dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xe8);
240 cmp_cap = (dtemp & 0x3000) >> 12;
241 if (mctGetLogicalCPUID(0) & (AMD_FAM10_REV_D | AMD_FAM15_ALL)) /* revision D or higher */
242 cmp_cap |= (dtemp & 0x8000) >> 13;
243 }
244
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600245 /* Get number of nodes */
246 dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 0)), 0x60);
247 node_count = ((dtemp & 0x70) >> 4) + 1;
Timothy Pearson066980c2015-05-08 17:17:44 -0500248 cores_per_node = cmp_cap + 1;
249
Timothy Pearson6fdb4d52015-02-10 21:15:39 -0600250 /* Compute total number of cores installed in system */
Timothy Pearson066980c2015-05-08 17:17:44 -0500251 total_core_count = cores_per_node * node_count;
Timothy Pearson6300b032015-01-26 17:53:22 -0600252
Timothy Pearson730a0432015-10-16 13:51:51 -0500253 /* Get number of boost states */
254 uint8_t boost_count = 0;
255 dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 4)), 0x15c);
256 if (fam10h_rev_e)
257 boost_count = (dtemp >> 2) & 0x1;
258 else if (mctGetLogicalCPUID(0) & AMD_FAM15_ALL)
259 boost_count = (dtemp >> 2) & 0x7;
260
Timothy Pearson6300b032015-01-26 17:53:22 -0600261 Pstate_num = 0;
262
263 /* See if the CPUID(0x80000007) returned EDX[7]==1b */
264 cpuid1 = cpuid(0x80000007);
265 if ((cpuid1.edx & 0x80) != 0x80) {
266 printk(BIOS_INFO, "No valid set of P-states\n");
Patrick Georgi477b4c52015-02-22 16:21:01 +0100267 return;
Timothy Pearson6300b032015-01-26 17:53:22 -0600268 }
269
Timothy Pearson83abd812015-06-08 19:35:06 -0500270 if (fam15h)
271 /* Set P_LVL2 P_BLK entry */
272 *(((uint8_t *)pcontrol_blk) + 0x04) = (rdmsr(0xc0010073).lo + 1) & 0xff;
273
Timothy Pearson6300b032015-01-26 17:53:22 -0600274 uint8_t pviModeFlag;
275 uint8_t Pstate_max;
276 uint8_t cpufid;
277 uint8_t cpudid;
278 uint8_t cpuvid;
279 uint8_t cpuidd;
280 uint8_t cpuidv;
281 uint8_t power_step_up;
282 uint8_t power_step_down;
283 uint8_t pll_lock_time;
284 uint32_t expanded_cpuidv;
285 uint32_t core_frequency;
286 uint32_t core_power;
287 uint32_t core_latency;
288 uint32_t core_voltage; /* multiplied by 10000 */
Timothy Pearsonef33db02015-05-08 00:32:47 -0500289 uint8_t single_link;
290
Timothy Pearson6300b032015-01-26 17:53:22 -0600291 /* Determine if this is a PVI or SVI system */
292 dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xA0);
293
294 if (dtemp & PVI_MODE)
295 pviModeFlag = 1;
296 else
297 pviModeFlag = 0;
298
299 /* Get PSmax's index */
300 msr = rdmsr(0xC0010061);
Timothy Pearson730a0432015-10-16 13:51:51 -0500301 Pstate_max = (uint8_t) ((msr.lo >> PS_MAX_VAL_SHFT) & ((fam15h)?BIT_MASK_7:BIT_MASK_3));
Timothy Pearson6300b032015-01-26 17:53:22 -0600302
303 /* Determine if all enabled Pstates have the same fidvid */
304 uint8_t i;
305 uint8_t cpufid_prev = (rdmsr(0xC0010064).lo & 0x3f);
306 uint8_t all_enabled_cores_have_same_cpufid = 1;
307 for (i = 1; i < Pstate_max; i++) {
308 cpufid = rdmsr(0xC0010064 + i).lo & 0x3f;
309 if (cpufid != cpufid_prev) {
310 all_enabled_cores_have_same_cpufid = 0;
311 break;
312 }
313 }
314
Timothy Pearson730a0432015-10-16 13:51:51 -0500315 /* Family 15h uses slightly different PSmax numbering */
316 if (fam15h)
317 Pstate_max++;
318
Timothy Pearson6300b032015-01-26 17:53:22 -0600319 /* Populate tables with all Pstate information */
320 for (Pstate_num = 0; Pstate_num < Pstate_max; Pstate_num++) {
321 /* Get power state information */
Timothy Pearson730a0432015-10-16 13:51:51 -0500322 msr = rdmsr(0xC0010064 + Pstate_num + boost_count);
Timothy Pearson6300b032015-01-26 17:53:22 -0600323 cpufid = (msr.lo & 0x3f);
324 cpudid = (msr.lo & 0x1c0) >> 6;
325 cpuvid = (msr.lo & 0xfe00) >> 9;
326 cpuidd = (msr.hi & 0xff);
327 cpuidv = (msr.hi & 0x300) >> 8;
328 core_frequency = (100 * (cpufid + 0x10)) / (0x01 << cpudid);
329 if (pviModeFlag) {
330 if (cpuvid >= 0x20) {
331 core_voltage = 7625 - (((cpuvid - 0x20) * 10000) / 80);
Timothy Pearson730a0432015-10-16 13:51:51 -0500332 } else {
Timothy Pearson6300b032015-01-26 17:53:22 -0600333 core_voltage = 15500 - ((cpuvid * 10000) / 40);
334 }
Timothy Pearson730a0432015-10-16 13:51:51 -0500335 } else {
Timothy Pearson6300b032015-01-26 17:53:22 -0600336 cpuvid = cpuvid & 0x7f;
337 if (cpuvid >= 0x7c)
338 core_voltage = 0;
339 else
340 core_voltage = 15500 - ((cpuvid * 10000) / 80);
341 }
342 switch (cpuidv) {
343 case 0x0:
344 expanded_cpuidv = 1;
345 break;
346 case 0x1:
347 expanded_cpuidv = 10;
348 break;
349 case 0x2:
350 expanded_cpuidv = 100;
351 break;
352 case 0x3:
353 expanded_cpuidv = 1000;
354 break;
Patrick Georgiaab66b12015-02-22 16:27:56 +0100355 default:
356 printk(BIOS_ERR, "%s:%s:%d: Invalid cpuidv, "
357 "not generating pstate tables.\n",
358 __FILE__, __func__, __LINE__);
359 return;
Timothy Pearson6300b032015-01-26 17:53:22 -0600360 }
361 core_power = (core_voltage * cpuidd) / (expanded_cpuidv * 10);
362
363 /* Calculate transition latency */
364 dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xD4);
365 power_step_up = (dtemp & 0xf000000) >> 24;
366 power_step_down = (dtemp & 0xf00000) >> 20;
367 dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xA0);
Timothy Pearsonc1f47c12015-02-06 16:07:53 -0600368 pll_lock_time = (dtemp & 0x3800) >> 11;
Timothy Pearson6300b032015-01-26 17:53:22 -0600369 if (all_enabled_cores_have_same_cpufid)
370 core_latency = ((12 * power_step_down) + power_step_up) / 1000;
371 else
372 core_latency = (12 * (power_step_down + power_step_up) / 1000)
373 + pll_lock_time;
374
375 Pstate_feq[Pstate_num] = core_frequency;
376 Pstate_power[Pstate_num] = core_power;
377 Pstate_latency[Pstate_num] = core_latency;
378 Pstate_control[Pstate_num] = Pstate_num;
379 Pstate_status[Pstate_num] = Pstate_num;
380 }
381
382 /* Print Pstate frequency, power, and latency */
383 for (index = 0; index < Pstate_num; index++) {
384 printk(BIOS_INFO, "Pstate_freq[%d] = %dMHz\t", index,
385 Pstate_feq[index]);
386 printk(BIOS_INFO, "Pstate_power[%d] = %dmw\n", index,
387 Pstate_power[index]);
388 printk(BIOS_INFO, "Pstate_latency[%d] = %dus\n", index,
389 Pstate_latency[index]);
390 }
391
Timothy Pearson83abd812015-06-08 19:35:06 -0500392 /* Enter processor block scope */
Patrick Georgia425b962015-03-05 20:18:21 +0100393 char pscope[] = "\\_PR";
Patrick Georgia425b962015-03-05 20:18:21 +0100394 acpigen_write_scope(pscope);
Timothy Pearson83abd812015-06-08 19:35:06 -0500395
Timothy Pearson066980c2015-05-08 17:17:44 -0500396 for (index = 0; index < total_core_count; index++) {
397 /* Determine if this is a single-link processor */
398 node_index = 0x18 + (index / cores_per_node);
399 dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(node_index, 0)), 0x80);
400 single_link = !!(((dtemp & 0xff00) >> 8) == 0);
401
Timothy Pearson83abd812015-06-08 19:35:06 -0500402 /* Enter processor core scope */
403 uint8_t plen_cur = plen;
404 uint32_t pcontrol_blk_cur = pcontrol_blk;
405 if ((onlyBSP) && (index != 0)) {
406 plen_cur = 0;
407 pcontrol_blk_cur = 0;
408 }
409 acpigen_write_processor(index, pcontrol_blk_cur, plen_cur);
410
411 /* Write P-state status and dependency objects */
Timothy Pearson6300b032015-01-26 17:53:22 -0600412 write_pstates_for_core(Pstate_num, Pstate_feq, Pstate_power,
413 Pstate_latency, Pstate_control, Pstate_status,
Timothy Pearson83abd812015-06-08 19:35:06 -0500414 index, single_link);
415
416 /* Write C-state status and dependency objects */
417 if (fam15h && enable_c_states)
418 write_cstates_for_core(index);
419
420 /* Exit processor core scope */
421 acpigen_pop_len();
Timothy Pearson066980c2015-05-08 17:17:44 -0500422 }
Timothy Pearson83abd812015-06-08 19:35:06 -0500423
424 /* Exit processor block scope */
Timothy Pearson6300b032015-01-26 17:53:22 -0600425 acpigen_pop_len();
Vladimir Serbinenko2a19fb12014-10-02 20:09:19 +0200426}
Timothy Pearson83abd812015-06-08 19:35:06 -0500427
428void amd_powernow_update_fadt(acpi_fadt_t * fadt)
429{
430 if (is_fam15h()) {
431 fadt->p_lvl2_lat = 101; /* NOTE: While the BKDG states this should
432 * be set to 100, there is no way to meet
433 * the other FADT requirements. I suspect
434 * there is an error in the BKDG for ACPI
435 * 1.x support; disable all FADT-based C
436 * states > 2... */
437 fadt->p_lvl3_lat = 1001;
438 fadt->flags |= 0x1 << 2; /* FLAGS.PROC_C1 = 1 */
439 fadt->flags |= 0x1 << 3; /* FLAGS.P_LVL2_UP = 1 */
440 } else {
441 fadt->cst_cnt = 0;
442 }
443 fadt->pstate_cnt = 0;
444}