[coreboot-gerrit] Patch set updated for coreboot: 9746734 haswell: Misc power management setup and fixes

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Sat Dec 7 03:22:16 CET 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4333

-gerrit

commit 974673424914173c21ed2f9ef9ae5cce9f768bf1
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Fri Jun 28 14:40:38 2013 -0700

    haswell: Misc power management setup and fixes
    
    1) fix enable of power aware interrupt routing
    2) set BIOS_RESET_CPL to 3 instead of 1
    3) mirror PKG power limit values from MSR to MMIO on all SKUs
    4) mirror DDR power limit values from MMIO to MSR
    5) remove DMI settings that were from snb/ivb as they do
    not apply to haswell
    
    1) verify power aware interrupt routing is working by looking
    in /proc/interrupts to see interrupts routed to both cores
    instead of always to core0
    
    BEFORE: 58:       4943          0   PCI-MSI-edge      ahci
    AFTER:  58:       4766        334   PCI-MSI-edge      ahci
    
    2) read back BIOS_RESET_CPL to verify it is == 3
    
    localhost ~ # iotools mmio_read32 0xfed15da8
    0x00000003
    
    3) read PKG power limit from MMIO and verify it is the same
    as the MSR value
    
    localhost ~ # rdmsr 0 0x610
    0x0000809600dc8078
    localhost ~ # iotools mmio_read32 0xfed159a0
    0x00dc8078
    localhost ~ # iotools mmio_read32 0xfed159a4
    0x00008096
    
    4) read DDR power limit from MSR and verify it is the same
    as the MMIO value (note this is zero based on current MRC input)
    
    localhost ~ # rdmsr 0 0x618
    0x0000000000000000
    localhost ~ # iotools mmio_read32 0xfed158e0
    0x00000000
    localhost ~ # iotools mmio_read32 0xfed158e4
    0x00000000
    
    Change-Id: I6cc4c5b2a81304e9deaad8cffcaf604ebad60b29
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Reviewed-on: https://gerrit.chromium.org/gerrit/60544
---
 src/cpu/intel/haswell/haswell.h             |  1 +
 src/cpu/intel/haswell/haswell_init.c        | 13 ++++-
 src/northbridge/intel/haswell/haswell.h     |  6 ++
 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 cd007c1..3875217 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 b2e6eaf..fb78df4 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 b350226..7d451a9 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 ac61ca4..be1b614 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;
 }



More information about the coreboot-gerrit mailing list