diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/intel/haswell/haswell.h | 1 | ||||
-rw-r--r-- | src/cpu/intel/haswell/haswell_init.c | 13 | ||||
-rw-r--r-- | src/northbridge/intel/haswell/haswell.h | 6 | ||||
-rw-r--r-- | src/northbridge/intel/haswell/northbridge.c | 88 |
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; } |