Jérémy Compostella has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/74572 )
Change subject: soc/intel/meteorlake: support Power Limits and Voltage Regulator ......................................................................
soc/intel/meteorlake: support Power Limits and Voltage Regulator
Power Limits and Voltage Regulator settings are the result of at least the following combination of factors: - The voltage regular itself - The TDP/SoC used - The board design (extra chips, cooling system, ...) - The Operating System and the use-cases - Power and performance measurements and tuning
Those settings being board design and use-case specific, they cannot be reduced to simple database indexed on a SoC ID and TDP. They must factor in the board itself.
Therefor, this patch adds support to apply Power Limits and Voltage Regulator settings supplied by a board specific database.
Note that the FSP includes default Power Limits and Voltage Regulator settings. These settings may be good enough for basic board bring-up but should be refined per board design.
BRANCH=None BUG=b:262499722 TEST=TBD
Change-Id: Ia1a6d4872718730951591cde6677557eebe3a944 Signed-off-by: Jeremy Compostella jeremy.compostella@intel.com --- M src/soc/intel/meteorlake/chip.h M src/soc/intel/meteorlake/chipset.cb M src/soc/intel/meteorlake/romstage/fsp_params.c M src/soc/intel/meteorlake/systemagent.c 4 files changed, 139 insertions(+), 44 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/72/74572/1
diff --git a/src/soc/intel/meteorlake/chip.h b/src/soc/intel/meteorlake/chip.h index dbe5eb1..905a14a 100644 --- a/src/soc/intel/meteorlake/chip.h +++ b/src/soc/intel/meteorlake/chip.h @@ -3,6 +3,7 @@ #ifndef _SOC_CHIP_H_ #define _SOC_CHIP_H_
+#include <device/pci_ids.h> #include <drivers/i2c/designware/dw_i2c.h> #include <gpio.h> #include <intelblocks/cfg.h> @@ -17,13 +18,50 @@ #include <soc/usb.h> #include <stdint.h>
-/* Types of different SKUs */ -enum soc_intel_meteorlake_power_limits { - MTL_P_POWER_LIMITS_1, - MTL_P_POWER_LIMITS_2, - MTL_P_POWER_LIMITS_3, - MTL_P_POWER_LIMITS_4, - MTL_POWER_LIMITS_COUNT +#define MTL_PL_VR_COUNT 8 +#define MTL_VR_DOMAINS 2 + +/* + * Power limits and voltage regulator settings depends on: + * 1. Board design / Voltage Regulator / EC + * 2. Thermal Design Power of the System on Chip + * 3. The System on Chip + * + * These settings should be provided by the mainboard or variant override. + * + * FSP silicon sets default values taking into account #2 and #3 and based on + * Intel board design. UPD can be used to override those values. + */ +struct soc_voltage_regulator_config { + /* AC and DC Loadline. + They are in 1/100 mOhms (ie. 1250 = 12.50 mOhms) and range is 0-6249. */ + uint16_t ac_loadline; + uint16_t dc_loadline; + + /* VR Icc Max limit. + Range is from 0-255A in 1/4 A units (400 = 100A). */ + uint16_t icc_max; + + /* Thermal Design Current time window. + Defined in milli seconds and range 1ms to 448s. */ + uint32_t tdc_timewindow; + + /* Thermal Design Current current limit. + Defined in 1/8A units and range is 0-4095. 1000 = 125A. */ + uint16_t tdc_currentlimit; + + /* Power State 1/2/3 Threshold Current. + Defined in 1/4A units and range is 0-128A */ + uint16_t psi1threshold; + uint16_t psi2threshold; + uint16_t psi3threshold; +}; + +struct soc_intel_meteorlake_power_settings { + uint32_t sa_dev_id; + uint8_t tdp; + struct soc_power_limits_config limits; + struct soc_voltage_regulator_config vr[MTL_VR_DOMAINS]; };
/* Types of display ports */ @@ -81,8 +119,11 @@ /* Common struct containing soc config data required by common code */ struct soc_intel_common_config common_soc_config;
- /* Common struct containing power limits configuration information */ - struct soc_power_limits_config power_limits_config[MTL_POWER_LIMITS_COUNT]; + /* + * Common struct containing power limits and voltage regular + * configuration information + */ + struct soc_intel_meteorlake_power_settings power_config[MTL_PL_VR_COUNT];
/* Gpio group routed to each dword of the GPE0 block. Values are * of the form PMC_GPP_[A:U] or GPD. */ diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 3af284c..b711b89 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -2,17 +2,6 @@
device cpu_cluster 0 on end
- #FIXME: update values for MTL and enable override in systemagent.c - register "power_limits_config[MTL_P_POWER_LIMITS_2]" = "{ - .tdp_pl1_override = 15, - .tdp_pl2_override = 55, - }" - - register "power_limits_config[MTL_P_POWER_LIMITS_1]" = "{ - .tdp_pl1_override = 45, - .tdp_pl2_override = 115, - }" - # NOTE: if any variant wants to override this value, use the same format # as register "common_soc_config.pch_thermal_trip" = "value", instead of # putting it under register "common_soc_config" in overridetree.cb file. diff --git a/src/soc/intel/meteorlake/romstage/fsp_params.c b/src/soc/intel/meteorlake/romstage/fsp_params.c index ec5a3af..26a6e47 100644 --- a/src/soc/intel/meteorlake/romstage/fsp_params.c +++ b/src/soc/intel/meteorlake/romstage/fsp_params.c @@ -5,6 +5,7 @@ #include <cpu/intel/cpu_ids.h> #include <cpu/x86/msr.h> #include <device/device.h> +#include <device/pci.h> #include <drivers/wifi/generic/wifi.h> #include <fsp/fsp_debug_event.h> #include <fsp/util.h> @@ -275,6 +276,40 @@ m_cfg->VmxEnable = CONFIG(ENABLE_VMX); }
+static void fill_fspm_vr_params(FSP_M_CONFIG *m_cfg, + const struct soc_intel_meteorlake_config *config) +{ + uint8_t tdp; + uint16_t sa_dev_id; + const struct soc_intel_meteorlake_power_settings *cur; + + /* Get System Agent PCI ID and Thermal Design Power */ + sa_dev_id = pci_read_config16(SA_DEV_ROOT, PCI_DEVICE_ID); + tdp = get_cpu_tdp(); + + for (size_t i = 0; i < ARRAY_SIZE(config->power_config); i++) { + cur = &config->power_config[i]; + if (!cur->sa_dev_id) + break; + + if (cur->sa_dev_id != sa_dev_id || cur->tdp != tdp) + continue; + + for (size_t domain = 0; domain < ARRAY_SIZE(cur->vr); domain++) { + m_cfg->AcLoadline[domain] = cur->vr[domain].ac_loadline; + m_cfg->DcLoadline[domain] = cur->vr[domain].dc_loadline; + m_cfg->IccMax[domain] = cur->vr[domain].icc_max; + m_cfg->Psi1Threshold[domain] = cur->vr[domain].psi1threshold; + m_cfg->Psi2Threshold[domain] = cur->vr[domain].psi2threshold; + m_cfg->Psi3Threshold[domain] = cur->vr[domain].psi3threshold; + } + + return; + } + + printk(BIOS_DEBUG, "No Voltage Regular settings override found\n"); +} + static void fill_fspm_trace_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_meteorlake_config *config) { @@ -307,6 +342,7 @@ fill_fspm_tcss_params, fill_fspm_usb4_params, fill_fspm_vtd_params, + fill_fspm_vr_params, fill_fspm_trace_params, };
diff --git a/src/soc/intel/meteorlake/systemagent.c b/src/soc/intel/meteorlake/systemagent.c index 81e4bed..d26b793 100644 --- a/src/soc/intel/meteorlake/systemagent.c +++ b/src/soc/intel/meteorlake/systemagent.c @@ -152,45 +152,41 @@ */ void soc_systemagent_init(struct device *dev) { - struct soc_power_limits_config *soc_config; struct device *sa; uint16_t sa_pci_id; + uint8_t tdp; config_t *config; + const struct soc_intel_meteorlake_power_settings *cur;
/* Enable Power Aware Interrupt Routing */ enable_power_aware_intr();
config = config_of_soc();
- /* Get System Agent PCI ID */ + /* Get System Agent PCI ID and TDP */ sa = pcidev_path_on_root(PCI_DEVFN_ROOT); - sa_pci_id = sa ? pci_read_config16(sa, PCI_DEVICE_ID) : 0xFFFF; + if (!sa) + return; + sa_pci_id = pci_read_config16(sa, PCI_DEVICE_ID); + tdp = get_cpu_tdp();
/* Choose a power limits configuration based on the SoC SKU type, * differentiated here based on SA PCI ID. */ - switch (sa_pci_id) { - case PCI_DID_INTEL_MTL_P_ID_1: - soc_config = &config->power_limits_config[MTL_P_POWER_LIMITS_1]; - break; - case PCI_DID_INTEL_MTL_P_ID_2: - soc_config = &config->power_limits_config[MTL_P_POWER_LIMITS_2]; - break; - case PCI_DID_INTEL_MTL_P_ID_3: - soc_config = &config->power_limits_config[MTL_P_POWER_LIMITS_3]; - break; - case PCI_DID_INTEL_MTL_P_ID_4: - soc_config = &config->power_limits_config[MTL_P_POWER_LIMITS_4]; - break; - default: - printk(BIOS_ERR, "unknown SA ID: 0x%4x, skipping power limits configuration\n", - sa_pci_id); + for (size_t i = 0; i < ARRAY_SIZE(config->power_config); i++) { + cur = &config->power_config[i]; + if (!cur->sa_dev_id) + break; + + if (cur->sa_dev_id != sa_pci_id || cur->tdp != tdp) + continue; + + /* TODO: `set_power_limits()' should take a `const struct + soc_power_limits_config *'. Fix `set_power_limits()' instead + of casting here. */ + set_power_limits(MOBILE_SKU_PL1_TIME_SEC, + (struct soc_power_limits_config *)&cur->limits); return; } - - /* Remove once commented line below is enabled */ - (void)soc_config; - /* UPDATEME: Need to enable later */ - //set_power_limits(MOBILE_SKU_PL1_TIME_SEC, soc_config); }
uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz)