[coreboot-gerrit] Change in coreboot[master]: soc/intel/cannonlake: Enable common PMC code for CNL

Lijian Zhao (Code Review) gerrit at coreboot.org
Mon Aug 21 18:47:08 CEST 2017


Lijian Zhao has uploaded this change for review. ( https://review.coreboot.org/21062


Change subject: soc/intel/cannonlake: Enable common PMC code for CNL
......................................................................

soc/intel/cannonlake: Enable common PMC code for CNL

This update changes Cannonlake to use the new common PMC code. This
will help to reduce code duplication and streamline code bring up.

Change-Id: Ia69fee8985e1c39b0e4b104c51439bca1a5493ac
Signed-off-by: Lijian Zhao <lijian.zhao at intel.com>
---
M src/soc/intel/cannonlake/Kconfig
M src/soc/intel/cannonlake/Makefile.inc
M src/soc/intel/cannonlake/bootblock/pch.c
M src/soc/intel/cannonlake/chip.h
A src/soc/intel/cannonlake/include/soc/gpe.h
M src/soc/intel/cannonlake/include/soc/pm.h
M src/soc/intel/cannonlake/include/soc/pmc.h
M src/soc/intel/cannonlake/include/soc/smbus.h
A src/soc/intel/cannonlake/pmutil.c
M src/soc/intel/cannonlake/romstage/power_state.c
M src/soc/intel/cannonlake/romstage/romstage.c
11 files changed, 580 insertions(+), 21 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/62/21062/13

diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig
index 1b6759c..1407b14 100644
--- a/src/soc/intel/cannonlake/Kconfig
+++ b/src/soc/intel/cannonlake/Kconfig
@@ -7,6 +7,7 @@
 
 config CPU_SPECIFIC_OPTIONS
 	def_bool y
+	select ACPI_INTEL_HARDWARE_SLEEP_VALUES
 	select ARCH_BOOTBLOCK_X86_32
 	select ARCH_RAMSTAGE_X86_32
 	select ARCH_ROMSTAGE_X86_32
@@ -34,6 +35,7 @@
 	select SOC_INTEL_COMMON_BLOCK_GSPI
 	select SOC_INTEL_COMMON_BLOCK_LPSS
 	select SOC_INTEL_COMMON_BLOCK_PCR
+	select SOC_INTEL_COMMON_BLOCK_PMC
 	select SOC_INTEL_COMMON_BLOCK_RTC
 	select SOC_INTEL_COMMON_BLOCK_SA
 	select SOC_INTEL_COMMON_BLOCK_SMBUS
diff --git a/src/soc/intel/cannonlake/Makefile.inc b/src/soc/intel/cannonlake/Makefile.inc
index 8a83eb0..10d444b 100644
--- a/src/soc/intel/cannonlake/Makefile.inc
+++ b/src/soc/intel/cannonlake/Makefile.inc
@@ -9,6 +9,7 @@
 bootblock-y += bootblock/bootblock.c
 bootblock-y += bootblock/cpu.c
 bootblock-y += bootblock/pch.c
+bootblock-y += pmutil.c
 bootblock-y += bootblock/report_platform.c
 bootblock-y += gpio.c
 bootblock-y += gspi.c
@@ -18,6 +19,7 @@
 
 romstage-y += gspi.c
 romstage-y += memmap.c
+romstage-y += pmutil.c
 romstage-y += reset.c
 romstage-y += spi.c
 romstage-$(CONFIG_UART_DEBUG) += uart.c
@@ -25,12 +27,14 @@
 ramstage-y += chip.c
 ramstage-y += gspi.c
 ramstage-y += memmap.c
+ramstage-y += pmutil.c
 ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c
 ramstage-y += spi.c
 ramstage-y += systemagent.c
 ramstage-$(CONFIG_UART_DEBUG) += uart.c
 
 postcar-y += memmap.c
+postcar-y += pmutil.c
 postcar-y += spi.c
 postcar-$(CONFIG_UART_DEBUG) += uart.c
 
diff --git a/src/soc/intel/cannonlake/bootblock/pch.c b/src/soc/intel/cannonlake/bootblock/pch.c
index 21a06e4..0062c0d 100644
--- a/src/soc/intel/cannonlake/bootblock/pch.c
+++ b/src/soc/intel/cannonlake/bootblock/pch.c
@@ -26,7 +26,7 @@
 #include <soc/p2sb.h>
 #include <soc/pci_devs.h>
 #include <soc/pcr_ids.h>
-#include <soc/pmc.h>
+#include <soc/pm.h>
 #include <soc/smbus.h>
 
 #define PCR_PSF3_TO_SHDW_PMC_REG_BASE	0x1400
diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h
index 67be85d..38f9a1f 100644
--- a/src/soc/intel/cannonlake/chip.h
+++ b/src/soc/intel/cannonlake/chip.h
@@ -24,6 +24,13 @@
 struct soc_intel_cannonlake_config {
 	/* GSPI */
 	struct gspi_cfg gspi[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX];
+
+	/* Gpio group routed to each dword of the GPE0 block. Values are
+	 * of the form GPP_[A:G] or GPD. */
+	uint8_t gpe0_dw0; /* GPE0_31_0 STS/EN */
+	uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */
+	uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */
+
 };
 
 typedef struct soc_intel_cannonlake_config config_t;
diff --git a/src/soc/intel/cannonlake/include/soc/gpe.h b/src/soc/intel/cannonlake/include/soc/gpe.h
new file mode 100644
index 0000000..521d523
--- /dev/null
+++ b/src/soc/intel/cannonlake/include/soc/gpe.h
@@ -0,0 +1,134 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_GPE_H_
+#define _SOC_GPE_H_
+
+/* GPE_31_0 */
+#define GPE0_DW0_00		0
+#define GPE0_DW0_01		1
+#define GPE0_DW0_02		2
+#define GPE0_DW0_03		3
+#define GPE0_DW0_04		4
+#define GPE0_DW0_05		5
+#define GPE0_DW0_06		6
+#define GPE0_DW0_07		7
+#define GPE0_DW0_08		8
+#define GPE0_DW0_09		9
+#define GPE0_DW0_10		10
+#define GPE0_DW0_11		11
+#define GPE0_DW0_12		12
+#define GPE0_DW0_13		13
+#define GPE0_DW0_14		14
+#define GPE0_DW0_15		15
+#define GPE0_DW0_16		16
+#define GPE0_DW0_17		17
+#define GPE0_DW0_18		18
+#define GPE0_DW0_19		19
+#define GPE0_DW0_20		20
+#define GPE0_DW0_21		21
+#define GPE0_DW0_22		22
+#define GPE0_DW0_23		23
+#define GPE0_DW0_24		24
+#define GPE0_DW0_25		25
+#define GPE0_DW0_26		26
+#define GPE0_DW0_27		27
+#define GPE0_DW0_28		28
+#define GPE0_DW0_29		29
+#define GPE0_DW0_30		30
+#define GPE0_DW0_31		31
+/* GPE_63_32 */
+#define GPE0_DW1_00		32
+#define GPE0_DW1_01		33
+#define GPE0_DW1_02		34
+#define GPE0_DW1_03		36
+#define GPE0_DW1_04		36
+#define GPE0_DW1_05		37
+#define GPE0_DW1_06		38
+#define GPE0_DW1_07		39
+#define GPE0_DW1_08		40
+#define GPE0_DW1_09		41
+#define GPE0_DW1_10		42
+#define GPE0_DW1_11		43
+#define GPE0_DW1_12		44
+#define GPE0_DW1_13		45
+#define GPE0_DW1_14		46
+#define GPE0_DW1_15		47
+#define GPE0_DW1_16		48
+#define GPE0_DW1_17		49
+#define GPE0_DW1_18		50
+#define GPE0_DW1_19		51
+#define GPE0_DW1_20		52
+#define GPE0_DW1_21		53
+#define GPE0_DW1_22		54
+#define GPE0_DW1_23		55
+#define GPE0_DW1_24		56
+#define GPE0_DW1_25		57
+#define GPE0_DW1_26		58
+#define GPE0_DW1_27		59
+#define GPE0_DW1_28		60
+#define GPE0_DW1_29		61
+#define GPE0_DW1_30		62
+#define GPE0_DW1_31		63
+/* GPE_95_64 */
+#define GPE0_DW2_00		64
+#define GPE0_DW2_01		65
+#define GPE0_DW2_02		66
+#define GPE0_DW2_03		67
+#define GPE0_DW2_04		68
+#define GPE0_DW2_05		69
+#define GPE0_DW2_06		70
+#define GPE0_DW2_07		71
+#define GPE0_DW2_08		72
+#define GPE0_DW2_09		73
+#define GPE0_DW2_10		74
+#define GPE0_DW2_11		75
+#define GPE0_DW2_12		76
+#define GPE0_DW2_13		77
+#define GPE0_DW2_14		78
+#define GPE0_DW2_15		79
+#define GPE0_DW2_16		80
+#define GPE0_DW2_17		81
+#define GPE0_DW2_18		82
+#define GPE0_DW2_19		83
+#define GPE0_DW2_20		84
+#define GPE0_DW2_21		85
+#define GPE0_DW2_22		86
+#define GPE0_DW2_23		87
+#define GPE0_DW2_24		88
+#define GPE0_DW2_25		89
+#define GPE0_DW2_26		90
+#define GPE0_DW2_27		91
+#define GPE0_DW2_28		92
+#define GPE0_DW2_29		93
+#define GPE0_DW2_30		94
+#define GPE0_DW2_31		95
+/* GPE_STD */
+#define GPE0_HOT_PLUG		97
+#define GPE0_SWGPE		98
+#define GPE0_TCOSCI		102
+#define GPE0_SMB_WAK		103
+#define GPE0_PCI_EXP		105
+#define GPE0_BATLOW		106
+#define GPE0_PME		107
+#define GPE0_ME_SCI		108
+#define GPE0_PME_B0		109
+#define GPE0_ESPI		110
+#define GPE0_GPIO_T2		111
+#define GPE0_LAN_WAK		112
+#define GPE0_WADT		114
+
+#define GPE_MAX			GPE0_WADT
+#endif /* _SOC_GPE_H_ */
diff --git a/src/soc/intel/cannonlake/include/soc/pm.h b/src/soc/intel/cannonlake/include/soc/pm.h
index 6654122..abf7db9 100644
--- a/src/soc/intel/cannonlake/include/soc/pm.h
+++ b/src/soc/intel/cannonlake/include/soc/pm.h
@@ -18,22 +18,124 @@
 #define _SOC_PM_H_
 
 #include <arch/acpi.h>
+#include <arch/io.h>
+#include <soc/gpe.h>
+#include <soc/iomap.h>
+#include <soc/smbus.h>
 #include <soc/pmc.h>
 
+#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  BM_STS			(1 << 4)
+#define  TMROF_STS		(1 << 0)
 #define PM1_EN			0x02
+#define  PCIEXPWAK_DIS		(1 << 14)
+#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  GBL_RLS		(1 << 2)
+#define  BM_RLD			(1 << 1)
+#define  SCI_EN			(1 << 0)
+#define PM1_TMR			0x08
 #define SMI_EN			0x30
+#define  XHCI_SMI_EN		(1 << 31)
+#define  ME_SMI_EN		(1 << 30)
 #define  ESPI_SMI_EN		(1 << 28)
+#define  GPIO_UNLOCK_SMI_EN	(1 << 27)
+#define  INTEL_USB2_EN		(1 << 18)
+#define  LEGACY_USB2_EN		(1 << 17)
+#define  PERIODIC_EN		(1 << 14)
+#define  TCO_SMI_EN		(1 << 13)
+#define  MCSMI_EN		(1 << 11)
+#define  BIOS_RLS		(1 <<  7)
+#define  SWSMI_TMR_EN		(1 <<  6)
 #define  APMC_EN		(1 <<  5)
 #define  SLP_SMI_EN		(1 <<  4)
+#define  LEGACY_USB_EN		(1 <<  3)
+#define  BIOS_EN		(1 <<  2)
 #define  EOS			(1 <<  1)
 #define  GBL_SMI_EN		(1 <<  0)
+#define SMI_STS			0x34
+#define  SMI_STS_BITS			32
+#define  XHCI_SMI_STS_BIT		31
+#define  ME_SMI_STS_BIT			30
+#define  ESPI_SMI_STS_BIT		28
+#define  GPIO_UNLOCK_SMI_STS_BIT	27
+#define  SPI_SMI_STS_BIT		26
+#define  SCC_SMI_STS_BIT		25
+#define  MONITOR_STS_BIT		21
+#define  PCI_EXP_SMI_STS_BIT		20
+#define  SMBUS_SMI_STS_BIT		16
+#define  SERIRQ_SMI_STS_BIT		15
+#define  PERIODIC_STS_BIT		14
+#define  TCO_STS_BIT			13
+#define  DEVMON_STS_BIT			12
+#define  MCSMI_STS_BIT			11
+#define  GPIO_STS_BIT			10
+#define  GPE0_STS_BIT			9
+#define  PM1_STS_BIT			8
+#define  SWSMI_TMR_STS_BIT		6
+#define  APM_STS_BIT			5
+#define  SMI_ON_SLP_EN_STS_BIT		4
+#define  LEGACY_USB_STS_BIT		3
+#define  BIOS_STS_BIT			2
+#define GPE_CNTL		0x42
+#define  SWGPE_CTRL		(1 << 1)
+#define DEVACT_STS		0x44
+#define PM2_CNT			0x50
 
-
+#define GPE0_REG_MAX		4
+#define GPE0_REG_SIZE		32
+#define GPE0_STS(x)		(0x60 + ((x) * 4))
+#define  GPE_31_0		0	/* 0x60/0x70 = GPE[31:0] */
+#define  GPE_63_32		1	/* 0x64/0x74 = GPE[63:32] */
+#define  GPE_95_64		2	/* 0x68/0x78 = GPE[95:64] */
+#define  GPE_STD		3	/* 0x6c/0x7c = Standard GPE */
+#define GPE_STS_RSVD            GPE_STD
+#define   WADT_STS		(1 << 18)
+#define   GPIO_T2_STS		(1 << 15)
+#define   ESPI_STS		(1 << 14)
+#define   PME_B0_STS		(1 << 13)
+#define   ME_SCI_STS		(1 << 12)
+#define   PME_STS		(1 << 11)
+#define   BATLOW_STS		(1 << 10)
+#define   PCI_EXP_STS		(1 << 9)
+#define   SMB_WAK_STS		(1 << 7)
+#define   TCOSCI_STS		(1 << 6)
+#define   SWGPE_STS		(1 << 2)
+#define   HOT_PLUG_STS		(1 << 1)
 #define GPE0_EN(x)		(0x70 + ((x) * 4))
-#define  PME_B0_EN		(1 << 13)
+#define   WADT_EN		(1 << 18)
+#define   GPIO_T2_EN		(1 << 15)
+#define   ESPI_EN		(1 << 14)
+#define   PME_B0_EN		(1 << 13)
+#define   ME_SCI_EN		(1 << 12)
+#define   PME_EN		(1 << 11)
+#define   BATLOW_EN		(1 << 10)
+#define   PCI_EXP_EN		(1 << 9)
+#define   TCOSCI_EN		(1 << 6)
+#define   SWGPE_EN		(1 << 2)
+#define   HOT_PLUG_EN		(1 << 1)
 
+#define EN_BLOCK		3
+
+/*
+ * Enable SMI generation:
+ *  - on APMC writes (io 0xb2)
+ *  - on writes to SLP_EN (sleep states)
+ *  - on writes to GBL_RLS (bios commands)
+ *  - on eSPI events (does nothing on LPC systems)
+ * No SMIs:
+ *  - on microcontroller writes (io 0x62/0x66)
+ *  - on TCO events
+ */
 #define ENABLE_SMI_PARAMS \
 	(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS)
 
@@ -51,6 +153,16 @@
 	uint32_t prev_sleep_state;
 } __attribute__ ((packed));
 
-struct chipset_power_state *fill_power_state(void);
+/* Return the selected ACPI SCI IRQ */
+int acpi_sci_irq(void);
+
+/* Get base address PMC memory mapped registers. */
+uint8_t *pmc_mmio_regs(void);
+
+/* Get base address of TCO I/O registers. */
+uint16_t smbus_tco_regs(void);
+
+/* Set the DISB after DRAM init */
+void pmc_set_disb(void);
 
 #endif
diff --git a/src/soc/intel/cannonlake/include/soc/pmc.h b/src/soc/intel/cannonlake/include/soc/pmc.h
index 0bca332..b8e49c2 100644
--- a/src/soc/intel/cannonlake/include/soc/pmc.h
+++ b/src/soc/intel/cannonlake/include/soc/pmc.h
@@ -71,9 +71,9 @@
 #define   SMI_LOCK			(1 << 4)
 #define   RTC_BATTERY_DEAD		(1 << 2)
 
-#define ETR3				0x1048
-#define   ETR3_CF9LOCK			(1 << 31)
-#define   ETR3_CF9GR			(1 << 20)
+#define ETR				0x1048
+#define   CF9_LOCK			(1 << 31)
+#define   CF9_GLB_RST			(1 << 20)
 
 #define SSML				0x104C
 #define    SSML_SSL_DS			(0 << 0)
@@ -84,6 +84,8 @@
 
 #define SSMD				0x1054
 #define    SSMD_SSD_MASK		(0xffff << 0)
+
+#define PRSTS				0x1810
 
 #define S3_PWRGATE_POL			0x1828
 #define    S3DC_GATE_SUS		(1 << 1)
@@ -109,11 +111,9 @@
 #define   PCH2CPU_TT_EN			(1 << 26)
 
 #define PCH_PWRM_ACPI_TMR_CTL		0x18FC
-#define GPIO_CFG			0x1920
-#define   GPE0_DWX_MASK			0xf
-#define   GPE0_DW0_SHIFT		0
-#define   GPE0_DW1_SHIFT		4
-#define   GPE0_DW2_SHIFT		8
+#define GPIO_GPE_CFG			0x1920
+#define  GPE0_DWX_MASK			0xf
+#define  GPE0_DW_SHIFT(x)		(4*(x))
 
 #define GBLRST_CAUSE0			0x1924
 #define   GBLRST_CAUSE0_THERMTRIP	(1 << 5)
diff --git a/src/soc/intel/cannonlake/include/soc/smbus.h b/src/soc/intel/cannonlake/include/soc/smbus.h
index 9de6981..9f1cf34 100644
--- a/src/soc/intel/cannonlake/include/soc/smbus.h
+++ b/src/soc/intel/cannonlake/include/soc/smbus.h
@@ -30,9 +30,9 @@
 
 /* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */
 #define TCO1_STS			0x04
+#define  TCO_TIMEOUT			(1 << 3)
 #define TCO2_STS			0x06
-#define TCO2_STS_SECOND_TO		0x02
-#define TCO2_STS_BOOT			0x04
+#define  TCO2_STS_SECOND_TO		(1 << 1)
 #define TCO1_CNT			0x08
 #define TCO_LOCK			(1 << 12)
 #define TCO_TMR_HLT			(1 << 11)
diff --git a/src/soc/intel/cannonlake/pmutil.c b/src/soc/intel/cannonlake/pmutil.c
new file mode 100644
index 0000000..455c969
--- /dev/null
+++ b/src/soc/intel/cannonlake/pmutil.c
@@ -0,0 +1,217 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 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.
+ */
+
+/*
+ * Helper functions for dealing with power management registers
+ * and the differences between PCH variants.
+ */
+
+#define __SIMPLE_DEVICE__
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <console/console.h>
+#include <intelblocks/pmclib.h>
+#include <halt.h>
+#include <rules.h>
+#include <stdlib.h>
+#include <soc/gpe.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/smbus.h>
+#include <timer.h>
+#include "chip.h"
+
+/*
+ * SMI
+ */
+
+const char *const *soc_smi_sts_array(size_t *a)
+{
+	static const char *const smi_sts_bits[] = {
+		[BIOS_STS_BIT] = "BIOS",
+		[LEGACY_USB_STS_BIT] = "LEGACY_USB",
+		[SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI",
+		[APM_STS_BIT] = "APM",
+		[SWSMI_TMR_STS_BIT] = "SWSMI_TMR",
+		[PM1_STS_BIT] = "PM1",
+		[GPE0_STS_BIT] = "GPE0",
+		[GPIO_STS_BIT] = "GPI",
+		[MCSMI_STS_BIT] = "MCSMI",
+		[DEVMON_STS_BIT] = "DEVMON",
+		[TCO_STS_BIT] = "TCO",
+		[PERIODIC_STS_BIT] = "PERIODIC",
+		[SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI",
+		[SMBUS_SMI_STS_BIT] = "SMBUS_SMI",
+		[PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI",
+		[MONITOR_STS_BIT] = "MONITOR",
+		[SPI_SMI_STS_BIT] = "SPI",
+		[GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK",
+		[ESPI_SMI_STS_BIT] = "ESPI_SMI",
+	};
+
+	*a = ARRAY_SIZE(smi_sts_bits);
+	return smi_sts_bits;
+}
+
+/*
+ * TCO
+ */
+
+const char *const *soc_tco_sts_array(size_t *a)
+{
+	static const char *const tco_sts_bits[] = {
+		[0] = "NMI2SMI",
+		[1] = "SW_TCO",
+		[2] = "TCO_INT",
+		[3] = "TIMEOUT",
+		[7] = "NEWCENTURY",
+		[8] = "BIOSWR",
+		[9] = "DMISCI",
+		[10] = "DMISMI",
+		[12] = "DMISERR",
+		[13] = "SLVSEL",
+		[16] = "INTRD_DET",
+		[17] = "SECOND_TO",
+		[18] = "BOOT",
+		[20] = "SMLINK_SLV"
+	};
+
+	*a = ARRAY_SIZE(tco_sts_bits);
+	return tco_sts_bits;
+}
+
+/*
+ * GPE0
+ */
+
+const char *const *soc_gpe_sts_array(size_t *a)
+{
+	static const char *const gpe_sts_bits[] = {
+		[1] = "HOTPLUG",
+		[2] = "SWGPE",
+		[6] = "TCO_SCI",
+		[7] = "SMB_WAK",
+		[9] = "PCI_EXP",
+		[10] = "BATLOW",
+		[11] = "PME",
+		[12] = "ME",
+		[13] = "PME_B0",
+		[14] = "eSPI",
+		[15] = "GPIO Tier-2",
+		[16] = "LAN_WAKE",
+		[18] = "WADT"
+	};
+
+	*a = ARRAY_SIZE(gpe_sts_bits);
+	return gpe_sts_bits;
+}
+
+int acpi_sci_irq(void)
+{
+	int scis = pci_read_config32(PCH_DEV_PMC, ACTL) & SCI_IRQ_SEL;
+	int sci_irq = 9;
+
+	/* Determine how SCI is routed. */
+	switch (scis) {
+	case SCIS_IRQ9:
+	case SCIS_IRQ10:
+	case SCIS_IRQ11:
+		sci_irq = scis - SCIS_IRQ9 + 9;
+		break;
+	case SCIS_IRQ20:
+	case SCIS_IRQ21:
+	case SCIS_IRQ22:
+	case SCIS_IRQ23:
+		sci_irq = scis - SCIS_IRQ20 + 20;
+		break;
+	default:
+		printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n");
+		sci_irq = 9;
+		break;
+	}
+
+	printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq);
+	return sci_irq;
+}
+
+uint8_t *pmc_mmio_regs(void)
+{
+	uint32_t reg32;
+
+	reg32 = pci_read_config32(PCH_DEV_PMC, PWRMBASE);
+
+	return (void *)(uintptr_t)ALIGN_DOWN(reg32, 4 * KiB);
+}
+
+uint16_t smbus_tco_regs(void)
+{
+	uint16_t reg16;
+
+	reg16 = pci_read_config16(PCH_DEV_SMBUS, TCOBASE);
+
+	return ALIGN_DOWN(reg16, 0x20);
+}
+
+uint32_t soc_reset_tco_status(void)
+{
+	u16 tco1_sts;
+	u16 tco2_sts;
+	u16 tcobase;
+
+	tcobase = smbus_tco_regs();
+
+	/* TCO Status 2 register */
+	tco2_sts = inw(tcobase + TCO2_STS);
+	tco2_sts |= TCO2_STS_SECOND_TO;
+	outw(tco2_sts, tcobase + TCO2_STS);
+
+	/* TCO Status 1 register */
+	tco1_sts = inw(tcobase + TCO1_STS);
+
+	/* Clear SECOND_TO_STS bit */
+	if (tco2_sts & TCO2_STS_SECOND_TO)
+		outw(tco2_sts & ~TCO2_STS_SECOND_TO, tcobase + TCO2_STS);
+
+	return (tco2_sts << 16) | tco1_sts;
+}
+
+uintptr_t soc_read_pmc_base(void)
+{
+	return (uintptr_t)pmc_mmio_regs();
+}
+
+void soc_get_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
+{
+	DEVTREE_CONST struct soc_intel_cannonlake_config *config;
+
+	/* Look up the device in devicetree */
+	DEVTREE_CONST struct device *dev = dev_find_slot(0, PCH_DEVFN_PMC);
+	if (!dev || !dev->chip_info) {
+		printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
+	}
+	config = dev->chip_info;
+
+	/* Assign to out variable */
+	*dw0 = config->gpe0_dw0;
+	*dw1 = config->gpe0_dw1;
+	*dw2 = config->gpe0_dw2;
+}
diff --git a/src/soc/intel/cannonlake/romstage/power_state.c b/src/soc/intel/cannonlake/romstage/power_state.c
index 2c45ad9..46048db 100644
--- a/src/soc/intel/cannonlake/romstage/power_state.c
+++ b/src/soc/intel/cannonlake/romstage/power_state.c
@@ -18,14 +18,94 @@
 #include <arch/io.h>
 #include <cbmem.h>
 #include <console/console.h>
+#include <device/device.h>
+#include <intelblocks/pmclib.h>
+#include <string.h>
+#include <soc/pci_devs.h>
 #include <soc/pm.h>
 
 static struct chipset_power_state power_state CAR_GLOBAL;
 
-/* Fill power state structure from ACPI PM registers */
-struct chipset_power_state *fill_power_state(void)
+static void migrate_power_state(int is_recovery)
 {
-	struct chipset_power_state *ps = car_get_var_ptr(&power_state);
+	struct chipset_power_state *ps_cbmem;
+	struct chipset_power_state *ps_car;
 
-	return ps;
+	ps_car = car_get_var_ptr(&power_state);
+	ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
+
+	if (ps_cbmem == NULL) {
+		printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
+		return;
+	}
+	memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
+}
+
+ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state)
+
+static inline int deep_s3_enabled(void)
+{
+	uint32_t deep_s3_pol;
+
+	deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL);
+	return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS));
+}
+
+/* Return 0, 3, or 5 to indicate the previous sleep state. */
+int soc_prev_sleep_state(const struct chipset_power_state *ps,
+	int prev_sleep_state)
+{
+
+	/*
+	 * Check for any power failure to determine if this a wake from
+	* S5 because the PCH does not set the WAK_STS bit when waking
+	* from a true G3 state.
+	*/
+	if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR))
+		prev_sleep_state = ACPI_S5;
+
+	/*
+	 * If waking from S3 determine if deep S3 is enabled. If not,
+	 * need to check both deep sleep well and normal suspend well.
+	 * Otherwise just check deep sleep well.
+	 */
+	if (prev_sleep_state == ACPI_S3) {
+		/* PWR_FLR represents deep sleep power well loss. */
+		uint32_t mask = PWR_FLR;
+
+		/* If deep s3 isn't enabled check the suspend well too. */
+		if (!deep_s3_enabled())
+			mask |= SUS_PWR_FLR;
+
+		if (ps->gen_pmcon_b & mask)
+			prev_sleep_state = ACPI_S5;
+	}
+
+	return prev_sleep_state;
+}
+
+void soc_fill_power_state(struct chipset_power_state *ps)
+{
+	uint16_t tcobase;
+	uint8_t *pmc;
+
+	tcobase = smbus_tco_regs();
+
+	ps->tco1_sts = inw(tcobase + TCO1_STS);
+	ps->tco2_sts = inw(tcobase + TCO2_STS);
+
+	printk(BIOS_DEBUG, "TCO_STS:   %04x %04x\n",
+	ps->tco1_sts, ps->tco2_sts);
+
+	pmc = pmc_mmio_regs();
+	ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A);
+	ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B);
+	ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
+	ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
+
+	printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
+		ps->gen_pmcon_a, ps->gen_pmcon_b);
+
+	printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
+		ps->gblrst_cause[0], ps->gblrst_cause[1]);
 }
diff --git a/src/soc/intel/cannonlake/romstage/romstage.c b/src/soc/intel/cannonlake/romstage/romstage.c
index 2f8617e..ab0e19b 100644
--- a/src/soc/intel/cannonlake/romstage/romstage.c
+++ b/src/soc/intel/cannonlake/romstage/romstage.c
@@ -14,30 +14,33 @@
  */
 
 #include <arch/io.h>
+#include <arch/early_variables.h>
 #include <cpu/x86/mtrr.h>
 #include <cbmem.h>
 #include <console/console.h>
 #include <fsp/util.h>
+#include <intelblocks/pmclib.h>
 #include <memory_info.h>
 #include <soc/pm.h>
 #include <soc/romstage.h>
 #include <timestamp.h>
+
+static struct chipset_power_state power_state CAR_GLOBAL;
 
 asmlinkage void car_stage_entry(void)
 {
 	bool s3wake;
 	struct postcar_frame pcf;
 	uintptr_t top_of_ram;
-	struct chipset_power_state *ps;
+	struct chipset_power_state *ps = car_get_var_ptr(&power_state);
 
 	console_init();
 
 	/* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */
 	systemagent_early_init();
 
-	ps = fill_power_state();
 	timestamp_add_now(TS_START_ROMSTAGE);
-	s3wake = ps->prev_sleep_state == ACPI_S3;
+	s3wake = pmc_fill_power_state(ps) == ACPI_S3;
 	fsp_memory_init(s3wake);
 	if (postcar_frame_init(&pcf, 1 * KiB))
 		die("Unable to initialize postcar frame.\n");

-- 
To view, visit https://review.coreboot.org/21062
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia69fee8985e1c39b0e4b104c51439bca1a5493ac
Gerrit-Change-Number: 21062
Gerrit-PatchSet: 13
Gerrit-Owner: Lijian Zhao <lijian.zhao at intel.com>
Gerrit-Reviewer: Aaron Durbin <adurbin at chromium.org>
Gerrit-Reviewer: Brandon Breitenstein <brandon.breitenstein at intel.com>
Gerrit-Reviewer: Hannah Williams <hannah.williams at intel.com>
Gerrit-Reviewer: John Zhao <john.zhao at intel.com>
Gerrit-Reviewer: Krzysztof M Sywula <krzysztof.m.sywula at intel.com>
Gerrit-Reviewer: Lijian Zhao <lijian.zhao at intel.com>
Gerrit-Reviewer: Pratikkumar V Prajapati <pratikkumar.v.prajapati at intel.com>
Gerrit-Reviewer: Shaunak Saha <shaunak.saha at intel.com>
Gerrit-Reviewer: Subrata Banik <subrata.banik at intel.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply at coreboot.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20170821/90742879/attachment-0001.html>


More information about the coreboot-gerrit mailing list