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

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ia69fee8985e1c39b0e4b104c51439bca1a5493ac </div>
<div style="display:none"> Gerrit-Change-Number: 21062 </div>
<div style="display:none"> Gerrit-PatchSet: 13 </div>
<div style="display:none"> Gerrit-Owner: Lijian Zhao <lijian.zhao@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Aaron Durbin <adurbin@chromium.org> </div>
<div style="display:none"> Gerrit-Reviewer: Brandon Breitenstein <brandon.breitenstein@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Hannah Williams <hannah.williams@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: John Zhao <john.zhao@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Krzysztof M Sywula <krzysztof.m.sywula@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Lijian Zhao <lijian.zhao@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Pratikkumar V Prajapati <pratikkumar.v.prajapati@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Shaunak Saha <shaunak.saha@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Subrata Banik <subrata.banik@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org> </div>