soc/intel/common: Support power limits update for variants
Add support to update power limit values for variants. Until now, each SoC implements this themselves. To avoid code duplication, add this to common code. BRANCH=None BUG=b:270664854 TEST=Built and verified power limit values as below log message for 15W SKU on Rex board. Overriding power limits PL1 (mW) (10000, 15000) PL2 (mW) (57000, 57000) PL4 (W) (114) Change-Id: I414715f211d816bbfad03a673ca96dd5df94caeb Signed-off-by: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/74620 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Subrata Banik <subratabanik@google.com> Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
This commit is contained in:
parent
e9efd32485
commit
83b36f8276
|
@ -42,4 +42,18 @@ void set_power_limits(u8 power_limit_1_time,
|
||||||
|
|
||||||
u8 get_cpu_tdp(void);
|
u8 get_cpu_tdp(void);
|
||||||
|
|
||||||
|
struct cpu_tdp_power_limits {
|
||||||
|
uint16_t mch_id;
|
||||||
|
uint8_t cpu_tdp;
|
||||||
|
unsigned int pl1_min_power;
|
||||||
|
unsigned int pl1_max_power;
|
||||||
|
unsigned int pl2_min_power;
|
||||||
|
unsigned int pl2_max_power;
|
||||||
|
unsigned int pl4_power;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Modify Power Limit devictree settings during ramstage */
|
||||||
|
void variant_update_cpu_power_limits(const struct cpu_tdp_power_limits *limits,
|
||||||
|
size_t num_entries);
|
||||||
|
|
||||||
#endif /* _SOC_INTEL_COMMON_BLOCK_POWER_LIMIT_H_ */
|
#endif /* _SOC_INTEL_COMMON_BLOCK_POWER_LIMIT_H_ */
|
||||||
|
|
|
@ -9,3 +9,10 @@ config SOC_INTEL_RAPL_DISABLE_VIA_MCHBAR
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Select if disabling Running Average Power Limit (RAPL) has to be done via MCHBAR.
|
Select if disabling Running Average Power Limit (RAPL) has to be done via MCHBAR.
|
||||||
|
|
||||||
|
config SOC_INTEL_COMMON_BLOCK_VARIANT_POWER_LIMIT
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option allows to configure processor power limit values
|
||||||
|
for different variants based on CPU TDP and machine id.
|
||||||
|
|
|
@ -2,9 +2,13 @@
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
|
#include <device/pci_ops.h>
|
||||||
|
#include <drivers/intel/dptf/chip.h>
|
||||||
#include <intelblocks/cpulib.h>
|
#include <intelblocks/cpulib.h>
|
||||||
#include <intelblocks/power_limit.h>
|
#include <intelblocks/power_limit.h>
|
||||||
#include <soc/msr.h>
|
#include <soc/msr.h>
|
||||||
|
#include <soc/pci_devs.h>
|
||||||
|
#include <soc/soc_chip.h>
|
||||||
#include <soc/systemagent.h>
|
#include <soc/systemagent.h>
|
||||||
|
|
||||||
/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
|
/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
|
||||||
|
@ -227,3 +231,55 @@ u8 get_cpu_tdp(void)
|
||||||
|
|
||||||
return cpu_tdp / power_unit;
|
return cpu_tdp / power_unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WEAK_DEV_PTR(dptf_policy);
|
||||||
|
|
||||||
|
#if CONFIG(SOC_INTEL_COMMON_BLOCK_VARIANT_POWER_LIMIT)
|
||||||
|
void variant_update_cpu_power_limits(const struct cpu_tdp_power_limits *limits,
|
||||||
|
size_t num_entries)
|
||||||
|
{
|
||||||
|
if (!num_entries) {
|
||||||
|
printk(BIOS_INFO, "CPU Power limits entry not available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct device *policy_dev = DEV_PTR(dptf_policy);
|
||||||
|
if (!policy_dev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct drivers_intel_dptf_config *config = policy_dev->chip_info;
|
||||||
|
if (!config) {
|
||||||
|
printk(BIOS_INFO, "DPTF is not enabled\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mch_id = pci_s_read_config16(PCI_DEV(0, 0, 0), PCI_DEVICE_ID);
|
||||||
|
if (mch_id == 0xffff) {
|
||||||
|
printk(BIOS_INFO, "No matching PCI DID present\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tdp = get_cpu_tdp();
|
||||||
|
|
||||||
|
for (size_t index = 0; index < num_entries; index++) {
|
||||||
|
if (mch_id != limits[index].mch_id || tdp != limits[index].cpu_tdp) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
struct dptf_power_limits *settings = &config->controls.power_limits;
|
||||||
|
config_t *conf = config_of_soc();
|
||||||
|
struct soc_power_limits_config *soc_config = conf->power_limits_config;
|
||||||
|
settings->pl1.min_power = limits[index].pl1_min_power;
|
||||||
|
settings->pl1.max_power = limits[index].pl1_max_power;
|
||||||
|
settings->pl2.min_power = limits[index].pl2_min_power;
|
||||||
|
settings->pl2.max_power = limits[index].pl2_max_power;
|
||||||
|
soc_config->tdp_pl4 = DIV_ROUND_UP(limits[index].pl4_power, MILLIWATTS_TO_WATTS);
|
||||||
|
printk(BIOS_INFO, "Overriding power limits PL1 (mW) (%u, %u) PL2 (mW) (%u, %u) PL4 (W) (%u)\n",
|
||||||
|
settings->pl1.min_power,
|
||||||
|
settings->pl1.max_power,
|
||||||
|
settings->pl2.min_power,
|
||||||
|
settings->pl2.max_power,
|
||||||
|
soc_config->tdp_pl4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue