1 /* 2 * From Coreboot file of same name 3 * 4 * Copyright (C) 2007-2009 coresystems GmbH 5 * Copyright (C) 2011 The Chromium Authors 6 * 7 * SPDX-License-Identifier: GPL-2.0 8 */ 9 10 #include <common.h> 11 #include <cpu.h> 12 #include <dm.h> 13 #include <fdtdec.h> 14 #include <malloc.h> 15 #include <asm/cpu.h> 16 #include <asm/cpu_x86.h> 17 #include <asm/msr.h> 18 #include <asm/msr-index.h> 19 #include <asm/mtrr.h> 20 #include <asm/processor.h> 21 #include <asm/speedstep.h> 22 #include <asm/turbo.h> 23 #include <asm/arch/model_206ax.h> 24 25 static void enable_vmx(void) 26 { 27 struct cpuid_result regs; 28 #ifdef CONFIG_ENABLE_VMX 29 int enable = true; 30 #else 31 int enable = false; 32 #endif 33 msr_t msr; 34 35 regs = cpuid(1); 36 /* Check that the VMX is supported before reading or writing the MSR. */ 37 if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) 38 return; 39 40 msr = msr_read(MSR_IA32_FEATURE_CONTROL); 41 42 if (msr.lo & (1 << 0)) { 43 debug("VMX is locked, so %s will do nothing\n", __func__); 44 /* VMX locked. If we set it again we get an illegal 45 * instruction 46 */ 47 return; 48 } 49 50 /* The IA32_FEATURE_CONTROL MSR may initialize with random values. 51 * It must be cleared regardless of VMX config setting. 52 */ 53 msr.hi = 0; 54 msr.lo = 0; 55 56 debug("%s VMX\n", enable ? "Enabling" : "Disabling"); 57 58 /* 59 * Even though the Intel manual says you must set the lock bit in 60 * addition to the VMX bit in order for VMX to work, it is incorrect. 61 * Thus we leave it unlocked for the OS to manage things itself. 62 * This is good for a few reasons: 63 * - No need to reflash the bios just to toggle the lock bit. 64 * - The VMX bits really really should match each other across cores, 65 * so hard locking it on one while another has the opposite setting 66 * can easily lead to crashes as code using VMX migrates between 67 * them. 68 * - Vendors that want to "upsell" from a bios that disables+locks to 69 * one that doesn't is sleazy. 70 * By leaving this to the OS (e.g. Linux), people can do exactly what 71 * they want on the fly, and do it correctly (e.g. across multiple 72 * cores). 73 */ 74 if (enable) { 75 msr.lo |= (1 << 2); 76 if (regs.ecx & CPUID_SMX) 77 msr.lo |= (1 << 1); 78 } 79 80 msr_write(MSR_IA32_FEATURE_CONTROL, msr); 81 } 82 83 /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ 84 static const u8 power_limit_time_sec_to_msr[] = { 85 [0] = 0x00, 86 [1] = 0x0a, 87 [2] = 0x0b, 88 [3] = 0x4b, 89 [4] = 0x0c, 90 [5] = 0x2c, 91 [6] = 0x4c, 92 [7] = 0x6c, 93 [8] = 0x0d, 94 [10] = 0x2d, 95 [12] = 0x4d, 96 [14] = 0x6d, 97 [16] = 0x0e, 98 [20] = 0x2e, 99 [24] = 0x4e, 100 [28] = 0x6e, 101 [32] = 0x0f, 102 [40] = 0x2f, 103 [48] = 0x4f, 104 [56] = 0x6f, 105 [64] = 0x10, 106 [80] = 0x30, 107 [96] = 0x50, 108 [112] = 0x70, 109 [128] = 0x11, 110 }; 111 112 /* Convert POWER_LIMIT_1_TIME MSR value to seconds */ 113 static const u8 power_limit_time_msr_to_sec[] = { 114 [0x00] = 0, 115 [0x0a] = 1, 116 [0x0b] = 2, 117 [0x4b] = 3, 118 [0x0c] = 4, 119 [0x2c] = 5, 120 [0x4c] = 6, 121 [0x6c] = 7, 122 [0x0d] = 8, 123 [0x2d] = 10, 124 [0x4d] = 12, 125 [0x6d] = 14, 126 [0x0e] = 16, 127 [0x2e] = 20, 128 [0x4e] = 24, 129 [0x6e] = 28, 130 [0x0f] = 32, 131 [0x2f] = 40, 132 [0x4f] = 48, 133 [0x6f] = 56, 134 [0x10] = 64, 135 [0x30] = 80, 136 [0x50] = 96, 137 [0x70] = 112, 138 [0x11] = 128, 139 }; 140 141 int cpu_config_tdp_levels(void) 142 { 143 struct cpuid_result result; 144 msr_t platform_info; 145 146 /* Minimum CPU revision */ 147 result = cpuid(1); 148 if (result.eax < IVB_CONFIG_TDP_MIN_CPUID) 149 return 0; 150 151 /* Bits 34:33 indicate how many levels supported */ 152 platform_info = msr_read(MSR_PLATFORM_INFO); 153 return (platform_info.hi >> 1) & 3; 154 } 155 156 /* 157 * Configure processor power limits if possible 158 * This must be done AFTER set of BIOS_RESET_CPL 159 */ 160 void set_power_limits(u8 power_limit_1_time) 161 { 162 msr_t msr = msr_read(MSR_PLATFORM_INFO); 163 msr_t limit; 164 unsigned power_unit; 165 unsigned tdp, min_power, max_power, max_time; 166 u8 power_limit_1_val; 167 168 if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr)) 169 return; 170 171 if (!(msr.lo & PLATFORM_INFO_SET_TDP)) 172 return; 173 174 /* Get units */ 175 msr = msr_read(MSR_PKG_POWER_SKU_UNIT); 176 power_unit = 2 << ((msr.lo & 0xf) - 1); 177 178 /* Get power defaults for this SKU */ 179 msr = msr_read(MSR_PKG_POWER_SKU); 180 tdp = msr.lo & 0x7fff; 181 min_power = (msr.lo >> 16) & 0x7fff; 182 max_power = msr.hi & 0x7fff; 183 max_time = (msr.hi >> 16) & 0x7f; 184 185 debug("CPU TDP: %u Watts\n", tdp / power_unit); 186 187 if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time) 188 power_limit_1_time = power_limit_time_msr_to_sec[max_time]; 189 190 if (min_power > 0 && tdp < min_power) 191 tdp = min_power; 192 193 if (max_power > 0 && tdp > max_power) 194 tdp = max_power; 195 196 power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time]; 197 198 /* Set long term power limit to TDP */ 199 limit.lo = 0; 200 limit.lo |= tdp & PKG_POWER_LIMIT_MASK; 201 limit.lo |= PKG_POWER_LIMIT_EN; 202 limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) << 203 PKG_POWER_LIMIT_TIME_SHIFT; 204 205 /* Set short term power limit to 1.25 * TDP */ 206 limit.hi = 0; 207 limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK; 208 limit.hi |= PKG_POWER_LIMIT_EN; 209 /* Power limit 2 time is only programmable on SNB EP/EX */ 210 211 msr_write(MSR_PKG_POWER_LIMIT, limit); 212 213 /* Use nominal TDP values for CPUs with configurable TDP */ 214 if (cpu_config_tdp_levels()) { 215 msr = msr_read(MSR_CONFIG_TDP_NOMINAL); 216 limit.hi = 0; 217 limit.lo = msr.lo & 0xff; 218 msr_write(MSR_TURBO_ACTIVATION_RATIO, limit); 219 } 220 } 221 222 static void configure_c_states(void) 223 { 224 struct cpuid_result result; 225 msr_t msr; 226 227 msr = msr_read(MSR_PMG_CST_CONFIG_CTL); 228 msr.lo |= (1 << 28); /* C1 Auto Undemotion Enable */ 229 msr.lo |= (1 << 27); /* C3 Auto Undemotion Enable */ 230 msr.lo |= (1 << 26); /* C1 Auto Demotion Enable */ 231 msr.lo |= (1 << 25); /* C3 Auto Demotion Enable */ 232 msr.lo &= ~(1 << 10); /* Disable IO MWAIT redirection */ 233 msr.lo |= 7; /* No package C-state limit */ 234 msr_write(MSR_PMG_CST_CONFIG_CTL, msr); 235 236 msr = msr_read(MSR_PMG_IO_CAPTURE_ADR); 237 msr.lo &= ~0x7ffff; 238 msr.lo |= (PMB0_BASE + 4); /* LVL_2 base address */ 239 msr.lo |= (2 << 16); /* CST Range: C7 is max C-state */ 240 msr_write(MSR_PMG_IO_CAPTURE_ADR, msr); 241 242 msr = msr_read(MSR_MISC_PWR_MGMT); 243 msr.lo &= ~(1 << 0); /* Enable P-state HW_ALL coordination */ 244 msr_write(MSR_MISC_PWR_MGMT, msr); 245 246 msr = msr_read(MSR_POWER_CTL); 247 msr.lo |= (1 << 18); /* Enable Energy Perf Bias MSR 0x1b0 */ 248 msr.lo |= (1 << 1); /* C1E Enable */ 249 msr.lo |= (1 << 0); /* Bi-directional PROCHOT# */ 250 msr_write(MSR_POWER_CTL, msr); 251 252 /* C3 Interrupt Response Time Limit */ 253 msr.hi = 0; 254 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x50; 255 msr_write(MSR_PKGC3_IRTL, msr); 256 257 /* C6 Interrupt Response Time Limit */ 258 msr.hi = 0; 259 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x68; 260 msr_write(MSR_PKGC6_IRTL, msr); 261 262 /* C7 Interrupt Response Time Limit */ 263 msr.hi = 0; 264 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x6D; 265 msr_write(MSR_PKGC7_IRTL, msr); 266 267 /* Primary Plane Current Limit */ 268 msr = msr_read(MSR_PP0_CURRENT_CONFIG); 269 msr.lo &= ~0x1fff; 270 msr.lo |= PP0_CURRENT_LIMIT; 271 msr_write(MSR_PP0_CURRENT_CONFIG, msr); 272 273 /* Secondary Plane Current Limit */ 274 msr = msr_read(MSR_PP1_CURRENT_CONFIG); 275 msr.lo &= ~0x1fff; 276 result = cpuid(1); 277 if (result.eax >= 0x30600) 278 msr.lo |= PP1_CURRENT_LIMIT_IVB; 279 else 280 msr.lo |= PP1_CURRENT_LIMIT_SNB; 281 msr_write(MSR_PP1_CURRENT_CONFIG, msr); 282 } 283 284 static int configure_thermal_target(struct udevice *dev) 285 { 286 int tcc_offset; 287 msr_t msr; 288 289 tcc_offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "tcc-offset", 290 0); 291 292 /* Set TCC activaiton offset if supported */ 293 msr = msr_read(MSR_PLATFORM_INFO); 294 if ((msr.lo & (1 << 30)) && tcc_offset) { 295 msr = msr_read(MSR_TEMPERATURE_TARGET); 296 msr.lo &= ~(0xf << 24); /* Bits 27:24 */ 297 msr.lo |= (tcc_offset & 0xf) << 24; 298 msr_write(MSR_TEMPERATURE_TARGET, msr); 299 } 300 301 return 0; 302 } 303 304 static void configure_misc(void) 305 { 306 msr_t msr; 307 308 msr = msr_read(IA32_MISC_ENABLE); 309 msr.lo |= (1 << 0); /* Fast String enable */ 310 msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ 311 msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */ 312 msr_write(IA32_MISC_ENABLE, msr); 313 314 /* Disable Thermal interrupts */ 315 msr.lo = 0; 316 msr.hi = 0; 317 msr_write(IA32_THERM_INTERRUPT, msr); 318 319 /* Enable package critical interrupt only */ 320 msr.lo = 1 << 4; 321 msr.hi = 0; 322 msr_write(IA32_PACKAGE_THERM_INTERRUPT, msr); 323 } 324 325 static void enable_lapic_tpr(void) 326 { 327 msr_t msr; 328 329 msr = msr_read(MSR_PIC_MSG_CONTROL); 330 msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */ 331 msr_write(MSR_PIC_MSG_CONTROL, msr); 332 } 333 334 static void configure_dca_cap(void) 335 { 336 struct cpuid_result cpuid_regs; 337 msr_t msr; 338 339 /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */ 340 cpuid_regs = cpuid(1); 341 if (cpuid_regs.ecx & (1 << 18)) { 342 msr = msr_read(IA32_PLATFORM_DCA_CAP); 343 msr.lo |= 1; 344 msr_write(IA32_PLATFORM_DCA_CAP, msr); 345 } 346 } 347 348 static void set_max_ratio(void) 349 { 350 msr_t msr, perf_ctl; 351 352 perf_ctl.hi = 0; 353 354 /* Check for configurable TDP option */ 355 if (cpu_config_tdp_levels()) { 356 /* Set to nominal TDP ratio */ 357 msr = msr_read(MSR_CONFIG_TDP_NOMINAL); 358 perf_ctl.lo = (msr.lo & 0xff) << 8; 359 } else { 360 /* Platform Info bits 15:8 give max ratio */ 361 msr = msr_read(MSR_PLATFORM_INFO); 362 perf_ctl.lo = msr.lo & 0xff00; 363 } 364 msr_write(MSR_IA32_PERF_CTL, perf_ctl); 365 366 debug("model_x06ax: frequency set to %d\n", 367 ((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK); 368 } 369 370 static void set_energy_perf_bias(u8 policy) 371 { 372 msr_t msr; 373 374 /* Energy Policy is bits 3:0 */ 375 msr = msr_read(IA32_ENERGY_PERFORMANCE_BIAS); 376 msr.lo &= ~0xf; 377 msr.lo |= policy & 0xf; 378 msr_write(IA32_ENERGY_PERFORMANCE_BIAS, msr); 379 380 debug("model_x06ax: energy policy set to %u\n", policy); 381 } 382 383 static void configure_mca(void) 384 { 385 msr_t msr; 386 int i; 387 388 msr.lo = 0; 389 msr.hi = 0; 390 /* This should only be done on a cold boot */ 391 for (i = 0; i < 7; i++) 392 msr_write(IA32_MC0_STATUS + (i * 4), msr); 393 } 394 395 #if CONFIG_USBDEBUG 396 static unsigned ehci_debug_addr; 397 #endif 398 399 static int model_206ax_init(struct udevice *dev) 400 { 401 int ret; 402 403 /* Clear out pending MCEs */ 404 configure_mca(); 405 406 #if CONFIG_USBDEBUG 407 /* Is this caution really needed? */ 408 if (!ehci_debug_addr) 409 ehci_debug_addr = get_ehci_debug(); 410 set_ehci_debug(0); 411 #endif 412 413 #if CONFIG_USBDEBUG 414 set_ehci_debug(ehci_debug_addr); 415 #endif 416 417 /* Enable the local cpu apics */ 418 enable_lapic_tpr(); 419 420 /* Enable virtualization if enabled in CMOS */ 421 enable_vmx(); 422 423 /* Configure C States */ 424 configure_c_states(); 425 426 /* Configure Enhanced SpeedStep and Thermal Sensors */ 427 configure_misc(); 428 429 /* Thermal throttle activation offset */ 430 ret = configure_thermal_target(dev); 431 if (ret) { 432 debug("Cannot set thermal target\n"); 433 return ret; 434 } 435 436 /* Enable Direct Cache Access */ 437 configure_dca_cap(); 438 439 /* Set energy policy */ 440 set_energy_perf_bias(ENERGY_POLICY_NORMAL); 441 442 /* Set Max Ratio */ 443 set_max_ratio(); 444 445 /* Enable Turbo */ 446 turbo_enable(); 447 448 return 0; 449 } 450 451 static int model_206ax_get_info(struct udevice *dev, struct cpu_info *info) 452 { 453 msr_t msr; 454 455 msr = msr_read(MSR_IA32_PERF_CTL); 456 info->cpu_freq = ((msr.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK * 1000000; 457 info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU | 458 1 << CPU_FEAT_UCODE; 459 460 return 0; 461 } 462 463 static int model_206ax_get_count(struct udevice *dev) 464 { 465 return 4; 466 } 467 468 static int cpu_x86_model_206ax_probe(struct udevice *dev) 469 { 470 if (dev->seq == 0) 471 model_206ax_init(dev); 472 473 return 0; 474 } 475 476 static const struct cpu_ops cpu_x86_model_206ax_ops = { 477 .get_desc = cpu_x86_get_desc, 478 .get_info = model_206ax_get_info, 479 .get_count = model_206ax_get_count, 480 .get_vendor = cpu_x86_get_vendor, 481 }; 482 483 static const struct udevice_id cpu_x86_model_206ax_ids[] = { 484 { .compatible = "intel,core-gen3" }, 485 { } 486 }; 487 488 U_BOOT_DRIVER(cpu_x86_model_206ax_drv) = { 489 .name = "cpu_x86_model_206ax", 490 .id = UCLASS_CPU, 491 .of_match = cpu_x86_model_206ax_ids, 492 .bind = cpu_x86_bind, 493 .probe = cpu_x86_model_206ax_probe, 494 .ops = &cpu_x86_model_206ax_ops, 495 }; 496