[coreboot] New patch to review for coreboot: 210d4c7 lynxpoint: Fix ELOG logging of power management events

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Mar 19 01:59:34 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/2817

-gerrit

commit 210d4c7d5d67cb040bb3adfd7f47f96468659464
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Fri Mar 8 17:16:37 2013 -0800

    lynxpoint: Fix ELOG logging of power management events
    
    This is updated to handle LynxPoint-H and LynxPoint-LP
    and a new wake event is added for the power button.
    
    Boot, suspend/resume, reboot, etc on WTM2
    and then check the event log to see if expected events
    have been added.
    
    Change-Id: I15cbc3901d81f4fd77cc04de37ff5fa048f9d3e8
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/include/elog.h                     |   1 +
 src/southbridge/intel/lynxpoint/elog.c | 119 ++++++++++++++++++++++++++-------
 2 files changed, 97 insertions(+), 23 deletions(-)

diff --git a/src/include/elog.h b/src/include/elog.h
index a5b5a77..a65893c 100644
--- a/src/include/elog.h
+++ b/src/include/elog.h
@@ -113,6 +113,7 @@
 #define  ELOG_WAKE_SOURCE_RTC              0x03
 #define  ELOG_WAKE_SOURCE_GPIO             0x04
 #define  ELOG_WAKE_SOURCE_SMBUS            0x05
+#define  ELOG_WAKE_SOURCE_PWRBTN           0x06
 struct elog_event_data_wake {
 	u8 source;
 	u32 instance;
diff --git a/src/southbridge/intel/lynxpoint/elog.c b/src/southbridge/intel/lynxpoint/elog.c
index 09dfcdb..9ba3a98 100644
--- a/src/southbridge/intel/lynxpoint/elog.c
+++ b/src/southbridge/intel/lynxpoint/elog.c
@@ -28,20 +28,101 @@
 #include <elog.h>
 #include "pch.h"
 
+static void pch_log_standard_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg)
+{
+	u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
+	u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;
+
+	/* PME (TODO: determine wake device) */
+	if (gpe0_sts & (1 << 11))
+		elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
+
+	/* Internal PME (TODO: determine wake device) */
+	if (gpe0_sts & (1 << 13))
+		elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
+
+	/* SMBUS Wake */
+	if (gpe0_sts & (1 << 7))
+		elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
+}
+
+static void pch_log_gpio_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg, int start)
+{
+	/* GPE Bank 1 is GPIO 0-31 */
+	u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
+	u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;
+	int i;
+
+	for (i = 0; i <= 31; i++) {
+		if (gpe0_sts & (1 << i))
+			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i + start);
+	}
+}
+
+static void pch_log_gpe(void)
+{
+	int i;
+	u16 pmbase = get_pmbase();
+	u32 gpe0_sts, gpe0_en;
+	int gpe0_high_gpios[] = {
+		[0] = 27,
+		[24] = 17,
+		[25] = 19,
+		[26] = 21,
+		[27] = 22,
+		[28] = 43,
+		[29] = 56,
+		[30] = 57,
+		[31] = 60
+	};
+
+	pch_log_standard_gpe(GPE0_EN, GPE0_STS);
+
+	/* GPIO 0-15 */
+	gpe0_en = inw(pmbase + GPE0_EN + 2);
+	gpe0_sts = inw(pmbase + GPE0_STS + 2) & gpe0_en;
+	for (i = 0; i <= 15; i++) {
+		if (gpe0_sts & (1 << i))
+			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i);
+	}
+
+	/*
+	 * Now check and log upper status bits
+	 */
+
+	gpe0_en = inl(pmbase + GPE0_EN_2);
+	gpe0_sts = inl(pmbase + GPE0_STS_2) & gpe0_en;
+
+	for (i = 0; i <= 31; i++) {
+		if (!gpe0_high_gpios[i])
+			continue;
+		if (gpe0_sts & (1 << i))
+			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO,
+					    gpe0_high_gpios[i]);
+	}
+}
+
+static void pch_lp_log_gpe(void)
+{
+	/* Standard GPE are in GPE set 4 */
+	pch_log_standard_gpe(LP_GPE0_STS_4, LP_GPE0_EN_4);
+
+	/* Log GPIO events in set 1-3 */
+	pch_log_gpio_gpe(LP_GPE0_STS_1, LP_GPE0_EN_1, 0);
+	pch_log_gpio_gpe(LP_GPE0_STS_2, LP_GPE0_EN_2, 32);
+	pch_log_gpio_gpe(LP_GPE0_STS_3, LP_GPE0_EN_3, 64);
+}
+
 void pch_log_state(void)
 {
 	u16 pm1_sts, gen_pmcon_3, tco2_sts;
-	u32 gpe0_sts, gpe0_en;
 	u8 gen_pmcon_2;
-	int i;
 	struct device *lpc = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
 	if (!lpc)
 		return;
 
-	pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
-	gpe0_sts = inl(DEFAULT_PMBASE + GPE0_STS);
-	gpe0_en = inl(DEFAULT_PMBASE + GPE0_EN);
-	tco2_sts = inw(DEFAULT_PMBASE + TCO2_STS);
+	pm1_sts = inw(get_pmbase() + PM1_STS);
+	tco2_sts = inw(get_pmbase() + TCO2_STS);
 	gen_pmcon_2 = pci_read_config8(lpc, GEN_PMCON_2);
 	gen_pmcon_3 = pci_read_config16(lpc, GEN_PMCON_3);
 
@@ -86,6 +167,10 @@ void pch_log_state(void)
 	 * Wake sources
 	 */
 
+	/* Power Button */
+	if (pm1_sts & (1 << 8))
+		elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
+
 	/* RTC */
 	if (pm1_sts & (1 << 10))
 		elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
@@ -94,21 +179,9 @@ void pch_log_state(void)
 	if (pm1_sts & (1 << 14))
 		elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
 
-	/* PME (TODO: determine wake device) */
-	if (gpe0_sts & (1 << 13))
-		elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
-
-	/* Internal PME (TODO: determine wake device) */
-	if (gpe0_sts & (1 << 13))
-		elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
-
-	/* GPIO 0-15 */
-	for (i = 0; i < 16; i++) {
-		if ((gpe0_sts & (1 << (16+i))) && (gpe0_en & (1 << (16+i))))
-			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i);
-	}
-
-	/* SMBUS Wake */
-	if (gpe0_sts & (1 << 7))
-		elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
+	/* GPE */
+	if (pch_is_lp())
+		pch_lp_log_gpe();
+	else
+		pch_log_gpe();
 }



More information about the coreboot mailing list