diff --git a/src/soc/intel/common/block/include/intelblocks/cfr.h b/src/soc/intel/common/block/include/intelblocks/cfr.h index 0185b0c028..0905d2d65d 100644 --- a/src/soc/intel/common/block/include/intelblocks/cfr.h +++ b/src/soc/intel/common/block/include/intelblocks/cfr.h @@ -184,4 +184,12 @@ static const struct sm_object bios_lock = SM_DECLARE_BOOL({ .default_value = CONFIG(BOOTMEDIA_SMM_BWP), }, WITH_CALLBACK(update_smm_bwp)); +static const struct sm_object pkg_power_limit_lock = SM_DECLARE_BOOL({ + .opt_name = "pkg_power_limit_lock", + .ui_name = "Package power limit lock", + .ui_helptext = "Lock the package power limits after programming.\n" + "This prevents the power limits from being changed by the OS or runtime tools.", + .default_value = false, +}); + #endif /* SOC_INTEL_CMN_CFR_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index 1965b36d59..26f433fb15 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -101,6 +101,7 @@ #define PKG_POWER_LIMIT_TIME_MASK (0x7f) #define PKG_POWER_LIMIT_DUTYCYCLE_SHIFT 24 #define PKG_POWER_LIMIT_DUTYCYCLE_MASK (0x7f) +#define PKG_POWER_LIMIT_LOCK (1 << 31) #define MSR_CORE_MKTME_ACTIVATION 0x9ff /* SMM save state MSRs */ diff --git a/src/soc/intel/common/block/power_limit/power_limit.c b/src/soc/intel/common/block/power_limit/power_limit.c index 4758f09f82..167c8d7f73 100644 --- a/src/soc/intel/common/block/power_limit/power_limit.c +++ b/src/soc/intel/common/block/power_limit/power_limit.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -141,8 +142,8 @@ void set_power_limits(u8 power_limit_1_time, /* Set long term power limit to TDP */ limit.lo = 0; - tdp_pl1 = ((conf->tdp_pl1_override == 0) ? - tdp : (conf->tdp_pl1_override * power_unit)); + const unsigned int tdp_pl1_override = get_uint_option("tdp_pl1_override", conf->tdp_pl1_override); + tdp_pl1 = tdp_pl1_override ? (tdp_pl1_override * power_unit) : tdp; printk(BIOS_INFO, "CPU PL1 = %u Watts\n", tdp_pl1 / power_unit); limit.lo |= (tdp_pl1 & PKG_POWER_LIMIT_MASK); @@ -155,13 +156,21 @@ void set_power_limits(u8 power_limit_1_time, /* Set short term power limit to 1.25 * TDP if no config given */ limit.hi = 0; - tdp_pl2 = (conf->tdp_pl2_override == 0) ? - (tdp * 125) / 100 : (conf->tdp_pl2_override * power_unit); + const unsigned int tdp_pl2_override = get_uint_option("tdp_pl2_override", conf->tdp_pl2_override); + tdp_pl2 = tdp_pl2_override ? (tdp_pl2_override * power_unit) : ((tdp * 125) / 100); + /* Ensure PL2 isn't less than PL1 */ + if (tdp_pl2 < tdp_pl1) + tdp_pl2 = tdp_pl1; printk(BIOS_INFO, "CPU PL2 = %u Watts\n", tdp_pl2 / power_unit); limit.hi |= (tdp_pl2) & PKG_POWER_LIMIT_MASK; limit.hi |= PKG_POWER_LIMIT_CLAMP; limit.hi |= PKG_POWER_LIMIT_EN; + if (get_uint_option("pkg_power_limit_lock", 0)) { + limit.hi |= PKG_POWER_LIMIT_LOCK; + printk(BIOS_INFO, "Locking package power limits\n"); + } + /* Power limit 2 time is only programmable on server SKU */ wrmsr(MSR_PKG_POWER_LIMIT, limit);