uboot/arch/x86/cpu/turbo.c
<<
>>
Prefs
   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
   8#include <common.h>
   9#include <log.h>
  10#include <asm/cpu.h>
  11#include <asm/global_data.h>
  12#include <asm/msr.h>
  13#include <asm/processor.h>
  14#include <asm/turbo.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18#ifdef CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
  19static inline int get_global_turbo_state(void)
  20{
  21        return TURBO_UNKNOWN;
  22}
  23
  24static inline void set_global_turbo_state(int state)
  25{
  26}
  27#else
  28static inline int get_global_turbo_state(void)
  29{
  30        return gd->arch.turbo_state;
  31}
  32
  33static inline void set_global_turbo_state(int state)
  34{
  35        gd->arch.turbo_state = state;
  36}
  37#endif
  38
  39/* gcc 7.3 does not wwant to drop strings, so use #ifdef */
  40#ifndef CONFIG_TPL_BUILD
  41static const char *const turbo_state_desc[] = {
  42        [TURBO_UNKNOWN]         = "unknown",
  43        [TURBO_UNAVAILABLE]     = "unavailable",
  44        [TURBO_DISABLED]        = "available but hidden",
  45        [TURBO_ENABLED]         = "available and visible"
  46};
  47#endif
  48
  49/*
  50 * Determine the current state of Turbo and cache it for later.
  51 * Turbo is a package level config so it does not need to be
  52 * enabled on every core.
  53 */
  54int turbo_get_state(void)
  55{
  56        struct cpuid_result cpuid_regs;
  57        int turbo_en, turbo_cap;
  58        msr_t msr;
  59        int turbo_state = get_global_turbo_state();
  60
  61        /* Return cached state if available */
  62        if (turbo_state != TURBO_UNKNOWN)
  63                return turbo_state;
  64
  65        cpuid_regs = cpuid(CPUID_LEAF_PM);
  66        turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE);
  67
  68        msr = msr_read(MSR_IA32_MISC_ENABLE);
  69        turbo_en = !(msr.hi & MISC_DISABLE_TURBO);
  70
  71        if (!turbo_cap && turbo_en) {
  72                /* Unavailable */
  73                turbo_state = TURBO_UNAVAILABLE;
  74        } else if (!turbo_cap && !turbo_en) {
  75                /* Available but disabled */
  76                turbo_state = TURBO_DISABLED;
  77        } else if (turbo_cap && turbo_en) {
  78                /* Available */
  79                turbo_state = TURBO_ENABLED;
  80        }
  81
  82        set_global_turbo_state(turbo_state);
  83#ifndef CONFIG_TPL_BUILD
  84        debug("Turbo is %s\n", turbo_state_desc[turbo_state]);
  85#endif
  86        return turbo_state;
  87}
  88
  89void turbo_enable(void)
  90{
  91        msr_t msr;
  92
  93        /* Only possible if turbo is available but hidden */
  94        if (turbo_get_state() == TURBO_DISABLED) {
  95                /* Clear Turbo Disable bit in Misc Enables */
  96                msr = msr_read(MSR_IA32_MISC_ENABLE);
  97                msr.hi &= ~MISC_DISABLE_TURBO;
  98                msr_write(MSR_IA32_MISC_ENABLE, msr);
  99
 100                /* Update cached turbo state */
 101                set_global_turbo_state(TURBO_ENABLED);
 102                debug("Turbo has been enabled\n");
 103        }
 104}
 105