turbo.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * From Coreboot file of the same name
  4. *
  5. * Copyright (C) 2011 The Chromium Authors.
  6. */
  7. #include <common.h>
  8. #include <asm/cpu.h>
  9. #include <asm/msr.h>
  10. #include <asm/processor.h>
  11. #include <asm/turbo.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. #ifdef CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
  14. static inline int get_global_turbo_state(void)
  15. {
  16. return TURBO_UNKNOWN;
  17. }
  18. static inline void set_global_turbo_state(int state)
  19. {
  20. }
  21. #else
  22. static inline int get_global_turbo_state(void)
  23. {
  24. return gd->arch.turbo_state;
  25. }
  26. static inline void set_global_turbo_state(int state)
  27. {
  28. gd->arch.turbo_state = state;
  29. }
  30. #endif
  31. static const char *const turbo_state_desc[] = {
  32. [TURBO_UNKNOWN] = "unknown",
  33. [TURBO_UNAVAILABLE] = "unavailable",
  34. [TURBO_DISABLED] = "available but hidden",
  35. [TURBO_ENABLED] = "available and visible"
  36. };
  37. /*
  38. * Determine the current state of Turbo and cache it for later.
  39. * Turbo is a package level config so it does not need to be
  40. * enabled on every core.
  41. */
  42. int turbo_get_state(void)
  43. {
  44. struct cpuid_result cpuid_regs;
  45. int turbo_en, turbo_cap;
  46. msr_t msr;
  47. int turbo_state = get_global_turbo_state();
  48. /* Return cached state if available */
  49. if (turbo_state != TURBO_UNKNOWN)
  50. return turbo_state;
  51. cpuid_regs = cpuid(CPUID_LEAF_PM);
  52. turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE);
  53. msr = msr_read(MSR_IA32_MISC_ENABLES);
  54. turbo_en = !(msr.hi & H_MISC_DISABLE_TURBO);
  55. if (!turbo_cap && turbo_en) {
  56. /* Unavailable */
  57. turbo_state = TURBO_UNAVAILABLE;
  58. } else if (!turbo_cap && !turbo_en) {
  59. /* Available but disabled */
  60. turbo_state = TURBO_DISABLED;
  61. } else if (turbo_cap && turbo_en) {
  62. /* Available */
  63. turbo_state = TURBO_ENABLED;
  64. }
  65. set_global_turbo_state(turbo_state);
  66. debug("Turbo is %s\n", turbo_state_desc[turbo_state]);
  67. return turbo_state;
  68. }
  69. void turbo_enable(void)
  70. {
  71. msr_t msr;
  72. /* Only possible if turbo is available but hidden */
  73. if (turbo_get_state() == TURBO_DISABLED) {
  74. /* Clear Turbo Disable bit in Misc Enables */
  75. msr = msr_read(MSR_IA32_MISC_ENABLES);
  76. msr.hi &= ~H_MISC_DISABLE_TURBO;
  77. msr_write(MSR_IA32_MISC_ENABLES, msr);
  78. /* Update cached turbo state */
  79. set_global_turbo_state(TURBO_ENABLED);
  80. debug("Turbo has been enabled\n");
  81. }
  82. }