broadwell: update processor power limits configuration

Update processor power limit configuration parameters based on
common code base support for Intel Broadwell SoC based platforms.

BRANCH=None
BUG=None
TEST=Build for broadwell based platform

Change-Id: I97e38a533e74a122b6809e20a10f6e425827ab9c
Signed-off-by: Sumeet R Pawnikar <sumeet.r.pawnikar@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41234
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
Sumeet R Pawnikar 2020-05-08 22:18:09 +05:30 committed by Patrick Georgi
parent 71a9a7c70f
commit fa42d568a0
8 changed files with 33 additions and 156 deletions

View File

@ -15,6 +15,7 @@ config CPU_SPECIFIC_OPTIONS
select BOOT_DEVICE_SUPPORTS_WRITES
select CACHE_MRC_SETTINGS
select MRC_SETTINGS_PROTECT
select CPU_INTEL_COMMON
select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
select SUPPORT_CPU_UCODE_IN_CBFS
select HAVE_SMI_HANDLER
@ -34,10 +35,12 @@ config CPU_SPECIFIC_OPTIONS
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
select SOC_INTEL_COMMON
select SOC_INTEL_COMMON_BLOCK
select SOC_INTEL_COMMON_BLOCK_CPU
select SOC_INTEL_COMMON_BLOCK_POWER_LIMIT
select INTEL_DESCRIPTOR_MODE_CAPABLE
select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
select HAVE_SPI_CONSOLE_SUPPORT
select CPU_INTEL_COMMON
select INTEL_GMA_ACPI
select HAVE_POWER_STATE_AFTER_FAILURE
select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE

View File

@ -24,6 +24,7 @@
#include <soc/pm.h>
#include <soc/systemagent.h>
#include <soc/intel/broadwell/chip.h>
#include <intelblocks/cpulib.h>
/*
* List of supported C-states in this processor. Only the ULT parts support C8,

View File

@ -4,6 +4,7 @@
#define _SOC_INTEL_BROADWELL_CHIP_H_
#include <drivers/intel/gma/i915.h>
#include <intelblocks/cfg.h>
#include <stdint.h>
struct soc_intel_broadwell_config {

View File

@ -16,6 +16,7 @@
#include <cpu/x86/name.h>
#include <cpu/x86/smm.h>
#include <delay.h>
#include <intelblocks/cpulib.h>
#include <soc/cpu.h>
#include <soc/msr.h>
#include <soc/pci_devs.h>
@ -25,64 +26,6 @@
#include <soc/intel/broadwell/chip.h>
#include <cpu/intel/common/common.h>
/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
static const u8 power_limit_time_sec_to_msr[] = {
[0] = 0x00,
[1] = 0x0a,
[2] = 0x0b,
[3] = 0x4b,
[4] = 0x0c,
[5] = 0x2c,
[6] = 0x4c,
[7] = 0x6c,
[8] = 0x0d,
[10] = 0x2d,
[12] = 0x4d,
[14] = 0x6d,
[16] = 0x0e,
[20] = 0x2e,
[24] = 0x4e,
[28] = 0x6e,
[32] = 0x0f,
[40] = 0x2f,
[48] = 0x4f,
[56] = 0x6f,
[64] = 0x10,
[80] = 0x30,
[96] = 0x50,
[112] = 0x70,
[128] = 0x11,
};
/* Convert POWER_LIMIT_1_TIME MSR value to seconds */
static const u8 power_limit_time_msr_to_sec[] = {
[0x00] = 0,
[0x0a] = 1,
[0x0b] = 2,
[0x4b] = 3,
[0x0c] = 4,
[0x2c] = 5,
[0x4c] = 6,
[0x6c] = 7,
[0x0d] = 8,
[0x2d] = 10,
[0x4d] = 12,
[0x6d] = 14,
[0x0e] = 16,
[0x2e] = 20,
[0x4e] = 24,
[0x6e] = 28,
[0x0f] = 32,
[0x2f] = 40,
[0x4f] = 48,
[0x6f] = 56,
[0x10] = 64,
[0x30] = 80,
[0x50] = 96,
[0x70] = 112,
[0x11] = 128,
};
/* The core 100MHz BLCK is disabled in deeper c-states. One needs to calibrate
* the 100MHz BCLCK against the 24MHz BLCK to restore the clocks properly
* when a core is woken up. */
@ -288,90 +231,6 @@ static void configure_pch_power_sharing(void)
RCBA32(PMSYNC_CONFIG2) = pmsync2;
}
int cpu_config_tdp_levels(void)
{
msr_t platform_info;
/* Bits 34:33 indicate how many levels supported */
platform_info = rdmsr(MSR_PLATFORM_INFO);
return (platform_info.hi >> 1) & 3;
}
/*
* Configure processor power limits if possible
* This must be done AFTER set of BIOS_RESET_CPL
*/
void set_power_limits(u8 power_limit_1_time)
{
msr_t msr = rdmsr(MSR_PLATFORM_INFO);
msr_t limit;
unsigned int power_unit;
unsigned int tdp, min_power, max_power, max_time;
u8 power_limit_1_val;
if (power_limit_1_time >= ARRAY_SIZE(power_limit_time_sec_to_msr))
power_limit_1_time = ARRAY_SIZE(power_limit_time_sec_to_msr) - 1;
if (!(msr.lo & PLATFORM_INFO_SET_TDP))
return;
/* Get units */
msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
power_unit = 2 << ((msr.lo & 0xf) - 1);
/* Get power defaults for this SKU */
msr = rdmsr(MSR_PKG_POWER_SKU);
tdp = msr.lo & 0x7fff;
min_power = (msr.lo >> 16) & 0x7fff;
max_power = msr.hi & 0x7fff;
max_time = (msr.hi >> 16) & 0x7f;
printk(BIOS_DEBUG, "CPU TDP: %u Watts\n", tdp / power_unit);
if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time)
power_limit_1_time = power_limit_time_msr_to_sec[max_time];
if (min_power > 0 && tdp < min_power)
tdp = min_power;
if (max_power > 0 && tdp > max_power)
tdp = max_power;
power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time];
/* Set long term power limit to TDP */
limit.lo = 0;
limit.lo |= tdp & PKG_POWER_LIMIT_MASK;
limit.lo |= PKG_POWER_LIMIT_EN;
limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) <<
PKG_POWER_LIMIT_TIME_SHIFT;
/* Set short term power limit to 1.25 * TDP */
limit.hi = 0;
limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK;
limit.hi |= PKG_POWER_LIMIT_EN;
/* Power limit 2 time is only programmable on server SKU */
wrmsr(MSR_PKG_POWER_LIMIT, limit);
/* Set power limit values in MCHBAR as well */
MCHBAR32(MCH_PKG_POWER_LIMIT_LO) = limit.lo;
MCHBAR32(MCH_PKG_POWER_LIMIT_HI) = limit.hi;
/* Set DDR RAPL power limit by copying from MMIO to MSR */
msr.lo = MCHBAR32(MCH_DDR_POWER_LIMIT_LO);
msr.hi = MCHBAR32(MCH_DDR_POWER_LIMIT_HI);
wrmsr(MSR_DDR_RAPL_LIMIT, msr);
/* Use nominal TDP values for CPUs with configurable TDP */
if (cpu_config_tdp_levels()) {
msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
limit.hi = 0;
limit.lo = msr.lo & 0xff;
wrmsr(MSR_TURBO_ACTIVATION_RATIO, limit);
}
}
static void configure_c_states(void)
{
msr_t msr;

View File

@ -37,10 +37,6 @@
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);
/* CPU identification */
u32 cpu_family_model(void);
u32 cpu_stepping(void);

View File

@ -3,6 +3,8 @@
#ifndef _BROADWELL_MSR_H_
#define _BROADWELL_MSR_H_
#include <intelblocks/msr.h>
#define MSR_PIC_MSG_CONTROL 0x2e
#define MSR_CORE_THREAD_COUNT 0x35
#define MSR_PLATFORM_INFO 0xce
@ -45,14 +47,6 @@
#define IRTL_RESPONSE_MASK (0x3ff)
#define MSR_COUNTER_24_MHZ 0x637
/* long duration in low dword, short duration in high dword */
#define MSR_PKG_POWER_LIMIT 0x610
#define PKG_POWER_LIMIT_MASK 0x7fff
#define PKG_POWER_LIMIT_EN (1 << 15)
#define PKG_POWER_LIMIT_CLAMP (1 << 16)
#define PKG_POWER_LIMIT_TIME_SHIFT 17
#define PKG_POWER_LIMIT_TIME_MASK 0x7f
#define MSR_VR_CURRENT_CONFIG 0x601
#define MSR_VR_MISC_CONFIG 0x603
#define MSR_PKG_POWER_SKU_UNIT 0x606

View File

@ -0,0 +1,20 @@
/*
* This file is part of the coreboot project.
*
*
* 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_BROADWELL_SOC_CHIP_H_
#define _SOC_BROADWELL_SOC_CHIP_H_
#include "../../chip.h"
#endif /* _SOC_BROADWELL_SOC_CHIP_H_ */

View File

@ -8,6 +8,7 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <intelblocks/power_limit.h>
#include <vendorcode/google/chromeos/chromeos.h>
#include <soc/cpu.h>
#include <soc/iomap.h>
@ -404,6 +405,7 @@ static void systemagent_read_resources(struct device *dev)
static void systemagent_init(struct device *dev)
{
struct soc_power_limits_config *config;
u8 bios_reset_cpl, pair;
/* Enable Power Aware Interrupt Routing */
@ -423,7 +425,8 @@ static void systemagent_init(struct device *dev)
/* Configure turbo power limits 1ms after reset complete bit */
mdelay(1);
set_power_limits(28);
config = config_of_soc();
set_power_limits(MOBILE_SKU_PL1_TIME_SEC, config);
}
static struct device_operations systemagent_ops = {