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>
This commit is contained in:
Marx Wang 2020-02-07 16:44:14 +08:00 committed by Patrick Georgi
parent 75cd6d2a97
commit 9318d6d625
2 changed files with 113 additions and 0 deletions

View File

@ -53,10 +53,18 @@ struct vr_config {
/* AC and DC Loadline in 1/100 mOhms. Range is 0-6249 */ /* AC and DC Loadline in 1/100 mOhms. Range is 0-6249 */
uint16_t ac_loadline; uint16_t ac_loadline;
uint16_t dc_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_AMP(i) (uint16_t)((i) * 4)
#define VR_CFG_MOHMS(i) (uint16_t)((i) * 100) #define VR_CFG_MOHMS(i) (uint16_t)((i) * 100)
#define VR_CFG_TDC_AMP(i) (uint16_t)((i) * 8)
/* VrConfig Settings for 4 domains /* VrConfig Settings for 4 domains
* 0 = System Agent, 1 = IA Core, * 0 = System Agent, 1 = IA Core,
@ -85,6 +93,14 @@ enum vr_domain {
[VR_GT_SLICED] = VR_CFG_MOHMS(gt_sl), \ [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, void fill_vr_domain_config(void *params,
int domain, const struct vr_config *cfg); int domain, const struct vr_config *cfg);

View File

@ -419,6 +419,96 @@ static uint16_t get_sku_voltagelimit(int domain)
return 1520; 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, void fill_vr_domain_config(void *params,
int domain, const struct vr_config *chip_cfg) 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; vr_params->DcLoadline[domain] = cfg->dc_loadline;
else else
vr_params->DcLoadline[domain] = get_sku_ac_dc_loadline(domain); 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);
} }