uboot/arch/x86/cpu/intel_common/cpu.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016 Google, Inc
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0
   5 */
   6
   7#include <common.h>
   8#include <dm.h>
   9#include <errno.h>
  10#include <asm/cpu_common.h>
  11#include <asm/intel_regs.h>
  12#include <asm/lapic.h>
  13#include <asm/lpc_common.h>
  14#include <asm/msr.h>
  15#include <asm/mtrr.h>
  16#include <asm/post.h>
  17#include <asm/microcode.h>
  18
  19DECLARE_GLOBAL_DATA_PTR;
  20
  21static int report_bist_failure(void)
  22{
  23        if (gd->arch.bist != 0) {
  24                post_code(POST_BIST_FAILURE);
  25                printf("BIST failed: %08x\n", gd->arch.bist);
  26                return -EFAULT;
  27        }
  28
  29        return 0;
  30}
  31
  32int cpu_common_init(void)
  33{
  34        struct udevice *dev, *lpc;
  35        int ret;
  36
  37        /* Halt if there was a built in self test failure */
  38        ret = report_bist_failure();
  39        if (ret)
  40                return ret;
  41
  42        enable_lapic();
  43
  44        ret = microcode_update_intel();
  45        if (ret && ret != -EEXIST) {
  46                debug("%s: Microcode update failure (err=%d)\n", __func__, ret);
  47                return ret;
  48        }
  49
  50        /* Enable upper 128bytes of CMOS */
  51        writel(1 << 2, RCB_REG(RC));
  52
  53        /* Early chipset init required before RAM init can work */
  54        uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
  55
  56        ret = uclass_first_device(UCLASS_LPC, &lpc);
  57        if (ret)
  58                return ret;
  59        if (!lpc)
  60                return -ENODEV;
  61
  62        /* Cause the SATA device to do its early init */
  63        uclass_first_device(UCLASS_AHCI, &dev);
  64
  65        return 0;
  66}
  67
  68int cpu_set_flex_ratio_to_tdp_nominal(void)
  69{
  70        msr_t flex_ratio, msr;
  71        u8 nominal_ratio;
  72
  73        /* Check for Flex Ratio support */
  74        flex_ratio = msr_read(MSR_FLEX_RATIO);
  75        if (!(flex_ratio.lo & FLEX_RATIO_EN))
  76                return -EINVAL;
  77
  78        /* Check for >0 configurable TDPs */
  79        msr = msr_read(MSR_PLATFORM_INFO);
  80        if (((msr.hi >> 1) & 3) == 0)
  81                return -EINVAL;
  82
  83        /* Use nominal TDP ratio for flex ratio */
  84        msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
  85        nominal_ratio = msr.lo & 0xff;
  86
  87        /* See if flex ratio is already set to nominal TDP ratio */
  88        if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
  89                return 0;
  90
  91        /* Set flex ratio to nominal TDP ratio */
  92        flex_ratio.lo &= ~0xff00;
  93        flex_ratio.lo |= nominal_ratio << 8;
  94        flex_ratio.lo |= FLEX_RATIO_LOCK;
  95        msr_write(MSR_FLEX_RATIO, flex_ratio);
  96
  97        /* Set flex ratio in soft reset data register bits 11:6 */
  98        clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
  99                        (nominal_ratio & 0x3f) << 6);
 100
 101        debug("CPU: Soft reset to set up flex ratio\n");
 102
 103        /* Set soft reset control to use register value */
 104        setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
 105
 106        /* Issue warm reset, will be "CPU only" due to soft reset data */
 107        outb(0x0, IO_PORT_RESET);
 108        outb(SYS_RST | RST_CPU, IO_PORT_RESET);
 109        cpu_hlt();
 110
 111        /* Not reached */
 112        return -EINVAL;
 113}
 114