aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Breitenstein <brandon.breitenstein@intel.com>2016-07-18 15:14:12 -0700
committerAaron Durbin <adurbin@chromium.org>2016-08-25 23:51:27 +0200
commit3b0e761dd5008b9b87d207f9c7d7571fc880a523 (patch)
tree4289c2368848b428ddd1da9cc247650bc75fcd2f
parentde9fed4c2a6014b25042899e199cfe9a6115b52e (diff)
soc/intel/apollolake: Enable ELOG
Add in the base for ELOG for APL. Some PM events still need to be added but the basic events are logged here. This enables the basic functionality of ELOG for Apollolake. BUG=chrome-os-partner:55473 BRANCH=none TEST=Verified image boots on Amenia Change-Id: I8682293e5a55b3efb5fdd9f1be1f3e4bf8d0757c Signed-off-by: Brandon Breitenstein <brandon.breitenstein@intel.com> Reviewed-on: https://review.coreboot.org/15937 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins)
-rw-r--r--src/soc/intel/apollolake/Makefile.inc1
-rw-r--r--src/soc/intel/apollolake/elog.c107
-rw-r--r--src/soc/intel/apollolake/include/soc/pm.h34
-rw-r--r--src/soc/intel/apollolake/pmc.c3
4 files changed, 140 insertions, 5 deletions
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index cae90b5558..1f3c276c3a 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -49,6 +49,7 @@ smm-y += uart_early.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
ramstage-y += cpu.c
ramstage-y += chip.c
+ramstage-y += elog.c
ramstage-y += dsp.c
ramstage-y += gpio.c
ramstage-y += graphics.c
diff --git a/src/soc/intel/apollolake/elog.c b/src/soc/intel/apollolake/elog.c
new file mode 100644
index 0000000000..0dd44c2e7d
--- /dev/null
+++ b/src/soc/intel/apollolake/elog.c
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Google Inc.
+ * Copyright (C) 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <bootstate.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <elog.h>
+#include <soc/pm.h>
+#include <soc/pci_devs.h>
+#include <stdint.h>
+
+static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
+{
+ int i;
+
+ gpe0_sts &= gpe0_en;
+
+ 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_wake_source(struct chipset_power_state *ps)
+{
+ /* Power Button */
+ if (ps->pm1_sts & PWRBTN_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
+
+ /* RTC */
+ if (ps->pm1_sts & RTC_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
+
+ /* PCI Express (TODO: determine wake device) */
+ if (ps->pm1_sts & PCIEXPWAK_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
+
+ /* PME */
+ if(ps->gpe0_sts[GPE0_A] & CSE_PME_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
+
+ /* SMBUS Wake */
+ if (ps->gpe0_sts[GPE0_A] & SMB_WAK_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
+
+ /* ACPI Wake Event - Always Log prev_sleep_state*/
+ elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state);
+
+ /* Log GPIO events in set A-D */
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE0_A], ps->gpe0_en[GPE0_A], 0);
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE0_B], ps->gpe0_en[GPE0_B], 32);
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE0_C], ps->gpe0_en[GPE0_C], 64);
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE0_D], ps->gpe0_en[GPE0_D], 96);
+}
+
+static void pch_log_power_and_resets(struct chipset_power_state *ps)
+{
+ /* RTC Reset */
+ if (ps->gen_pmcon1 & RPS)
+ elog_add_event(ELOG_TYPE_RTC_RESET);
+
+ /* System Reset */
+ if (ps->gen_pmcon1 & SRS)
+ elog_add_event(ELOG_TYPE_SYSTEM_RESET);
+
+ /* TCO Timeout */
+ if (ps->prev_sleep_state != ACPI_S3 &&
+ ps->tco_sts & TCO_TIMEOUT)
+ elog_add_event(ELOG_TYPE_TCO_RESET);
+
+ /* Power Button Override */
+ if (ps->pm1_sts & PRBTNOR_STS)
+ elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
+
+}
+
+void pch_log_state(void)
+{
+ struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
+
+ if (ps == NULL) {
+ printk(BIOS_ERR,
+ "Not logging power state information. "
+ "Power state not found in cbmem.\n");
+ return;
+ }
+
+ /* Power and Reset */
+ pch_log_power_and_resets(ps);
+
+ /* Wake Sources */
+ if (ps->prev_sleep_state > ACPI_S0)
+ pch_log_wake_source(ps);
+}
diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h
index 7eb593002e..b3da3aa628 100644
--- a/src/soc/intel/apollolake/include/soc/pm.h
+++ b/src/soc/intel/apollolake/include/soc/pm.h
@@ -25,16 +25,17 @@
#define PM1_STS 0x00
#define WAK_STS (1 << 15)
+#define PCIEXPWAK_STS (1 << 14)
+#define PRBTNOR_STS (1 << 11)
#define RTC_STS (1 << 10)
#define PWRBTN_STS (1 << 8)
+#define GBL_STS (1 << 5)
#define PM1_EN 0x02
#define PCIEXPWAK_DIS (1 << 14)
-#define USB_WAKE_EN (1 << 13)
#define RTC_EN (1 << 10)
#define PWRBTN_EN (1 << 8)
#define GBL_EN (1 << 5)
-#define TMROF_EN (1 << 0)
#define PM1_CNT 0x04
#define SCI_EN (1 << 0)
@@ -113,8 +114,30 @@
#define GPE0_REG_MAX 4
#define GPE0_REG_SIZE 32
#define GPE0_STS(x) (0x20 + (x * 4))
+#define GPE0_A 0
+#define GPE0_B 1
+#define GPE0_C 2
+#define GPE0_D 3
+#define SATA_PME_STS (1 << 17)
+#define SMB_WAK_STS (1 << 16)
+#define AVS_PME_STS (1 << 14)
+#define XHCI_PME_STS (1 << 13)
+#define XDCI_PME_STS (1 << 12)
+#define CSE_PME_STS (1 << 11)
+#define BATLOW_STS (1 << 10)
+#define PCIE_GPE_STS (1 << 9)
+#define SWGPE_STS (1 << 2)
#define GPE0_EN(x) (0x30 + (x * 4))
+#define SATA_PME_EN (1 << 17)
+#define SMB_WAK_EN (1 << 16)
+#define AVS_PME_EN (1 << 14)
#define PME_B0_EN (1 << 13)
+#define XDCI_PME_EN (1 << 12)
+#define CSE_PME_EN (1 << 11)
+#define BATLOW_EN (1 << 10)
+#define PCIE_GPE_EN (1 << 9)
+#define SWGPE_EN (1 << 2)
+
/*
* Enables the setting of the GPIO_TIER1_SCI_STS bit to generate a wake event
* and/or an SCI or SMI#.
@@ -124,10 +147,9 @@
/* Memory mapped IO registers behind PMC_BASE_ADDRESS */
#define PRSTS 0x1000
#define GEN_PMCON1 0x1020
-# define PWR_FLR (1 << 16)
-# define SUS_PWR_FLR (1 << 14)
+#define SRS (1 << 20)
+#define RPS (1 << 2)
#define GEN_PMCON2 0x1024
-# define RPS (1 << 2)
#define GEN_PMCON3 0x1028
#define ETR 0x1048
# define CF9_LOCK (1 << 31)
@@ -188,4 +210,6 @@ uintptr_t get_pmc_mmio_bar(void);
void global_reset_enable(bool enable);
void global_reset_lock(void);
+void pch_log_state(void);
+
#endif
diff --git a/src/soc/intel/apollolake/pmc.c b/src/soc/intel/apollolake/pmc.c
index 92a150ddf4..30b7677a92 100644
--- a/src/soc/intel/apollolake/pmc.c
+++ b/src/soc/intel/apollolake/pmc.c
@@ -137,6 +137,9 @@ static void pmc_init(struct device *dev)
/* Set up GPE configuration */
pmc_gpe_init();
pch_set_acpi_mode();
+
+ /* Log power state */
+ pch_log_state();
}
static const struct device_operations device_ops = {