Andrey Petrov has uploaded this change for review. ( https://review.coreboot.org/20066
Change subject: soc/intel/cannonlake: Add early CPU initialization ......................................................................
soc/intel/cannonlake: Add early CPU initialization
Add basic CPU initialization for bootblock, as well as relevant headers.
Change-Id: I318b7ea0f3aa5b5d28bf70784ccd20f2fe28cd86 Signed-off-by: Andrey Petrov andrey.petrov@intel.com --- A src/soc/intel/cannonlake/bootblock/cpu.c A src/soc/intel/cannonlake/include/soc/cpu.h A src/soc/intel/cannonlake/include/soc/msr.h 3 files changed, 280 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/20066/1
diff --git a/src/soc/intel/cannonlake/bootblock/cpu.c b/src/soc/intel/cannonlake/bootblock/cpu.c new file mode 100644 index 0000000..844d9a7 --- /dev/null +++ b/src/soc/intel/cannonlake/bootblock/cpu.c @@ -0,0 +1,156 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <console/console.h> +#include <cpu/intel/microcode/microcode.c> +#include <cpu/x86/mtrr.h> +#include <delay.h> +#include <lib.h> +#include <reset.h> +#include <soc/bootblock.h> +#include <soc/cpu.h> +#include <soc/iomap.h> +#include <soc/msr.h> +#include <soc/pmc.h> + +/* Soft Reset Data Register Bit 12 = MAX Boot Frequency */ +#define SPI_STRAP_MAX_FREQ (1<<12) +/* Soft Reset Data Register Bit 6-11 = Flex Ratio */ +#define FLEX_RATIO_BIT 6 + +static void set_pch_cpu_strap(u8 flex_ratio) +{ + u32 soft_reset_data; + uint8_t *pwrmbase = (void *)PCH_PWRM_BASE_ADDRESS; + u32 ssl, ssms; + + /* Set Strap Lock Disable */ + ssl = read32(pwrmbase + SSML); + ssl |= SSML_SSL_DS; + write32(pwrmbase + SSML, ssl); + + /* Soft Reset Data Register Bit 12 = MAX Boot Frequency + * Bit 6-11 = Flex Ratio + * Soft Reset Data register located at PWRMBASE offset 0x1054[0:15]. + */ + soft_reset_data = SPI_STRAP_MAX_FREQ; + soft_reset_data |= (flex_ratio << FLEX_RATIO_BIT); + write32(pwrmbase + SSMD, soft_reset_data); + + /* Set Strap Mux Select set to '1' */ + ssms = read32(pwrmbase + SSMC); + ssms |= SSMC_SSMS; + write32(pwrmbase + SSMC, ssms); + + /* Set Strap Lock Enable */ + ssl = read32(pwrmbase + SSML); + ssl |= SSML_SSL_EN; + write32(pwrmbase + SSML, ssl); +} + +static void set_flex_ratio_to_tdp_nominal(void) +{ + msr_t flex_ratio, msr; + u8 nominal_ratio; + + /* Check for Flex Ratio support */ + flex_ratio = rdmsr(MSR_FLEX_RATIO); + if (!(flex_ratio.lo & FLEX_RATIO_EN)) + return; + + /* Check for >0 configurable TDPs */ + msr = rdmsr(MSR_PLATFORM_INFO); + if (((msr.hi >> 1) & 3) == 0) + return; + + /* Use nominal TDP ratio for flex ratio */ + msr = rdmsr(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; + + /* Set flex ratio to nominal TDP ratio */ + flex_ratio.lo &= ~0xff00; + flex_ratio.lo |= nominal_ratio << 8; + flex_ratio.lo |= FLEX_RATIO_LOCK; + wrmsr(MSR_FLEX_RATIO, flex_ratio); + + /* Set PCH Soft Reset Data Register with new Flex Ratio */ + set_pch_cpu_strap(nominal_ratio); + + /* Delay before reset to avoid potential TPM lockout */ + mdelay(30); + + /* Issue soft reset, will be "CPU only" due to soft reset data */ + soft_reset(); +} + +static void cache_bios_region(void) +{ + int mtrr; + size_t rom_size; + uint32_t alignment; + + mtrr = get_free_var_mtrr(); + + if (mtrr == -1) + return; + + rom_size = CONFIG_ROM_SIZE; + + if (!rom_size) + return; + + /* Round to power of two */ + alignment = 1 << (log2_ceil(rom_size)); + rom_size = ALIGN_UP(rom_size, alignment); + set_var_mtrr(mtrr, 4ULL*GiB - rom_size, rom_size, MTRR_TYPE_WRPROT); +} + +void bootblock_cpu_init(void) +{ + cache_bios_region(); + /* Set flex ratio and reset if needed */ + set_flex_ratio_to_tdp_nominal(); + intel_update_microcode_from_cbfs(); +} + +void set_max_freq(void) +{ + msr_t msr, perf_ctl, platform_info; + + /* Check for configurable TDP option */ + platform_info = rdmsr(MSR_PLATFORM_INFO); + + if ((platform_info.hi >> 1) & 3) { + /* Set to nominal TDP ratio */ + msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else { + /* Platform Info bits 15:8 give max ratio */ + msr = rdmsr(MSR_PLATFORM_INFO); + perf_ctl.lo = msr.lo & 0xff00; + } + + perf_ctl.hi = 0; + wrmsr(MSR_IA32_PERF_CTL, perf_ctl); + + printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n", + ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); +} diff --git a/src/soc/intel/cannonlake/include/soc/cpu.h b/src/soc/intel/cannonlake/include/soc/cpu.h new file mode 100644 index 0000000..d97605b --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/cpu.h @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_CANNONLAKE_CPU_H_ +#define _SOC_CANNONLAKE_CPU_H_ + +#include <arch/cpu.h> +#include <device/device.h> + +/* CPU types */ +#define CANNONLAKE_FAMILY_ULT 0x60660 + +/* Supported CPUIDs */ +#define CPUID_CANNONLAKE_A0 0x60660 +#define CPUID_CANNONLAKE_B0 0x60661 +#define CPUID_CANNONLAKE_C0 0x60662 + +/* CPU bus clock is fixed at 100MHz */ +#define CPU_BCLK 100 + +/* Latency times in units of 1024ns. */ +#define C_STATE_LATENCY_CONTROL_0_LIMIT 0x4e +#define C_STATE_LATENCY_CONTROL_1_LIMIT 0x76 +#define C_STATE_LATENCY_CONTROL_2_LIMIT 0x94 +#define C_STATE_LATENCY_CONTROL_3_LIMIT 0xfa +#define C_STATE_LATENCY_CONTROL_4_LIMIT 0x14c +#define C_STATE_LATENCY_CONTROL_5_LIMIT 0x3f2 + +/* Power in units of mW */ +#define C1_POWER 0x3e8 +#define C3_POWER 0x1f4 +#define C6_POWER 0x15e +#define C7_POWER 0xc8 +#define C8_POWER 0xc8 +#define C9_POWER 0xc8 +#define C10_POWER 0xc8 + +#define C_STATE_LATENCY_MICRO_SECONDS(limit, base) \ + (((1 << ((base)*5)) * (limit)) / 1000) +#define C_STATE_LATENCY_FROM_LAT_REG(reg) \ + C_STATE_LATENCY_MICRO_SECONDS(C_STATE_LATENCY_CONTROL_ ##reg## _LIMIT, \ + (IRTL_1024_NS >> 10)) + +/* Configure power limits for turbo mode */ +void set_power_limits(u8 power_limit_1_time); +int cpu_config_tdp_levels(void); + +#endif diff --git a/src/soc/intel/cannonlake/include/soc/msr.h b/src/soc/intel/cannonlake/include/soc/msr.h new file mode 100644 index 0000000..25c13e2 --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/msr.h @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_MSR_H_ +#define _SOC_MSR_H_ + +#include <intelblocks/msr.h> + +#define MSR_EMULATE_PM_TIMER 0x121 +#define EMULATE_PM_TMR_EN (1 << 16) +#define uCODE_TMR_EMULATION_19_MHZ 0x2FBA2E26 +#define uCODE_TMR_EMULATION_24_MHZ 0x262E8B52 +#define EMULATE_DELAY_OFFSET_VALUE 20 +#define EMULATE_DELAY_VALUE 0x13 +#define MSR_PIC_MSG_CONTROL 0x2e +#define MSR_BIOS_UPGD_TRIG 0x7a +#define MSR_FLEX_RATIO 0x194 +#define FLEX_RATIO_LOCK (1 << 20) +#define FLEX_RATIO_EN (1 << 16) +#define IA32_THERM_INTERRUPT 0x19b +#define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 +#define ENERGY_POLICY_PERFORMANCE 0 +#define ENERGY_POLICY_NORMAL 6 +#define ENERGY_POLICY_POWERSAVE 15 +#define IA32_PACKAGE_THERM_INTERRUPT 0x1b2 +#define PRMRR_PHYS_BASE_MSR 0x1f4 +#define PRMRR_PHYS_MASK_MSR 0x1f5 +#define PRMRR_PHYS_MASK_LOCK (1 << 10) +#define PRMRR_PHYS_MASK_VALID (1 << 11) +#define IA32_PLATFORM_DCA_CAP 0x1f8 +#define MSR_LT_LOCK_MEMORY 0x2e7 +#define UNCORE_PRMRR_PHYS_BASE_MSR 0x2f4 +#define UNCORE_PRMRR_PHYS_MASK_MSR 0x2f5 +#define MSR_SGX_OWNEREPOCH0 0x300 +#define MSR_SGX_OWNEREPOCH1 0x301 +#define MSR_VR_CURRENT_CONFIG 0x601 +#define MSR_VR_MISC_CONFIG 0x603 +#define MSR_VR_MISC_CONFIG2 0x636 +#define MSR_PP0_POWER_LIMIT 0x638 +#define MSR_PP1_POWER_LIMIT 0x640 + +/* SMM save state MSRs */ +#define SMBASE_MSR 0xc20 +#define IEDBASE_MSR 0xc22 + +/* MTRR_CAP_MSR bits */ +#define SMRR_SUPPORTED (1<<11) +#define PRMRR_SUPPORTED (1<<12) + +#endif