coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
pmutil.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #define __SIMPLE_DEVICE__
4 
5 #include <acpi/acpi.h>
6 #include <acpi/acpi_pm.h>
7 #include <arch/io.h>
8 #include <device/mmio.h>
9 #include <console/console.h>
10 #include <cpu/x86/msr.h>
11 #include <device/device.h>
12 #include <device/pci.h>
13 #include <device/pci_def.h>
14 #include <intelblocks/msr.h>
15 #include <intelblocks/pmclib.h>
16 #include <intelblocks/rtc.h>
17 #include <intelblocks/tco.h>
18 #include <soc/iomap.h>
19 #include <soc/cpu.h>
20 #include <soc/pci_devs.h>
21 #include <soc/pm.h>
22 #include <soc/smbus.h>
23 #include <security/vboot/vbnv.h>
24 
25 #include "chip.h"
26 
28 {
29  return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS;
30 }
31 
33 {
34  return (uintptr_t)pmc_mmio_regs();
35 }
36 
38 {
39  return (uint32_t *)(soc_read_pmc_base() + ETR);
40 }
41 
42 const char *const *soc_smi_sts_array(size_t *a)
43 {
44  static const char *const smi_sts_bits[] = {
45  [BIOS_STS_BIT] = "BIOS",
46  [LEGACY_USB_STS_BIT] = "LEGACY USB",
47  [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI",
48  [APM_STS_BIT] = "APM",
49  [SWSMI_TMR_STS_BIT] = "SWSMI_TMR",
50  [PM1_STS_BIT] = "PM1",
51  [GPE0_STS_BIT] = "GPE0 (reserved)",
52  [GPIO_STS_BIT] = "GPIO_SMI",
53  [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK_SSMI",
54  [MC_SMI_STS_BIT] = "MCSMI",
55  [TCO_STS_BIT] = "TCO",
56  [PERIODIC_STS_BIT] = "PERIODIC",
57  [SERIRQ_SMI_STS_BIT] = "SERIRQ",
58  [SMBUS_SMI_STS_BIT] = "SMBUS_SMI",
59  [XHCI_SMI_STS_BIT] = "XHCI",
60  [SCS_SMI_STS_BIT] = "HOST_SMBUS",
61  [SCS_SMI_STS_BIT] = "SCS",
62  [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI",
63  [SCC2_SMI_STS_BIT] = "SCC2",
64  [SPI_SSMI_STS_BIT] = "SPI_SSMI",
65  [SPI_SMI_STS_BIT] = "SPI",
66  [PMC_OCP_SMI_STS_BIT] = "OCP_CSE",
67  };
68 
69  *a = ARRAY_SIZE(smi_sts_bits);
70  return smi_sts_bits;
71 }
72 
73 /*
74  * For APL/GLK this check for power button status if nothing else
75  * is indicating an SMI and SMIs aren't turned into SCIs.
76  * Apparently, there is no PM1 status bit in the SMI status
77  * register. That makes things difficult for
78  * determining if the power button caused an SMI.
79  */
81 {
82  if (generic_sts == 0 && !(pmc_read_pm1_control() & SCI_EN)) {
84 
85  /* Fake PM1 status bit if power button pressed. */
86  if (pm1_sts & PWRBTN_STS)
87  generic_sts |= (1 << PM1_STS_BIT);
88  }
89 
90  /*
91  * GPE0_STS is reserved in APL/GLK datasheets. For compatibility
92  * with common code, mask it out so that it is always zero.
93  */
94  return generic_sts & ~(1 << GPE0_STS_BIT);
95 }
96 
97 const char *const *soc_tco_sts_array(size_t *a)
98 {
99  static const char *const tco_sts_bits[] = {
100  [3] = "TIMEOUT",
101  [17] = "SECOND_TO",
102  };
103 
104  *a = ARRAY_SIZE(tco_sts_bits);
105  return tco_sts_bits;
106 }
107 
108 const char *const *soc_std_gpe_sts_array(size_t *a)
109 {
110  static const char *const gpe_sts_bits[] = {
111  [0] = "PCIE_SCI",
112  [2] = "SWGPE",
113  [3] = "PCIE_WAKE0",
114  [4] = "PUNIT",
115  [6] = "PCIE_WAKE1",
116  [7] = "PCIE_WAKE2",
117  [8] = "PCIE_WAKE3",
118  [9] = "PCI_EXP",
119  [10] = "BATLOW",
120  [11] = "CSE_PME",
121  [12] = "XDCI_PME",
122  [13] = "XHCI_PME",
123  [14] = "AVS_PME",
124  [15] = "GPIO_TIER1_SCI",
125  [16] = "SMB_WAK",
126  [17] = "SATA_PME",
127  };
128 
129  *a = ARRAY_SIZE(gpe_sts_bits);
130  return gpe_sts_bits;
131 }
132 
134 {
135  uint32_t gen_pmcon1;
136 
137  gen_pmcon1 = read32((void *)(pmc_bar + GEN_PMCON1));
138  /* Clear the status bits. The RPS field is cleared on a 0 write. */
139  write32((void *)(pmc_bar + GEN_PMCON1), gen_pmcon1 & ~RPS);
140 }
141 
143 {
145 
146  config = config_of_soc();
147 
148  /* Assign to out variable */
149  *dw0 = config->gpe0_dw1;
150  *dw1 = config->gpe0_dw2;
151  *dw2 = config->gpe0_dw3;
152 }
153 
155 {
156  uintptr_t pmc_bar0 = soc_read_pmc_base();
157 
160 
161  ps->prsts = read32((void *)(pmc_bar0 + PRSTS));
162  ps->gen_pmcon1 = read32((void *)(pmc_bar0 + GEN_PMCON1));
163  ps->gen_pmcon2 = read32((void *)(pmc_bar0 + GEN_PMCON2));
164  ps->gen_pmcon3 = read32((void *)(pmc_bar0 + GEN_PMCON3));
165 
166  printk(BIOS_DEBUG, "prsts: %08x\n",
167  ps->prsts);
168  printk(BIOS_DEBUG, "tco_sts: %04x %04x\n",
169  ps->tco1_sts, ps->tco2_sts);
171  "gen_pmcon1: %08x gen_pmcon2: %08x gen_pmcon3: %08x\n",
172  ps->gen_pmcon1, ps->gen_pmcon2, ps->gen_pmcon3);
173 }
174 
175 /* Return 0, 3, or 5 to indicate the previous sleep state. */
177  int prev_sleep_state)
178 {
179  /* WAK_STS bit will not be set when waking from G3 state */
180 
181  if (!(ps->pm1_sts & WAK_STS) && (ps->gen_pmcon1 & COLD_BOOT_STS))
183  return prev_sleep_state;
184 }
185 
186 static int rtc_failed(uint32_t gen_pmcon1)
187 {
188  return !!(gen_pmcon1 & RPS);
189 }
190 
192 {
193  const struct chipset_power_state *ps;
194 
195  if (acpi_pm_state_for_rtc(&ps) < 0)
196  return 1;
197 
198  return rtc_failed(ps->gen_pmcon1);
199 }
200 
202 {
203  uintptr_t pmc_bar = soc_read_pmc_base();
204  uint32_t gen_pmcon1 = read32((void *)(pmc_bar + GEN_PMCON1));
206 
207  if (rtc_failure) {
208  printk(BIOS_INFO, "RTC failed!\n");
209 
210  /* We do not want to write 1 to clear-1 bits. Set them to 0. */
212 
213  /* RPS is write 0 to clear. */
214  gen_pmcon1 &= ~RPS;
215 
216  write32((void *)(pmc_bar + GEN_PMCON1), gen_pmcon1);
217  }
218 
219  return rtc_failure;
220 }
221 
222 /* STM Support */
224 {
225  return (uint16_t) ACPI_BASE_ADDRESS;
226 }
227 
228 void pmc_soc_set_afterg3_en(const bool on)
229 {
231  uint32_t reg32;
232 
233  reg32 = read32p(gen_pmcon1);
234  if (on)
235  reg32 &= ~SLEEP_AFTER_POWER_FAIL;
236  else
237  reg32 |= SLEEP_AFTER_POWER_FAIL;
238  write32p(gen_pmcon1, reg32);
239 }
int acpi_pm_state_for_rtc(const struct chipset_power_state **ps)
Definition: acpi_pm.c:51
#define GPE0_STS_BIT
Definition: pm.h:67
#define SMI_ON_SLP_EN_STS_BIT
Definition: pm.h:71
#define SCI_EN
Definition: pm.h:30
#define SPI_SMI_STS_BIT
Definition: pm.h:56
#define PM1_STS
Definition: pm.h:12
#define TCO_STS_BIT
Definition: pm.h:63
#define PERIODIC_STS_BIT
Definition: pm.h:62
#define GPIO_STS_BIT
Definition: pm.h:66
#define LEGACY_USB_STS_BIT
Definition: pm.h:72
#define PM1_STS_BIT
Definition: pm.h:68
#define BIOS_STS_BIT
Definition: pm.h:73
#define PCI_EXP_SMI_STS_BIT
Definition: pm.h:59
#define GPIO_UNLOCK_SMI_STS_BIT
Definition: pm.h:55
#define APM_STS_BIT
Definition: pm.h:70
#define SMBUS_SMI_STS_BIT
Definition: pm.h:60
#define XHCI_SMI_STS_BIT
Definition: pm.h:52
#define SERIRQ_SMI_STS_BIT
Definition: pm.h:61
#define SWSMI_TMR_STS_BIT
Definition: pm.h:69
#define MC_SMI_STS_BIT
Definition: pm.h:108
#define GEN_PMCON1_CLR1_BITS
Definition: pm.h:164
#define GEN_PMCON1
Definition: pm.h:154
#define COLD_BOOT_STS
Definition: pm.h:156
#define SCC2_SMI_STS_BIT
Definition: pm.h:99
#define GEN_PMCON2
Definition: pm.h:167
#define SCS_SMI_STS_BIT
Definition: pm.h:101
#define PMC_OCP_SMI_STS_BIT
Definition: pm.h:96
#define SPI_SSMI_STS_BIT
Definition: pm.h:98
#define GEN_PMCON3
Definition: pm.h:168
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define PWRBTN_STS
Definition: southbridge.h:30
#define WAK_STS
Definition: southbridge.h:27
#define printk(level,...)
Definition: stdlib.h:16
u16 inw(u16 port)
#define RPS
Definition: i440bx.h:45
@ ACPI_S5
Definition: acpi.h:1385
#define config_of_soc()
Definition: device.h:394
static __always_inline uint32_t read32p(const uintptr_t addr)
Definition: mmio.h:220
static __always_inline void write32p(const uintptr_t addr, const uint32_t value)
Definition: mmio.h:240
#define PCH_PWRM_BASE_ADDRESS
Definition: iomap.h:70
#define ACPI_BASE_ADDRESS
Definition: iomap.h:99
#define SLEEP_AFTER_POWER_FAIL
Definition: pmc.h:51
#define ETR
Definition: pmc.h:63
#define PRSTS
Definition: pmc.h:77
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
enum board_config config
Definition: memory.c:448
static int prev_sleep_state(const struct chipset_power_state *ps)
Definition: power_state.c:36
const char *const * soc_std_gpe_sts_array(size_t *a)
Definition: pmutil.c:99
uint16_t get_pmbase(void)
Definition: pmutil.c:254
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
Definition: pmutil.c:157
const char *const * soc_smi_sts_array(size_t *a)
Definition: pmutil.c:40
void pmc_soc_set_afterg3_en(const bool on)
Definition: pmutil.c:263
uint8_t * pmc_mmio_regs(void)
Definition: pmutil.c:142
int soc_get_rtc_failed(void)
Definition: pmutil.c:174
int vbnv_cmos_failed(void)
Definition: pmutil.c:184
uint32_t * soc_pmc_etr_addr(void)
Definition: pmutil.c:152
int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state)
Definition: pmutil.c:198
const char *const * soc_tco_sts_array(size_t *a)
Definition: pmutil.c:72
void soc_fill_power_state(struct chipset_power_state *ps)
Definition: pmutil.c:228
uintptr_t soc_read_pmc_base(void)
Definition: pmutil.c:147
#define TCO2_STS
Definition: smbus.h:9
#define TCO1_STS
Definition: smbus.h:7
static int rtc_failed(uint32_t gen_pmcon1)
Definition: pmutil.c:186
uint32_t soc_get_smi_status(uint32_t generic_sts)
Definition: pmutil.c:80
void soc_clear_pm_registers(uintptr_t pmc_bar)
Definition: pmutil.c:133
int rtc_failure(void)
Definition: pmutil.c:330
uint32_t pmc_read_pm1_control(void)
Definition: pmclib.c:196
uint16_t tco_read_reg(uint16_t tco_reg)
Definition: tco.c:32
#define DEVTREE_CONST
Definition: stddef.h:30
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned char uint8_t
Definition: stdint.h:8
uint16_t tco2_sts
Definition: pm.h:146
uint32_t gen_pmcon3
Definition: pm.h:233
uint16_t tco1_sts
Definition: pm.h:145
uint32_t gen_pmcon2
Definition: pm.h:232
uint32_t gen_pmcon1
Definition: pm.h:231
uint16_t pm1_sts
Definition: pm.h:142
uint32_t prsts
Definition: pm.h:230