diff options
author | Sumeet Pawnikar <sumeet.r.pawnikar@intel.com> | 2016-09-27 23:18:35 +0530 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2016-10-16 02:51:52 +0200 |
commit | a247d8e53cebbd754e46f76412ed9d17df752308 (patch) | |
tree | 32c3fcf219f97debcdfecfa0f77117e0d0549bfa /src | |
parent | 9a20551b7e15ff8bb05922489ee4649f1b7f4826 (diff) | |
download | coreboot-a247d8e53cebbd754e46f76412ed9d17df752308.tar.xz |
soc/intel/apollolake: Set PL1 limits for RAPL MSR registers
This patch sets the package power limit (PL1) value in RAPL MSR
and disables MMIO register. Added configurable PL1 override
parameter to leverage full TDP capacity.
BUG=chrome-os-partner:56922
TEST=webGL performance(fps) not impacted before and after S3.
Change-Id: I34208048a6d4a127e9b1267d2df043cb2c46cf77
Signed-off-by: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com>
Signed-off-by: Venkateswarlu Vinjamuri <venkateswarlu.v.vinjamuri@intel.com>
Reviewed-on: https://review.coreboot.org/16884
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/intel/apollolake/chip.c | 79 | ||||
-rw-r--r-- | src/soc/intel/apollolake/chip.h | 3 | ||||
-rw-r--r-- | src/soc/intel/apollolake/include/soc/cpu.h | 14 |
3 files changed, 79 insertions, 17 deletions
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index eeac6cee5e..181d4d68bc 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -193,22 +193,67 @@ static void pcie_override_devicetree_after_silicon_init(void) pcie_update_device_tree(PCIEB0_DEVFN, 2); } -static void rapl_update(void) +/* Configure package power limits */ +static void set_power_limits(void) { - uint32_t *rapl_reg; - uint32_t val; - const uint32_t power_mw = 15000; - - rapl_reg = (void*)(uintptr_t) (MCH_BASE_ADDR + MCHBAR_RAPL_PPL); - - /* Due to an incorrect value set for the power limit PL1 as 6W in RAPL - * MMIO register from FSP code, the system is not able to leverage full - * TDP capacity. This RAPL MMIO register is a physically separate - * instance from RAPL MSR register. Punit algorithm controls to the - * minimum power limit PL1 mentioned in the RAPL MMIO and MSR registers. - * Here, setting RAPL PL1 in Bits[14:0] to 15W in RAPL MMIO register. */ - val = (power_mw << (rdmsr(MSR_PKG_POWER_SKU_UNIT).lo & 0xf)) / 1000; - write32(rapl_reg, (read32(rapl_reg) & ~0x7fff) | val); + static struct soc_intel_apollolake_config *cfg; + struct device *dev = NB_DEV_ROOT; + msr_t rapl_msr_reg, limit; + uint32_t power_unit; + uint32_t tdp, min_power, max_power; + uint32_t *rapl_mmio_reg; + + if (!dev || !dev->chip_info) { + printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n"); + return; + } + + cfg = dev->chip_info; + + /* Get units */ + rapl_msr_reg = rdmsr(MSR_PKG_POWER_SKU_UNIT); + power_unit = 1 << (rapl_msr_reg.lo & 0xf); + + /* Get power defaults for this SKU */ + rapl_msr_reg = rdmsr(MSR_PKG_POWER_SKU); + tdp = rapl_msr_reg.lo & PKG_POWER_LIMIT_MASK; + min_power = (rapl_msr_reg.lo >> 16) & PKG_POWER_LIMIT_MASK; + max_power = rapl_msr_reg.hi & PKG_POWER_LIMIT_MASK; + + if (min_power > 0 && tdp < min_power) + tdp = min_power; + + if (max_power > 0 && tdp > max_power) + tdp = max_power; + + /* Set PL1 override value */ + tdp = (cfg->tdp_pl1_override_mw == 0) ? + tdp : (cfg->tdp_pl1_override_mw * power_unit) / 1000; + + /* Set long term power limit to TDP */ + limit.lo = tdp & PKG_POWER_LIMIT_MASK; + /* PL2 is invalid for small core */ + limit.hi = 0x0; + + /* Set PL1 Pkg Power clamp bit */ + limit.lo |= PKG_POWER_LIMIT_CLAMP; + + limit.lo |= PKG_POWER_LIMIT_EN; + limit.lo |= (MB_POWER_LIMIT1_TIME_DEFAULT & + PKG_POWER_LIMIT_TIME_MASK) << PKG_POWER_LIMIT_TIME_SHIFT; + + /* Program package power limits in RAPL MSR */ + wrmsr(MSR_PKG_POWER_LIMIT, limit); + printk(BIOS_INFO, "RAPL PL1 %d.%dW\n", tdp / power_unit, + 100 * (tdp % power_unit) / power_unit); + + /* Get the MMIO address */ + rapl_mmio_reg = (void *)(uintptr_t) (MCH_BASE_ADDR + MCHBAR_RAPL_PPL); + /* + * Disable RAPL MMIO PL1 Power limits because RAPL uses MSR value. + * PL2 (limit.hi) is invalid for small cores + */ + write32(rapl_mmio_reg, limit.lo & ~(PKG_POWER_LIMIT_EN)); } static void soc_init(void *data) @@ -241,8 +286,8 @@ static void soc_init(void *data) /* Allocate ACPI NVS in CBMEM */ gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(*gnvs)); - /* Update RAPL package power limit */ - rapl_update(); + /* Set RAPL MSR for Package power limits*/ + set_power_limits(); } static void soc_final(void *data) diff --git a/src/soc/intel/apollolake/chip.h b/src/soc/intel/apollolake/chip.h index 74a6411b50..6c3bcd8cad 100644 --- a/src/soc/intel/apollolake/chip.h +++ b/src/soc/intel/apollolake/chip.h @@ -107,6 +107,9 @@ struct soc_intel_apollolake_config { /* Enable DPTF support */ int dptf_enable; + /* PL1 override value in mW for APL */ + uint16_t tdp_pl1_override_mw; + /* Configure Audio clk gate and power gate * IOSF-SB port ID 92 offset 0x530 [5] and [3] */ diff --git a/src/soc/intel/apollolake/include/soc/cpu.h b/src/soc/intel/apollolake/include/soc/cpu.h index 22412aff2d..bffe4bcd8d 100644 --- a/src/soc/intel/apollolake/include/soc/cpu.h +++ b/src/soc/intel/apollolake/include/soc/cpu.h @@ -39,6 +39,20 @@ void apollolake_init_cpus(struct device *dev); #define PREFETCH_L2_DISABLE (1 << 2) #define MSR_PKG_POWER_SKU_UNIT 0x606 +#define MSR_PKG_POWER_SKU 0x614 +#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) +/* + * For Mobile, RAPL default PL1 time window value set to 28 seconds. + * RAPL time window calculation defined as follows: + * Time Window = (float)((1+X/4)*(2*^Y), X Corresponds to [23:22], + * Y to [21:17] in MSR 0x610. 28 sec is equal to 0x6e. + */ +#define MB_POWER_LIMIT1_TIME_DEFAULT 0x6e #define MSR_L2_QOS_MASK(reg) (0xd10 + reg) #define MSR_IA32_PQR_ASSOC 0xc8f |