diff options
author | Marx Wang <marx.wang@intel.com> | 2020-02-07 16:44:14 +0800 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2020-02-25 10:11:02 +0000 |
commit | 9318d6d6251dcc5ae243a377d15d407a066ec46f (patch) | |
tree | 4ed813f2fc7dfd0ea9829cb6e297849a0561e7e8 /src/soc/intel | |
parent | 75cd6d2a97a3d5630e74ca099ddb702be143415e (diff) |
soc/intel/cannonlake: Add TDC config for CML
Add Thermal Design Current (TDC) defaults for CML:
1. TdcEnable
2. TdcPowerLimit
BUG=b:148912093
BRANCH=None
TEST=build coreboot and Intel FSP with fw_debug enabled, flash image to
the device, capture the log from the serial port during boot-up and
check TdcEnable and TdcPowerLimit for each domain in captured log
Signed-off-by: Marx Wang <marx.wang@intel.com>
Change-Id: Ie4b17e5b4ce41c1adb436ae5646f0d8578a440e8
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38741
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: EricR Lai <ericr_lai@compal.corp-partner.google.com>
Reviewed-by: John Su <john_su@compal.corp-partner.google.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/cannonlake/include/soc/vr_config.h | 16 | ||||
-rw-r--r-- | src/soc/intel/cannonlake/vr_config.c | 97 |
2 files changed, 113 insertions, 0 deletions
diff --git a/src/soc/intel/cannonlake/include/soc/vr_config.h b/src/soc/intel/cannonlake/include/soc/vr_config.h index 1390b174e1..456db5b48f 100644 --- a/src/soc/intel/cannonlake/include/soc/vr_config.h +++ b/src/soc/intel/cannonlake/include/soc/vr_config.h @@ -53,10 +53,18 @@ struct vr_config { /* AC and DC Loadline in 1/100 mOhms. Range is 0-6249 */ uint16_t ac_loadline; uint16_t dc_loadline; + + /* Thermal Design Current (TDC) Power Limit will take effect when + this is set to 0 */ + uint8_t tdc_disable; + + /* Thermal Design Current (TDC) Power Limit in 1/8 A units */ + uint16_t tdc_powerlimit; }; #define VR_CFG_AMP(i) (uint16_t)((i) * 4) #define VR_CFG_MOHMS(i) (uint16_t)((i) * 100) +#define VR_CFG_TDC_AMP(i) (uint16_t)((i) * 8) /* VrConfig Settings for 4 domains * 0 = System Agent, 1 = IA Core, @@ -85,6 +93,14 @@ enum vr_domain { [VR_GT_SLICED] = VR_CFG_MOHMS(gt_sl), \ } +#define VR_CFG_ALL_DOMAINS_TDC(sa, ia, gt_unsl, gt_sl) \ + { \ + [VR_SYSTEM_AGENT] = VR_CFG_TDC_AMP(sa), \ + [VR_IA_CORE] = VR_CFG_TDC_AMP(ia), \ + [VR_GT_UNSLICED] = VR_CFG_TDC_AMP(gt_unsl), \ + [VR_GT_SLICED] = VR_CFG_TDC_AMP(gt_sl), \ + } + void fill_vr_domain_config(void *params, int domain, const struct vr_config *cfg); diff --git a/src/soc/intel/cannonlake/vr_config.c b/src/soc/intel/cannonlake/vr_config.c index 5fadcf4023..bd73d15dd7 100644 --- a/src/soc/intel/cannonlake/vr_config.c +++ b/src/soc/intel/cannonlake/vr_config.c @@ -419,6 +419,96 @@ static uint16_t get_sku_voltagelimit(int domain) return 1520; } +static uint16_t get_sku_tdc_powerlimit(int domain) +{ + const uint16_t tdp = cpu_get_power_max(); + const config_t *cfg = config_of_soc(); + + static uint16_t mch_id = 0; + if (!mch_id) { + struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT); + mch_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff; + } + + switch (mch_id) { + case PCI_DEVICE_ID_INTEL_CML_ULT: + case PCI_DEVICE_ID_INTEL_CML_ULT_6_2: { + uint16_t tdc[NUM_VR_DOMAINS] = + VR_CFG_ALL_DOMAINS_TDC(4, 58, 22, 22); + + if (cfg->cpu_pl2_4_cfg == baseline) + tdc[VR_IA_CORE] = VR_CFG_TDC_AMP(48); + + return tdc[domain]; + } + case PCI_DEVICE_ID_INTEL_CML_ULT_2_2: { + const uint16_t tdc[NUM_VR_DOMAINS] = + VR_CFG_ALL_DOMAINS_TDC(4, 24, 22, 22); + return tdc[domain]; + } + case PCI_DEVICE_ID_INTEL_CML_H_4_2: { + uint16_t tdc[NUM_VR_DOMAINS] = + VR_CFG_ALL_DOMAINS_TDC(10, 80, 25, 25); + + if (cfg->cpu_pl2_4_cfg == baseline) + tdc[VR_IA_CORE] = VR_CFG_TDC_AMP(60); + + return tdc[domain]; + } + case PCI_DEVICE_ID_INTEL_CML_H: { + uint16_t tdc[NUM_VR_DOMAINS] = + VR_CFG_ALL_DOMAINS_TDC(10, 92, 25, 25); + + if (cfg->cpu_pl2_4_cfg == baseline) + tdc[VR_IA_CORE] = VR_CFG_TDC_AMP(80); + + return tdc[domain]; + } + case PCI_DEVICE_ID_INTEL_CML_H_8_2: { + uint16_t tdc[NUM_VR_DOMAINS] = + VR_CFG_ALL_DOMAINS_TDC(10, 125, 25, 25); + + if (tdp >= 65) /* 65W */ + tdc[VR_IA_CORE] = (cfg->cpu_pl2_4_cfg == baseline) ? + VR_CFG_TDC_AMP(117) : + VR_CFG_TDC_AMP(146); + else /* 45W */ + tdc[VR_IA_CORE] = (cfg->cpu_pl2_4_cfg == baseline) ? + VR_CFG_TDC_AMP(86) : + VR_CFG_TDC_AMP(125); + + return tdc[domain]; + } + case PCI_DEVICE_ID_INTEL_CML_S_G0G1_P0P1_6_2: { + uint16_t tdc[NUM_VR_DOMAINS] = + VR_CFG_ALL_DOMAINS_TDC(10, 74, 28, 28); + + if (tdp >= 125) /* 125W */ + tdc[VR_IA_CORE] = VR_CFG_TDC_AMP(132); + else if (tdp >= 65) /* 80W or 65W */ + tdc[VR_IA_CORE] = VR_CFG_TDC_AMP(104); + else /* 35W */ + tdc[VR_IA_CORE] = VR_CFG_TDC_AMP(74); + + return tdc[domain]; + } + case PCI_DEVICE_ID_INTEL_CML_S_P0P1_8_2: + case PCI_DEVICE_ID_INTEL_CML_S_P0P1_10_2: { + uint16_t tdc[NUM_VR_DOMAINS] = + VR_CFG_ALL_DOMAINS_TDC(10, 100, 28, 28); + + if (tdp > 35) /* 125W or 80W or 65W */ + tdc[VR_IA_CORE] = VR_CFG_TDC_AMP(175); + + return tdc[domain]; + } + default: + printk(BIOS_ERR, "ERROR: Unknown MCH (0x%x) in VR-config\n", mch_id); + } + + return 0; +} + void fill_vr_domain_config(void *params, int domain, const struct vr_config *chip_cfg) { @@ -463,4 +553,11 @@ void fill_vr_domain_config(void *params, vr_params->DcLoadline[domain] = cfg->dc_loadline; else vr_params->DcLoadline[domain] = get_sku_ac_dc_loadline(domain); + + vr_params->TdcEnable[domain] = !cfg->tdc_disable; + + if (cfg->tdc_powerlimit) + vr_params->TdcPowerLimit[domain] = cfg->tdc_powerlimit; + else + vr_params->TdcPowerLimit[domain] = get_sku_tdc_powerlimit(domain); } |