haswell: Configure PCH power sharing for ULT
This reads PCH power levels via PCODE mailbox and writes the values into the PMSYNC registers as indicated in the BWG. Change-Id: Iddcdef9b7deb6365f874f629599d1f7376c9a190 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/49329 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/4143 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
parent
f24262d018
commit
e1e87e0ed6
|
@ -107,6 +107,8 @@
|
||||||
#define MAILBOX_BIOS_CMD_WRITE_PCS 2
|
#define MAILBOX_BIOS_CMD_WRITE_PCS 2
|
||||||
#define MAILBOX_BIOS_CMD_READ_CALIBRATION 0x509
|
#define MAILBOX_BIOS_CMD_READ_CALIBRATION 0x509
|
||||||
#define MAILBOX_BIOS_CMD_FSM_MEASURE_INTVL 0x909
|
#define MAILBOX_BIOS_CMD_FSM_MEASURE_INTVL 0x909
|
||||||
|
#define MAILBOX_BIOS_CMD_READ_PCH_POWER 0xa
|
||||||
|
#define MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT 0xb
|
||||||
/* Errors are returned back in bits 7:0. */
|
/* Errors are returned back in bits 7:0. */
|
||||||
#define MAILBOX_BIOS_ERROR_NONE 0
|
#define MAILBOX_BIOS_ERROR_NONE 0
|
||||||
#define MAILBOX_BIOS_ERROR_INVALID_COMMAND 1
|
#define MAILBOX_BIOS_ERROR_INVALID_COMMAND 1
|
||||||
|
|
|
@ -274,6 +274,71 @@ static void calibrate_24mhz_bclk(void)
|
||||||
MCHBAR32(BIOS_MAILBOX_DATA));
|
MCHBAR32(BIOS_MAILBOX_DATA));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 pcode_mailbox_read(u32 command)
|
||||||
|
{
|
||||||
|
if (pcode_ready() < 0) {
|
||||||
|
printk(BIOS_ERR, "PCODE: mailbox timeout on wait ready.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send command and start transaction */
|
||||||
|
MCHBAR32(BIOS_MAILBOX_INTERFACE) = command | MAILBOX_RUN_BUSY;
|
||||||
|
|
||||||
|
if (pcode_ready() < 0) {
|
||||||
|
printk(BIOS_ERR, "PCODE: mailbox timeout on completion.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read mailbox */
|
||||||
|
return MCHBAR32(BIOS_MAILBOX_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void configure_pch_power_sharing(void)
|
||||||
|
{
|
||||||
|
u32 pch_power, pch_power_ext, pmsync, pmsync2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Read PCH Power levels from PCODE */
|
||||||
|
pch_power = pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER);
|
||||||
|
pch_power_ext = pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT);
|
||||||
|
|
||||||
|
printk(BIOS_INFO, "PCH Power: PCODE Levels 0x%08x 0x%08x\n",
|
||||||
|
pch_power, pch_power_ext);
|
||||||
|
|
||||||
|
pmsync = RCBA32(PMSYNC_CONFIG);
|
||||||
|
pmsync2 = RCBA32(PMSYNC_CONFIG2);
|
||||||
|
|
||||||
|
/* Program PMSYNC_TPR_CONFIG PCH power limit values
|
||||||
|
* pmsync[0:4] = mailbox[0:5]
|
||||||
|
* pmsync[8:12] = mailbox[6:11]
|
||||||
|
* pmsync[16:20] = mailbox[12:17]
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
u32 level = pch_power & 0x3f;
|
||||||
|
pch_power >>= 6;
|
||||||
|
pmsync &= ~(0x1f << (i * 8));
|
||||||
|
pmsync |= (level & 0x1f) << (i * 8);
|
||||||
|
}
|
||||||
|
RCBA32(PMSYNC_CONFIG) = pmsync;
|
||||||
|
|
||||||
|
/* Program PMSYNC_TPR_CONFIG2 Extended PCH power limit values
|
||||||
|
* pmsync2[0:4] = mailbox[23:18]
|
||||||
|
* pmsync2[8:12] = mailbox_ext[6:11]
|
||||||
|
* pmsync2[16:20] = mailbox_ext[12:17]
|
||||||
|
* pmsync2[24:28] = mailbox_ext[18:22]
|
||||||
|
*/
|
||||||
|
pmsync2 &= ~0x1f;
|
||||||
|
pmsync2 |= pch_power & 0x1f;
|
||||||
|
|
||||||
|
for (i = 1; i < 4; i++) {
|
||||||
|
u32 level = pch_power_ext & 0x3f;
|
||||||
|
pch_power_ext >>= 6;
|
||||||
|
pmsync2 &= ~(0x1f << (i * 8));
|
||||||
|
pmsync2 |= (level & 0x1f) << (i * 8);
|
||||||
|
}
|
||||||
|
RCBA32(PMSYNC_CONFIG2) = pmsync2;
|
||||||
|
}
|
||||||
|
|
||||||
int cpu_config_tdp_levels(void)
|
int cpu_config_tdp_levels(void)
|
||||||
{
|
{
|
||||||
msr_t platform_info;
|
msr_t platform_info;
|
||||||
|
@ -574,8 +639,10 @@ static void bsp_init_before_ap_bringup(struct bus *cpu_bus)
|
||||||
x86_setup_var_mtrrs(cpuid_eax(0x80000008) & 0xff, 2);
|
x86_setup_var_mtrrs(cpuid_eax(0x80000008) & 0xff, 2);
|
||||||
x86_mtrr_check();
|
x86_mtrr_check();
|
||||||
|
|
||||||
if (is_ult())
|
if (is_ult()) {
|
||||||
calibrate_24mhz_bclk();
|
calibrate_24mhz_bclk();
|
||||||
|
configure_pch_power_sharing();
|
||||||
|
}
|
||||||
|
|
||||||
/* Call through the cpu driver's initialization. */
|
/* Call through the cpu driver's initialization. */
|
||||||
cpu_initialize(0);
|
cpu_initialize(0);
|
||||||
|
|
|
@ -54,6 +54,9 @@ void intel_pch_finalize_smm(void)
|
||||||
/* GEN_PMCON Lock */
|
/* GEN_PMCON Lock */
|
||||||
pci_or_config8(PCH_LPC_DEV, 0xa6, (1 << 1) | (1 << 2));
|
pci_or_config8(PCH_LPC_DEV, 0xa6, (1 << 1) | (1 << 2));
|
||||||
|
|
||||||
|
/* PMSYNC */
|
||||||
|
RCBA32_OR(PMSYNC_CONFIG, (1 << 31));
|
||||||
|
|
||||||
/* R/WO registers */
|
/* R/WO registers */
|
||||||
RCBA32(0x21a4) = RCBA32(0x21a4);
|
RCBA32(0x21a4) = RCBA32(0x21a4);
|
||||||
pci_write_config32(PCI_DEV(0, 27, 0), 0x74,
|
pci_write_config32(PCI_DEV(0, 27, 0), 0x74,
|
||||||
|
|
|
@ -574,6 +574,8 @@ void set_gpio(int gpio_num, int value);
|
||||||
#define D19IR 0x3168 /* 16bit */
|
#define D19IR 0x3168 /* 16bit */
|
||||||
#define ACPIIRQEN 0x31e0 /* 32bit */
|
#define ACPIIRQEN 0x31e0 /* 32bit */
|
||||||
#define OIC 0x31fe /* 16bit */
|
#define OIC 0x31fe /* 16bit */
|
||||||
|
#define PMSYNC_CONFIG 0x33c4 /* 32bit */
|
||||||
|
#define PMSYNC_CONFIG2 0x33cc /* 32bit */
|
||||||
#define SOFT_RESET_CTRL 0x38f4
|
#define SOFT_RESET_CTRL 0x38f4
|
||||||
#define SOFT_RESET_DATA 0x38f8
|
#define SOFT_RESET_DATA 0x38f8
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue