siemens/mc_apl1: Fix accuracy issue with IDT PMIC

Due to an accuracy issue on IMON in the IDT PMIC, the reported system
power consumption was higher than the actual consumption. To prevent
this problem, a logic must be implemented in mainboard_init(). This logic
consists of slope and offset as constants for Vcc and Vnn, which need
to be programmed by coreboot. This fix compensates for the accuracy
issue.

Change-Id: I77faf95951d03ac6ce97a6721dba6e8466122a25
Signed-off-by: Mario Scheithauer <mario.scheithauer@siemens.com>
Reviewed-on: https://review.coreboot.org/25585
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
This commit is contained in:
Mario Scheithauer 2018-04-10 12:40:11 +02:00 committed by Martin Roth
parent 5d27f40418
commit 0af272c1a9
1 changed files with 82 additions and 1 deletions

View File

@ -15,14 +15,17 @@
*/
#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <gpio.h>
#include <hwilib.h>
#include <i210.h>
#include <intelblocks/cpulib.h>
#include <intelblocks/lpc_lib.h>
#include <intelblocks/pcr.h>
#include <intelblocks/systemagent.h>
#include <soc/pci_devs.h>
#include <soc/pcr_ids.h>
#include <string.h>
@ -35,6 +38,11 @@
#define MAX_PATH_DEPTH 12
#define MAX_NUM_MAPPINGS 10
#define BIOS_MAILBOX_WAIT_MAX_MS 1000
#define BIOS_MAILBOX_DATA 0x7080
#define BIOS_MAILBOX_INTERFACE 0x7084
#define RUN_BUSY_STS (1 << 31)
/** \brief This function can decide if a given MAC address is valid or not.
* Currently, addresses filled with 0xff or 0x00 are not valid.
* @param mac Buffer to the MAC address to check
@ -110,6 +118,77 @@ enum cb_err mainboard_get_mac_address(struct device *dev, uint8_t mac[6])
return CB_ERR;
}
/** \brief This function fixes an accuracy issue with IDT PMIC.
* The current reported system power consumption is higher than the
* actual consumption. With a correction of slope and offset for Vcc
* and Vnn, the issue is solved.
*/
static void config_pmic_imon(void)
{
struct stopwatch sw;
uint32_t power_max;
printk(BIOS_DEBUG, "PMIC: Configure PMIC IMON - Start\n");
/* Calculate CPU TDP in mW */
power_max = cpu_get_power_max();
printk(BIOS_INFO, "PMIC: CPU TDP %d mW.\n", power_max);
/*
* Fix Vnn slope and offset value.
* slope = 0x4a4 # 2.32
* offset = 0xfa0d # -2.975
*/
stopwatch_init_msecs_expire(&sw, BIOS_MAILBOX_WAIT_MAX_MS);
/* Read P_CR_BIOS_MAILBOX_INTERFACE_0_0_0_MCHBAR and check RUN_BUSY. */
while ((MCHBAR32(BIOS_MAILBOX_INTERFACE) & RUN_BUSY_STS)) {
if (stopwatch_expired(&sw)) {
printk(BIOS_ERR, "PMIC: Power consumption measurement "
"setup fails for Vnn.\n");
return;
}
}
/* Set Vnn values into P_CR_BIOS_MAILBOX_DATA_0_0_0_MCHBAR. */
MCHBAR32(BIOS_MAILBOX_DATA) = 0xfa0d04a4;
/* Set command, address and busy bit. */
MCHBAR32(BIOS_MAILBOX_INTERFACE) = 0x8000011d;
printk(BIOS_DEBUG, "PMIC: Fix Vnn slope and offset value.\n");
/*
* Fix Vcc slope and offset value.
* Premium and High SKU:
* slope = 0x466 # 2.2
* offset = 0xe833 # -11.9
* Low and Intermediate SKU:
* slope = 0x3b3 # 1.85
* offset = 0xed33 # -9.4
*/
stopwatch_init_msecs_expire(&sw, BIOS_MAILBOX_WAIT_MAX_MS);
while ((MCHBAR32(BIOS_MAILBOX_INTERFACE) & RUN_BUSY_STS)) {
if (stopwatch_expired(&sw)) {
printk(BIOS_ERR, "PMIC: Power consumption measurement "
"setup fails for Vcc.\n");
return;
}
}
/*
* CPU TDP limit between Premium/High and Low/Intermediate SKU
* is 9010 mW.
*/
if (power_max > 9010) {
MCHBAR32(BIOS_MAILBOX_DATA) = 0xe8330466;
MCHBAR32(BIOS_MAILBOX_INTERFACE) = 0x8000001d;
printk(BIOS_INFO, "PMIC: Fix Vcc for Premium SKU.\n");
} else {
MCHBAR32(BIOS_MAILBOX_DATA) = 0xed3303b3;
MCHBAR32(BIOS_MAILBOX_INTERFACE) = 0x8000001d;
printk(BIOS_INFO, "PMIC: Fix Vcc for Low SKU.\n");
}
printk(BIOS_DEBUG, "PMIC: Configure PMIC IMON - End\n");
}
static void mainboard_init(void *chip_info)
{
const struct pad_config *pads;
@ -117,6 +196,8 @@ static void mainboard_init(void *chip_info)
pads = brd_gpio_table(&num);
gpio_configure_pads(pads, num);
config_pmic_imon();
}
static void mainboard_final(void *chip_info)
@ -125,7 +206,7 @@ static void mainboard_final(void *chip_info)
uint16_t cmd = 0;
device_t dev = NULL;
/**
/*
* Set up the DP2LVDS converter.
* ptn3460_init() may only be executed after i2c bus init.
*/