b824f7dbae
If the board doesn't provide VRconfig in devicetree make sure to use the lookup table for IccMax instead of defaults for some mobile SoC. Also use decimal values instead of hex. Change-Id: If31063f9b483a3bbd6cc90df1c1b76b4efc66445 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/37598 Reviewed-by: Maxim Polyakov <max.senia.poliak@gmail.com> Reviewed-by: Michael Niewöhner Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
353 lines
11 KiB
C
353 lines
11 KiB
C
/*
|
|
* This file is part of the coreboot project.
|
|
*
|
|
* Copyright 2015 Google Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include <device/pci_ids.h>
|
|
#include <device/pci_ops.h>
|
|
#include <fsp/api.h>
|
|
#include <soc/ramstage.h>
|
|
#include <soc/vr_config.h>
|
|
#include <console/console.h>
|
|
#include <intelblocks/cpulib.h>
|
|
|
|
/* Default values for domain configuration. PSI3 and PSI4 are disabled. */
|
|
static const struct vr_config default_configs[NUM_VR_DOMAINS] = {
|
|
[VR_SYSTEM_AGENT] = {
|
|
.vr_config_enable = 1,
|
|
.psi1threshold = VR_CFG_AMP(20),
|
|
.psi2threshold = VR_CFG_AMP(4),
|
|
.psi3threshold = VR_CFG_AMP(1),
|
|
.psi3enable = 0,
|
|
.psi4enable = 0,
|
|
.imon_slope = 0,
|
|
.imon_offset = 0,
|
|
.icc_max = 0,
|
|
.voltage_limit = 1520,
|
|
},
|
|
[VR_IA_CORE] = {
|
|
.vr_config_enable = 1,
|
|
.psi1threshold = VR_CFG_AMP(20),
|
|
.psi2threshold = VR_CFG_AMP(5),
|
|
.psi3threshold = VR_CFG_AMP(1),
|
|
.psi3enable = 0,
|
|
.psi4enable = 0,
|
|
.imon_slope = 0,
|
|
.imon_offset = 0,
|
|
.icc_max = 0,
|
|
.voltage_limit = 1520,
|
|
},
|
|
[VR_GT_UNSLICED] = {
|
|
.vr_config_enable = 1,
|
|
.psi1threshold = VR_CFG_AMP(20),
|
|
.psi2threshold = VR_CFG_AMP(5),
|
|
.psi3threshold = VR_CFG_AMP(1),
|
|
.psi3enable = 0,
|
|
.psi4enable = 0,
|
|
.imon_slope = 0,
|
|
.imon_offset = 0,
|
|
.icc_max = 0,
|
|
.voltage_limit = 1520,
|
|
},
|
|
[VR_GT_SLICED] = {
|
|
.vr_config_enable = 1,
|
|
.psi1threshold = VR_CFG_AMP(20),
|
|
.psi2threshold = VR_CFG_AMP(5),
|
|
.psi3threshold = VR_CFG_AMP(1),
|
|
.psi3enable = 0,
|
|
.psi4enable = 0,
|
|
.imon_slope = 0,
|
|
.imon_offset = 0,
|
|
.icc_max = 0,
|
|
.voltage_limit = 1520,
|
|
},
|
|
};
|
|
|
|
static uint16_t get_sku_icc_max(int domain)
|
|
{
|
|
const uint16_t tdp = cpu_get_power_max();
|
|
|
|
static uint16_t mch_id = 0, igd_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;
|
|
}
|
|
if (!igd_id) {
|
|
struct device *dev = pcidev_path_on_root(SA_DEVFN_IGD);
|
|
igd_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
|
|
}
|
|
|
|
/*
|
|
* Iccmax table from Doc #559100 Section 7.2 DC Specifications, the
|
|
* Iccmax is the same among KBL-Y but KBL-U/R.
|
|
* Addendum for AML-Y #594883, IccMax for IA core is 28A.
|
|
* KBL-S #335195, KBL-H #335190, SKL-S #332687, SKL-H #332986,
|
|
* SKL-U/Y #332990
|
|
*
|
|
* Platform Segment SA IA GT (GT/GTx)
|
|
* ---------------------------------------------------------------------
|
|
* KBL/SKL-S (95W) quad 11.1 100 45
|
|
* SKL-S (80W) quad 11.1 82 45
|
|
* KBL/SKL-S (65W) quad 11.1 79 45
|
|
* SKL-S (45W) quad 11.1 70 0
|
|
* KBL/SKL-S (35W) quad 11.1 66 35
|
|
* SKL-S (25W) quad 11.1 55 35
|
|
*
|
|
* KBL/SKL-S (54W) dual 11.1 58 48
|
|
* KBL/SKL-S (51W) dual 11.1 45 48
|
|
* KBL/SKL-S (35W) dual 11.1 40 48
|
|
*
|
|
* SKL-H + OPC (65W) GT4 quad 8 74 105/24
|
|
* SKL-H + OPC (45W) GT4 quad 8 74 94/20
|
|
* SKL-H + OPC (35W) GT4 quad 8 66 94/20
|
|
*
|
|
* SKL-H (35W) GT2 dual 11.1 60 55
|
|
*
|
|
* KBL/SKL-H (45W) GT2 quad 11.1 68 55
|
|
* KBL-H (18W) GT2 quad 6.6 60 55
|
|
*
|
|
* SKL-U + OPC (28W) GT3 dual 5.1 32 57/19
|
|
* SKL-U + OPC (15W) GT3 dual 5.1 29 57/19
|
|
* SKL-U (15W) GT2 dual 4.5 29 31
|
|
*
|
|
* KBL-U + OPC (28W) GT3 dual 5.1 32 57/19
|
|
* KBL-U + OPC (15W) GT3 dual 5.1 32 57/19
|
|
* KBL-U (15W) GT1/2 dual 4.5 32 31
|
|
* KBL-U [*] (15W) GT1 quad 4.5 29 31
|
|
*
|
|
* KBL-U/R (15W) GT2 quad 6 64 31
|
|
*
|
|
* SKL/KBL-Y (6W) 4.1 24 24
|
|
* SKL/KBL-Y (4.5W) 4.1 24 24
|
|
*
|
|
* [*] Pentium/Celeron CPUs with HD Graphics 610
|
|
*/
|
|
|
|
switch (mch_id) {
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_S_2: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_S: {
|
|
uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(11.1, 40, 48, 48);
|
|
if (tdp >= 54)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(58);
|
|
else if (tdp >= 51)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(45);
|
|
|
|
return icc_max[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_S_4: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_DT_2: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_DT: {
|
|
uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(11.1, 55, 45, 45);
|
|
if (tdp >= 91)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(100);
|
|
else if (tdp >= 80)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(82);
|
|
else if (tdp >= 65)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(79);
|
|
else if (tdp >= 45) {
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(70);
|
|
icc_max[VR_GT_SLICED] = 0;
|
|
icc_max[VR_GT_UNSLICED] = 0;
|
|
} else if (tdp >= 25) {
|
|
if (tdp >= 35)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(66);
|
|
|
|
icc_max[VR_GT_SLICED] = VR_CFG_AMP(35);
|
|
icc_max[VR_GT_UNSLICED] = VR_CFG_AMP(35);
|
|
}
|
|
|
|
return icc_max[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_H_4: {
|
|
uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(11.1, 60, 94, 20);
|
|
if (tdp >= 45) {
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(74);
|
|
if (tdp >= 65) {
|
|
icc_max[VR_GT_SLICED] = VR_CFG_AMP(105);
|
|
icc_max[VR_GT_UNSLICED] = VR_CFG_AMP(24);
|
|
}
|
|
}
|
|
return icc_max[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_H_2: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_H_EM: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_H: {
|
|
uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(6.6, 60, 55, 55);
|
|
if (tdp >= 35) {
|
|
if (tdp >= 45)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(68);
|
|
|
|
icc_max[VR_SYSTEM_AGENT] = VR_CFG_AMP(11.1);
|
|
}
|
|
|
|
return icc_max[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_U: {
|
|
uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(5.1, 29, 57, 19);
|
|
if (tdp >= 28)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(32);
|
|
else if (igd_id != PCI_DEVICE_ID_INTEL_SKL_GT3E_SULTM_1) {
|
|
const uint16_t icc_max_gt2[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_ICC(4.5, 29, 31, 31);
|
|
|
|
return icc_max_gt2[domain];
|
|
}
|
|
return icc_max[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_KBL_U_R: {
|
|
const uint16_t icc_max[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_ICC(6, 64, 31, 31);
|
|
return icc_max[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_Y: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_Y: {
|
|
uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(4.1, 24, 24, 24);
|
|
|
|
if (igd_id == PCI_DEVICE_ID_INTEL_AML_GT2_ULX)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(28);
|
|
|
|
return icc_max[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_U: {
|
|
uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(4.5, 32, 31, 31);
|
|
|
|
if (igd_id == PCI_DEVICE_ID_INTEL_KBL_GT1_SULTM)
|
|
icc_max[VR_IA_CORE] = VR_CFG_AMP(29);
|
|
|
|
else if ((igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_1) ||
|
|
(igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_2)) {
|
|
const uint16_t icc_max_gt3[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_ICC(5.1, 32, 57, 19);
|
|
|
|
return icc_max_gt3[domain];
|
|
}
|
|
|
|
return icc_max[domain];
|
|
}
|
|
default:
|
|
printk(BIOS_ERR, "ERROR: Unknown MCH (0x%x) in VR-config\n", mch_id);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static uint16_t get_sku_ac_dc_loadline(const int domain)
|
|
{
|
|
static uint16_t mch_id = 0, igd_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;
|
|
}
|
|
if (!igd_id) {
|
|
struct device *dev = pcidev_path_on_root(SA_DEVFN_IGD);
|
|
igd_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
|
|
}
|
|
|
|
switch (mch_id) {
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_S_2: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_S_4: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_S: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_DT: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_DT_2: {
|
|
/* SA Loadline is not specified */
|
|
const uint16_t loadline[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_LOADLINE(0, 2.1, 3.1, 3.1);
|
|
return loadline[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_H_2: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_H_EM: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_H_4: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_H: {
|
|
const uint16_t loadline[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_LOADLINE(10, 1.8, 2.65, 2.65);
|
|
|
|
if (igd_id == PCI_DEVICE_ID_INTEL_SKL_GT4_SHALM) {
|
|
const uint16_t loadline_gt4[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_LOADLINE(6, 1.6, 1.4, 6);
|
|
return loadline_gt4[domain];
|
|
}
|
|
|
|
return loadline[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_Y: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_Y: {
|
|
uint16_t loadline[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_LOADLINE(18, 5.9, 5.7, 5.7);
|
|
|
|
if (igd_id == PCI_DEVICE_ID_INTEL_AML_GT2_ULX)
|
|
loadline[VR_IA_CORE] = VR_CFG_MOHMS(4);
|
|
|
|
return loadline[domain];
|
|
}
|
|
case PCI_DEVICE_ID_INTEL_SKL_ID_U: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_U_R: /* fallthrough */
|
|
case PCI_DEVICE_ID_INTEL_KBL_ID_U: {
|
|
uint16_t loadline[NUM_VR_DOMAINS] =
|
|
VR_CFG_ALL_DOMAINS_LOADLINE(10.3, 2.4, 3.1, 3.1);
|
|
|
|
if ((igd_id == PCI_DEVICE_ID_INTEL_SKL_GT3E_SULTM_1) ||
|
|
(igd_id == PCI_DEVICE_ID_INTEL_SKL_GT3E_SULTM_2) ||
|
|
(igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_1) ||
|
|
(igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_2)) {
|
|
loadline[VR_GT_UNSLICED] = VR_CFG_MOHMS(2);
|
|
loadline[VR_GT_SLICED] = VR_CFG_MOHMS(6);
|
|
}
|
|
|
|
return loadline[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)
|
|
{
|
|
FSP_SIL_UPD *vr_params = (FSP_SIL_UPD *)params;
|
|
const struct vr_config *cfg;
|
|
|
|
if (domain < 0 || domain >= NUM_VR_DOMAINS)
|
|
return;
|
|
|
|
/* Use device tree override if requested. */
|
|
if (chip_cfg->vr_config_enable)
|
|
cfg = chip_cfg;
|
|
else
|
|
cfg = &default_configs[domain];
|
|
|
|
vr_params->VrConfigEnable[domain] = cfg->vr_config_enable;
|
|
vr_params->Psi1Threshold[domain] = cfg->psi1threshold;
|
|
vr_params->Psi2Threshold[domain] = cfg->psi2threshold;
|
|
vr_params->Psi3Threshold[domain] = cfg->psi3threshold;
|
|
vr_params->Psi3Enable[domain] = cfg->psi3enable;
|
|
vr_params->Psi4Enable[domain] = cfg->psi4enable;
|
|
vr_params->ImonSlope[domain] = cfg->imon_slope;
|
|
vr_params->ImonOffset[domain] = cfg->imon_offset;
|
|
|
|
/* If board provided non-zero value, use it. */
|
|
if (cfg->icc_max)
|
|
vr_params->IccMax[domain] = cfg->icc_max;
|
|
else
|
|
vr_params->IccMax[domain] = get_sku_icc_max(domain);
|
|
vr_params->VrVoltageLimit[domain] = cfg->voltage_limit;
|
|
|
|
if (cfg->ac_loadline)
|
|
vr_params->AcLoadline[domain] = cfg->ac_loadline;
|
|
else
|
|
vr_params->AcLoadline[domain] = get_sku_ac_dc_loadline(domain);
|
|
if (cfg->dc_loadline)
|
|
vr_params->DcLoadline[domain] = cfg->dc_loadline;
|
|
else
|
|
vr_params->DcLoadline[domain] = get_sku_ac_dc_loadline(domain);
|
|
}
|