x86: Move common CPU code to its own place
Some of the Intel CPU code is common to several Intel CPUs. Move it into a common location along with required declarations. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
parent
8c30b57130
commit
50dd3da004
@ -5,6 +5,7 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_HAVE_MRC) += car.o
|
||||
obj-y += cpu.o
|
||||
obj-y += lpc.o
|
||||
ifndef CONFIG_TARGET_EFI
|
||||
obj-y += microcode.o
|
||||
|
111
arch/x86/cpu/intel_common/cpu.c
Normal file
111
arch/x86/cpu/intel_common/cpu.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <asm/cpu_common.h>
|
||||
#include <asm/intel_regs.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <asm/lpc_common.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/post.h>
|
||||
#include <asm/microcode.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int report_bist_failure(void)
|
||||
{
|
||||
if (gd->arch.bist != 0) {
|
||||
post_code(POST_BIST_FAILURE);
|
||||
printf("BIST failed: %08x\n", gd->arch.bist);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_common_init(void)
|
||||
{
|
||||
struct udevice *dev, *lpc;
|
||||
int ret;
|
||||
|
||||
/* Halt if there was a built in self test failure */
|
||||
ret = report_bist_failure();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
enable_lapic();
|
||||
|
||||
ret = microcode_update_intel();
|
||||
if (ret && ret != -EEXIST)
|
||||
return ret;
|
||||
|
||||
/* Enable upper 128bytes of CMOS */
|
||||
writel(1 << 2, RCB_REG(RC));
|
||||
|
||||
/* Early chipset init required before RAM init can work */
|
||||
uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
|
||||
|
||||
ret = uclass_first_device(UCLASS_LPC, &lpc);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!lpc)
|
||||
return -ENODEV;
|
||||
|
||||
/* Cause the SATA device to do its early init */
|
||||
uclass_first_device(UCLASS_DISK, &dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_set_flex_ratio_to_tdp_nominal(void)
|
||||
{
|
||||
msr_t flex_ratio, msr;
|
||||
u8 nominal_ratio;
|
||||
|
||||
/* Check for Flex Ratio support */
|
||||
flex_ratio = msr_read(MSR_FLEX_RATIO);
|
||||
if (!(flex_ratio.lo & FLEX_RATIO_EN))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check for >0 configurable TDPs */
|
||||
msr = msr_read(MSR_PLATFORM_INFO);
|
||||
if (((msr.hi >> 1) & 3) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Use nominal TDP ratio for flex ratio */
|
||||
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
|
||||
nominal_ratio = msr.lo & 0xff;
|
||||
|
||||
/* See if flex ratio is already set to nominal TDP ratio */
|
||||
if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
|
||||
return 0;
|
||||
|
||||
/* Set flex ratio to nominal TDP ratio */
|
||||
flex_ratio.lo &= ~0xff00;
|
||||
flex_ratio.lo |= nominal_ratio << 8;
|
||||
flex_ratio.lo |= FLEX_RATIO_LOCK;
|
||||
msr_write(MSR_FLEX_RATIO, flex_ratio);
|
||||
|
||||
/* Set flex ratio in soft reset data register bits 11:6 */
|
||||
clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
|
||||
(nominal_ratio & 0x3f) << 6);
|
||||
|
||||
debug("CPU: Soft reset to set up flex ratio\n");
|
||||
|
||||
/* Set soft reset control to use register value */
|
||||
setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
|
||||
|
||||
/* Issue warm reset, will be "CPU only" due to soft reset data */
|
||||
outb(0x0, PORT_RESET);
|
||||
outb(SYS_RST | RST_CPU, PORT_RESET);
|
||||
cpu_hlt();
|
||||
|
||||
/* Not reached */
|
||||
return -EINVAL;
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
#include <fdtdec.h>
|
||||
#include <pch.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu_common.h>
|
||||
#include <asm/intel_regs.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/lapic.h>
|
||||
@ -34,51 +35,11 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int set_flex_ratio_to_tdp_nominal(void)
|
||||
{
|
||||
msr_t flex_ratio, msr;
|
||||
u8 nominal_ratio;
|
||||
|
||||
/* Minimum CPU revision for configurable TDP support */
|
||||
if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check for Flex Ratio support */
|
||||
flex_ratio = msr_read(MSR_FLEX_RATIO);
|
||||
if (!(flex_ratio.lo & FLEX_RATIO_EN))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check for >0 configurable TDPs */
|
||||
msr = msr_read(MSR_PLATFORM_INFO);
|
||||
if (((msr.hi >> 1) & 3) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Use nominal TDP ratio for flex ratio */
|
||||
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
|
||||
nominal_ratio = msr.lo & 0xff;
|
||||
|
||||
/* See if flex ratio is already set to nominal TDP ratio */
|
||||
if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
|
||||
return 0;
|
||||
|
||||
/* Set flex ratio to nominal TDP ratio */
|
||||
flex_ratio.lo &= ~0xff00;
|
||||
flex_ratio.lo |= nominal_ratio << 8;
|
||||
flex_ratio.lo |= FLEX_RATIO_LOCK;
|
||||
msr_write(MSR_FLEX_RATIO, flex_ratio);
|
||||
|
||||
/* Set flex ratio in soft reset data register bits 11:6 */
|
||||
clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
|
||||
(nominal_ratio & 0x3f) << 6);
|
||||
|
||||
/* Set soft reset control to use register value */
|
||||
setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
|
||||
|
||||
/* Issue warm reset, will be "CPU only" due to soft reset data */
|
||||
outb(0x0, PORT_RESET);
|
||||
outb(SYS_RST | RST_CPU, PORT_RESET);
|
||||
cpu_hlt();
|
||||
|
||||
/* Not reached */
|
||||
return -EINVAL;
|
||||
return cpu_set_flex_ratio_to_tdp_nominal();
|
||||
}
|
||||
|
||||
int arch_cpu_init(void)
|
||||
@ -163,17 +124,6 @@ static void enable_usb_bar(struct udevice *bus)
|
||||
pci_bus_write_config(bus, usb3, PCI_COMMAND, cmd, PCI_SIZE_32);
|
||||
}
|
||||
|
||||
static int report_bist_failure(void)
|
||||
{
|
||||
if (gd->arch.bist != 0) {
|
||||
post_code(POST_BIST_FAILURE);
|
||||
printf("BIST failed: %08x\n", gd->arch.bist);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE;
|
||||
@ -184,20 +134,6 @@ int print_cpuinfo(void)
|
||||
uint16_t pm1_sts;
|
||||
int ret;
|
||||
|
||||
/* Halt if there was a built in self test failure */
|
||||
ret = report_bist_failure();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
enable_lapic();
|
||||
|
||||
ret = microcode_update_intel();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable upper 128bytes of CMOS */
|
||||
writel(1 << 2, RCB_REG(RC));
|
||||
|
||||
/* TODO: cmos_post_init() */
|
||||
if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) {
|
||||
debug("soft reset detected\n");
|
||||
@ -208,16 +144,10 @@ int print_cpuinfo(void)
|
||||
reset_cpu(0);
|
||||
}
|
||||
|
||||
/* Early chipset init required before RAM init can work */
|
||||
uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_LPC, &lpc);
|
||||
ret = cpu_common_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Cause the SATA device to do its early init */
|
||||
uclass_first_device(UCLASS_DISK, &dev);
|
||||
|
||||
/* Check PM1_STS[15] to see if we are waking from Sx */
|
||||
pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
|
||||
|
||||
@ -240,8 +170,10 @@ int print_cpuinfo(void)
|
||||
return ret;
|
||||
|
||||
/* Prepare USB controller early in S3 resume */
|
||||
if (boot_mode == PEI_BOOT_RESUME)
|
||||
if (boot_mode == PEI_BOOT_RESUME) {
|
||||
uclass_first_device(UCLASS_LPC, &lpc);
|
||||
enable_usb_bar(pci_get_controller(lpc->parent));
|
||||
}
|
||||
|
||||
gd->arch.pei_boot_mode = boot_mode;
|
||||
|
||||
|
@ -332,8 +332,6 @@
|
||||
#define SPI_FREQ_SWSEQ 0x3893
|
||||
#define SPI_DESC_COMP0 0x38b0
|
||||
#define SPI_FREQ_WR_ERA 0x38b4
|
||||
#define SOFT_RESET_CTRL 0x38f4
|
||||
#define SOFT_RESET_DATA 0x38f8
|
||||
|
||||
#define DIR_ROUTE(a, b, c, d) \
|
||||
(((d) << DIR_IDR) | ((c) << DIR_ICR) | \
|
||||
|
35
arch/x86/include/asm/cpu_common.h
Normal file
35
arch/x86/include/asm/cpu_common.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ASM_CPU_COMMON_H
|
||||
#define __ASM_CPU_COMMON_H
|
||||
|
||||
#define IA32_PERF_CTL 0x199
|
||||
|
||||
/**
|
||||
* cpu_common_init() - Set up common CPU init
|
||||
*
|
||||
* This reports BIST failure, enables the LAPIC, updates microcode, enables
|
||||
* the upper 128-bytes of CROM RAM, probes the northbridge, PCH, LPC and SATA.
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cpu_common_init(void);
|
||||
|
||||
/**
|
||||
* cpu_set_flex_ratio_to_tdp_nominal() - Set up the maximum non-turbo rate
|
||||
*
|
||||
* If a change is needed, this function will do a soft reset so it takes
|
||||
* effect.
|
||||
*
|
||||
* Some details are available here:
|
||||
* http://forum.hwbot.org/showthread.php?t=76092
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cpu_set_flex_ratio_to_tdp_nominal(void);
|
||||
|
||||
#endif
|
@ -12,8 +12,17 @@
|
||||
#define MCH_BASE_SIZE 0x8000
|
||||
#define MCHBAR_REG(reg) (MCH_BASE_ADDRESS + (reg))
|
||||
|
||||
#define MCHBAR_PEI_VERSION 0x5034
|
||||
#define MCH_PKG_POWER_LIMIT_LO 0x59a0
|
||||
#define MCH_PKG_POWER_LIMIT_HI 0x59a4
|
||||
#define MCH_DDR_POWER_LIMIT_LO 0x58e0
|
||||
#define MCH_DDR_POWER_LIMIT_HI 0x58e4
|
||||
|
||||
/* Access the Root Complex Register Block */
|
||||
#define RCB_BASE_ADDRESS 0xfed1c000
|
||||
#define RCB_REG(reg) (RCB_BASE_ADDRESS + (reg))
|
||||
|
||||
#define SOFT_RESET_CTRL 0x38f4
|
||||
#define SOFT_RESET_DATA 0x38f8
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user