summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/intel/haswell/haswell.h1
-rw-r--r--src/cpu/intel/haswell/haswell_init.c13
-rw-r--r--src/northbridge/intel/haswell/haswell.h6
-rw-r--r--src/northbridge/intel/haswell/northbridge.c88
4 files changed, 26 insertions, 82 deletions
diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h
index cd007c1f7e..387521722a 100644
--- a/src/cpu/intel/haswell/haswell.h
+++ b/src/cpu/intel/haswell/haswell.h
@@ -85,6 +85,7 @@
#define MSR_VR_CURRENT_CONFIG 0x601
#define MSR_PKG_POWER_SKU_UNIT 0x606
#define MSR_PKG_POWER_SKU 0x614
+#define MSR_DDR_RAPL_LIMIT 0x618
#define MSR_PP0_POWER_LIMIT 0x638
#define MSR_PP1_POWER_LIMIT 0x640
diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c
index b2e6eaf324..fb78df419a 100644
--- a/src/cpu/intel/haswell/haswell_init.c
+++ b/src/cpu/intel/haswell/haswell_init.c
@@ -361,7 +361,7 @@ void set_power_limits(u8 power_limit_1_time)
u8 power_limit_1_val;
if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr))
- return;
+ power_limit_1_time = 28;
if (!(msr.lo & PLATFORM_INFO_SET_TDP))
return;
@@ -401,10 +401,19 @@ void set_power_limits(u8 power_limit_1_time)
limit.hi = 0;
limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK;
limit.hi |= PKG_POWER_LIMIT_EN;
- /* Power limit 2 time is only programmable on SNB EP/EX */
+ /* Power limit 2 time is only programmable on server SKU */
wrmsr(MSR_PKG_POWER_LIMIT, limit);
+ /* Set power limit values in MCHBAR as well */
+ MCHBAR32(MCH_PKG_POWER_LIMIT_LO) = limit.lo;
+ MCHBAR32(MCH_PKG_POWER_LIMIT_HI) = limit.hi;
+
+ /* Set DDR RAPL power limit by copying from MMIO to MSR */
+ msr.lo = MCHBAR32(MCH_DDR_POWER_LIMIT_LO);
+ msr.hi = MCHBAR32(MCH_DDR_POWER_LIMIT_HI);
+ wrmsr(MSR_DDR_RAPL_LIMIT, msr);
+
/* Use nominal TDP values for CPUs with configurable TDP */
if (cpu_config_tdp_levels()) {
msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
diff --git a/src/northbridge/intel/haswell/haswell.h b/src/northbridge/intel/haswell/haswell.h
index b3502267a5..7d451a91da 100644
--- a/src/northbridge/intel/haswell/haswell.h
+++ b/src/northbridge/intel/haswell/haswell.h
@@ -125,6 +125,12 @@
#define BIOS_RESET_CPL 0x5da8 /* 8bit */
+/* Some power MSRs are also represented in MCHBAR */
+#define MCH_PKG_POWER_LIMIT_LO 0x59a0
+#define MCH_PKG_POWER_LIMIT_HI 0x59a4
+#define MCH_DDR_POWER_LIMIT_LO 0x58e0
+#define MCH_DDR_POWER_LIMIT_HI 0x58e4
+
/*
* EPBAR - Egress Port Root Complex Register Block
*/
diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c
index ac61ca47ee..be1b61456b 100644
--- a/src/northbridge/intel/haswell/northbridge.c
+++ b/src/northbridge/intel/haswell/northbridge.c
@@ -436,84 +436,22 @@ static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
}
}
-static void northbridge_dmi_init(struct device *dev)
-{
- u32 reg32;
-
- /* Clear error status bits */
- DMIBAR32(0x1c4) = 0xffffffff;
- DMIBAR32(0x1d0) = 0xffffffff;
-
- /* Steps prior to DMI ASPM */
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
- reg32 = DMIBAR32(0x250);
- reg32 &= ~((1 << 22)|(1 << 20));
- reg32 |= (1 << 21);
- DMIBAR32(0x250) = reg32;
- }
-
- reg32 = DMIBAR32(0x238);
- reg32 |= (1 << 29);
- DMIBAR32(0x238) = reg32;
-
- if (bridge_silicon_revision() >= SNB_STEP_D0) {
- reg32 = DMIBAR32(0x1f8);
- reg32 |= (1 << 16);
- DMIBAR32(0x1f8) = reg32;
- } else if (bridge_silicon_revision() >= SNB_STEP_D1) {
- reg32 = DMIBAR32(0x1f8);
- reg32 &= ~(1 << 26);
- reg32 |= (1 << 16);
- DMIBAR32(0x1f8) = reg32;
-
- reg32 = DMIBAR32(0x1fc);
- reg32 |= (1 << 12) | (1 << 23);
- DMIBAR32(0x1fc) = reg32;
- }
-
- /* Enable ASPM on SNB link, should happen before PCH link */
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
- reg32 = DMIBAR32(0xd04);
- reg32 |= (1 << 4);
- DMIBAR32(0xd04) = reg32;
- }
-
- reg32 = DMIBAR32(0x88);
- reg32 |= (1 << 1) | (1 << 0);
- DMIBAR32(0x88) = reg32;
-}
-
static void northbridge_init(struct device *dev)
{
- u8 bios_reset_cpl;
- u32 bridge_type;
+ u8 bios_reset_cpl, pair;
- northbridge_dmi_init(dev);
-
- bridge_type = MCHBAR32(0x5f10);
- bridge_type &= ~0xff;
-
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
- /* Enable Power Aware Interrupt Routing */
- u8 pair = MCHBAR8(0x5418);
- pair &= ~0xf; /* Clear 3:0 */
- pair |= 0x4; /* Fixed Priority */
- MCHBAR8(0x5418) = pair;
-
- /* 30h for IvyBridge */
- bridge_type |= 0x30;
- } else {
- /* 20h for Sandybridge */
- bridge_type |= 0x20;
- }
- MCHBAR32(0x5f10) = bridge_type;
+ /* Enable Power Aware Interrupt Routing */
+ pair = MCHBAR8(0x5418);
+ pair &= ~0x7; /* Clear 2:0 */
+ pair |= 0x4; /* Fixed Priority */
+ MCHBAR8(0x5418) = pair;
/*
- * Set bit 0 of BIOS_RESET_CPL to indicate to the CPU
+ * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
* that BIOS has initialized memory and power management
*/
bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
- bios_reset_cpl |= 1;
+ bios_reset_cpl |= 3;
MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n");
@@ -521,16 +459,6 @@ static void northbridge_init(struct device *dev)
mdelay(1);
set_power_limits(28);
- /*
- * CPUs with configurable TDP also need power limits set
- * in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT.
- */
- if (cpu_config_tdp_levels()) {
- msr_t msr = rdmsr(MSR_PKG_POWER_LIMIT);
- MCHBAR32(0x59A0) = msr.lo;
- MCHBAR32(0x59A4) = msr.hi;
- }
-
/* Set here before graphics PM init */
MCHBAR32(0x5500) = 0x00100001;
}