uboot/arch/x86/cpu/intel_common/cpu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2014 Google Inc.
   4 * Copyright (c) 2016 Google, Inc
   5 * Copyright (C) 2015-2018 Intel Corporation.
   6 * Copyright (C) 2018 Siemens AG
   7 * Some code taken from coreboot cpulib.c
   8 */
   9
  10#include <common.h>
  11#include <cpu.h>
  12#include <dm.h>
  13#include <errno.h>
  14#include <log.h>
  15#include <acpi/acpigen.h>
  16#include <asm/cpu.h>
  17#include <asm/cpu_common.h>
  18#include <asm/global_data.h>
  19#include <asm/intel_regs.h>
  20#include <asm/lapic.h>
  21#include <asm/lpc_common.h>
  22#include <asm/msr.h>
  23#include <asm/mtrr.h>
  24#include <asm/post.h>
  25#include <asm/microcode.h>
  26
  27DECLARE_GLOBAL_DATA_PTR;
  28
  29static int report_bist_failure(void)
  30{
  31        if (gd->arch.bist != 0) {
  32                post_code(POST_BIST_FAILURE);
  33                printf("BIST failed: %08x\n", gd->arch.bist);
  34                return -EFAULT;
  35        }
  36
  37        return 0;
  38}
  39
  40int cpu_common_init(void)
  41{
  42        struct udevice *dev, *lpc;
  43        int ret;
  44
  45        /* Halt if there was a built in self test failure */
  46        ret = report_bist_failure();
  47        if (ret)
  48                return ret;
  49
  50        enable_lapic();
  51
  52        ret = microcode_update_intel();
  53        if (ret && ret != -EEXIST) {
  54                debug("%s: Microcode update failure (err=%d)\n", __func__, ret);
  55                return ret;
  56        }
  57
  58        /* Enable upper 128bytes of CMOS */
  59        writel(1 << 2, RCB_REG(RC));
  60
  61        /* Early chipset init required before RAM init can work */
  62        uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
  63
  64        ret = uclass_first_device(UCLASS_LPC, &lpc);
  65        if (ret)
  66                return ret;
  67        if (!lpc)
  68                return -ENODEV;
  69
  70        /* Cause the SATA device to do its early init */
  71        uclass_first_device(UCLASS_AHCI, &dev);
  72
  73        return 0;
  74}
  75
  76int cpu_set_flex_ratio_to_tdp_nominal(void)
  77{
  78        msr_t flex_ratio, msr;
  79        u8 nominal_ratio;
  80
  81        /* Check for Flex Ratio support */
  82        flex_ratio = msr_read(MSR_FLEX_RATIO);
  83        if (!(flex_ratio.lo & FLEX_RATIO_EN))
  84                return -EINVAL;
  85
  86        /* Check for >0 configurable TDPs */
  87        msr = msr_read(MSR_PLATFORM_INFO);
  88        if (((msr.hi >> 1) & 3) == 0)
  89                return -EINVAL;
  90
  91        /* Use nominal TDP ratio for flex ratio */
  92        msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
  93        nominal_ratio = msr.lo & 0xff;
  94
  95        /* See if flex ratio is already set to nominal TDP ratio */
  96        if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
  97                return 0;
  98
  99        /* Set flex ratio to nominal TDP ratio */
 100        flex_ratio.lo &= ~0xff00;
 101        flex_ratio.lo |= nominal_ratio << 8;
 102        flex_ratio.lo |= FLEX_RATIO_LOCK;
 103        msr_write(MSR_FLEX_RATIO, flex_ratio);
 104
 105        /* Set flex ratio in soft reset data register bits 11:6 */
 106        clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
 107                        (nominal_ratio & 0x3f) << 6);
 108
 109        debug("CPU: Soft reset to set up flex ratio\n");
 110
 111        /* Set soft reset control to use register value */
 112        setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
 113
 114        /* Issue warm reset, will be "CPU only" due to soft reset data */
 115        outb(0x0, IO_PORT_RESET);
 116        outb(SYS_RST | RST_CPU, IO_PORT_RESET);
 117        cpu_hlt();
 118
 119        /* Not reached */
 120        return -EINVAL;
 121}
 122
 123int cpu_intel_get_info(struct cpu_info *info, int bclk)
 124{
 125        msr_t msr;
 126
 127        msr = msr_read(MSR_IA32_PERF_CTL);
 128        info->cpu_freq = ((msr.lo >> 8) & 0xff) * bclk * 1000000;
 129        info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU |
 130                1 << CPU_FEAT_UCODE | 1 << CPU_FEAT_DEVICE_ID;
 131        info->address_width = cpu_phys_address_size();
 132
 133        return 0;
 134}
 135
 136int cpu_configure_thermal_target(struct udevice *dev)
 137{
 138        u32 tcc_offset;
 139        msr_t msr;
 140        int ret;
 141
 142        ret = dev_read_u32(dev, "tcc-offset", &tcc_offset);
 143        if (!ret)
 144                return -ENOENT;
 145
 146        /* Set TCC activaiton offset if supported */
 147        msr = msr_read(MSR_PLATFORM_INFO);
 148        if (msr.lo & (1 << 30)) {
 149                msr = msr_read(MSR_TEMPERATURE_TARGET);
 150                msr.lo &= ~(0xf << 24); /* Bits 27:24 */
 151                msr.lo |= (tcc_offset & 0xf) << 24;
 152                msr_write(MSR_TEMPERATURE_TARGET, msr);
 153        }
 154
 155        return 0;
 156}
 157
 158void cpu_set_perf_control(uint clk_ratio)
 159{
 160        msr_t perf_ctl;
 161
 162        perf_ctl.lo = (clk_ratio & 0xff) << 8;
 163        perf_ctl.hi = 0;
 164        msr_write(MSR_IA32_PERF_CTL, perf_ctl);
 165        debug("CPU: frequency set to %d MHz\n", clk_ratio * INTEL_BCLK_MHZ);
 166}
 167
 168bool cpu_config_tdp_levels(void)
 169{
 170        msr_t platform_info;
 171
 172        /* Bits 34:33 indicate how many levels supported */
 173        platform_info = msr_read(MSR_PLATFORM_INFO);
 174
 175        return ((platform_info.hi >> 1) & 3) != 0;
 176}
 177
 178void cpu_set_p_state_to_turbo_ratio(void)
 179{
 180        msr_t msr;
 181
 182        msr = msr_read(MSR_TURBO_RATIO_LIMIT);
 183        cpu_set_perf_control(msr.lo);
 184}
 185
 186enum burst_mode_t cpu_get_burst_mode_state(void)
 187{
 188        enum burst_mode_t state;
 189        int burst_en, burst_cap;
 190        msr_t msr;
 191        uint eax;
 192
 193        eax = cpuid_eax(0x6);
 194        burst_cap = eax & 0x2;
 195        msr = msr_read(MSR_IA32_MISC_ENABLE);
 196        burst_en = !(msr.hi & BURST_MODE_DISABLE);
 197
 198        if (!burst_cap && burst_en)
 199                state = BURST_MODE_UNAVAILABLE;
 200        else if (burst_cap && !burst_en)
 201                state = BURST_MODE_DISABLED;
 202        else if (burst_cap && burst_en)
 203                state = BURST_MODE_ENABLED;
 204        else
 205                state = BURST_MODE_UNKNOWN;
 206
 207        return state;
 208}
 209
 210void cpu_set_burst_mode(bool burst_mode)
 211{
 212        msr_t msr;
 213
 214        msr = msr_read(MSR_IA32_MISC_ENABLE);
 215        if (burst_mode)
 216                msr.hi &= ~BURST_MODE_DISABLE;
 217        else
 218                msr.hi |= BURST_MODE_DISABLE;
 219        msr_write(MSR_IA32_MISC_ENABLE, msr);
 220}
 221
 222void cpu_set_eist(bool eist_status)
 223{
 224        msr_t msr;
 225
 226        msr = msr_read(MSR_IA32_MISC_ENABLE);
 227        if (eist_status)
 228                msr.lo |= MISC_ENABLE_ENHANCED_SPEEDSTEP;
 229        else
 230                msr.lo &= ~MISC_ENABLE_ENHANCED_SPEEDSTEP;
 231        msr_write(MSR_IA32_MISC_ENABLE, msr);
 232}
 233
 234int cpu_get_coord_type(void)
 235{
 236        return HW_ALL;
 237}
 238
 239int cpu_get_min_ratio(void)
 240{
 241        msr_t msr;
 242
 243        /* Get bus ratio limits and calculate clock speeds */
 244        msr = msr_read(MSR_PLATFORM_INFO);
 245
 246        return (msr.hi >> 8) & 0xff;    /* Max Efficiency Ratio */
 247}
 248
 249int cpu_get_max_ratio(void)
 250{
 251        u32 ratio_max;
 252        msr_t msr;
 253
 254        if (cpu_config_tdp_levels()) {
 255                /* Set max ratio to nominal TDP ratio */
 256                msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
 257                ratio_max = msr.lo & 0xff;
 258        } else {
 259                msr = msr_read(MSR_PLATFORM_INFO);
 260                /* Max Non-Turbo Ratio */
 261                ratio_max = (msr.lo >> 8) & 0xff;
 262        }
 263
 264        return ratio_max;
 265}
 266
 267int cpu_get_bus_clock_khz(void)
 268{
 269        /*
 270         * CPU bus clock is set by default here to 100MHz. This function returns
 271         * the bus clock in KHz.
 272         */
 273        return INTEL_BCLK_MHZ * 1000;
 274}
 275
 276int cpu_get_power_max(void)
 277{
 278        int power_unit;
 279        msr_t msr;
 280
 281        msr = msr_read(MSR_PKG_POWER_SKU_UNIT);
 282        power_unit = 2 << ((msr.lo & 0xf) - 1);
 283        msr = msr_read(MSR_PKG_POWER_SKU);
 284
 285        return (msr.lo & 0x7fff) * 1000 / power_unit;
 286}
 287
 288int cpu_get_max_turbo_ratio(void)
 289{
 290        msr_t msr;
 291
 292        msr = msr_read(MSR_TURBO_RATIO_LIMIT);
 293
 294        return msr.lo & 0xff;
 295}
 296
 297int cpu_get_cores_per_package(void)
 298{
 299        struct cpuid_result result;
 300        int cores = 1;
 301
 302        if (gd->arch.x86_vendor != X86_VENDOR_INTEL)
 303                return 1;
 304
 305        result = cpuid_ext(0xb, 1);
 306        cores = result.ebx & 0xff;
 307
 308        return cores;
 309}
 310
 311void cpu_mca_configure(void)
 312{
 313        msr_t msr;
 314        int i;
 315        int num_banks;
 316
 317        msr = msr_read(MSR_IA32_MCG_CAP);
 318        num_banks = msr.lo & 0xff;
 319        msr.lo = 0;
 320        msr.hi = 0;
 321        for (i = 0; i < num_banks; i++) {
 322                /* Clear the machine check status */
 323                msr_write(MSR_IA32_MC0_STATUS + (i * 4), msr);
 324                /* Initialise machine checks */
 325                msr_write(MSR_IA32_MC0_CTL + i * 4,
 326                          (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff});
 327        }
 328}
 329