model_206ax.c 12 KB

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