turbo.c 2.2 KB

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