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-only */
2 
3 /*
4  * Helper functions for dealing with power management registers
5  * and the differences between PCH variants.
6  */
7 
8 #define __SIMPLE_DEVICE__
9 
10 #include <acpi/acpi_pm.h>
11 #include <device/mmio.h>
12 #include <device/device.h>
13 #include <device/pci.h>
14 #include <device/pci_def.h>
15 #include <console/console.h>
16 #include <intelblocks/pmclib.h>
17 #include <intelblocks/rtc.h>
18 #include <intelblocks/tco.h>
19 #include <soc/espi.h>
20 #include <soc/gpe.h>
21 #include <soc/gpio.h>
22 #include <soc/iomap.h>
23 #include <soc/pci_devs.h>
24 #include <soc/pm.h>
25 #include <soc/smbus.h>
26 #include <soc/soc_chip.h>
27 #include <security/vboot/vbnv.h>
28 
29 /*
30  * SMI
31  */
32 
33 const char *const *soc_smi_sts_array(size_t *a)
34 {
35  static const char *const smi_sts_bits[] = {
36  [BIOS_STS_BIT] = "BIOS",
37  [LEGACY_USB_STS_BIT] = "LEGACY_USB",
38  [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI",
39  [APM_STS_BIT] = "APM",
40  [SWSMI_TMR_STS_BIT] = "SWSMI_TMR",
41  [PM1_STS_BIT] = "PM1",
42  [GPE0_STS_BIT] = "GPE0",
43  [GPIO_STS_BIT] = "GPI",
44  [MCSMI_STS_BIT] = "MCSMI",
45  [DEVMON_STS_BIT] = "DEVMON",
46  [TCO_STS_BIT] = "TCO",
47  [PERIODIC_STS_BIT] = "PERIODIC",
48  [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI",
49  [SMBUS_SMI_STS_BIT] = "SMBUS_SMI",
50  [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI",
51  [MONITOR_STS_BIT] = "MONITOR",
52  [SPI_SMI_STS_BIT] = "SPI",
53  [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK",
54  [ESPI_SMI_STS_BIT] = "ESPI_SMI",
55  };
56 
57  *a = ARRAY_SIZE(smi_sts_bits);
58  return smi_sts_bits;
59 }
60 
61 /*
62  * TCO
63  */
64 
65 const char *const *soc_tco_sts_array(size_t *a)
66 {
67  static const char *const tco_sts_bits[] = {
68  [0] = "NMI2SMI",
69  [1] = "SW_TCO",
70  [2] = "TCO_INT",
71  [3] = "TIMEOUT",
72  [7] = "NEWCENTURY",
73  [8] = "BIOSWR",
74  [9] = "DMISCI",
75  [10] = "DMISMI",
76  [12] = "DMISERR",
77  [13] = "SLVSEL",
78  [16] = "INTRD_DET",
79  [17] = "SECOND_TO",
80  [18] = "BOOT",
81  [20] = "SMLINK_SLV"
82  };
83 
84  *a = ARRAY_SIZE(tco_sts_bits);
85  return tco_sts_bits;
86 }
87 
88 /*
89  * GPE0
90  */
91 
92 const char *const *soc_std_gpe_sts_array(size_t *a)
93 {
94  static const char *const gpe_sts_bits[] = {
95  [1] = "HOTPLUG",
96  [2] = "SWGPE",
97  [6] = "TCO_SCI",
98  [7] = "SMB_WAK",
99  [9] = "PCI_EXP",
100  [10] = "BATLOW",
101  [11] = "PME",
102  [12] = "ME",
103  [13] = "PME_B0",
104  [14] = "eSPI",
105  [15] = "GPIO Tier-2",
106  [16] = "LAN_WAKE",
107  [18] = "WADT"
108  };
109 
110  *a = ARRAY_SIZE(gpe_sts_bits);
111  return gpe_sts_bits;
112 }
113 
114 void pmc_set_disb(void)
115 {
116  /* Set the DISB after DRAM init */
117  uint8_t disb_val;
118  /* Only care about bits [23:16] of register GEN_PMCON_A */
119  uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2);
120 
121  disb_val = read8(addr);
122  disb_val |= (DISB >> 16);
123 
124  /* Don't clear bits that are write-1-to-clear */
125  disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16);
126  write8(addr, disb_val);
127 }
128 
129 /*
130  * PMC controller gets hidden from PCI bus
131  * during FSP-Silicon init call. Hence PWRMBASE
132  * can't be accessible using PCI configuration space
133  * read/write.
134  */
136 {
137  return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS;
138 }
139 
141 {
142  return (uintptr_t)pmc_mmio_regs();
143 }
144 
146 {
147  return (uint32_t *)(soc_read_pmc_base() + ETR);
148 }
149 
151 {
153 
154  config = config_of_soc();
155 
156  /* Assign to out variable */
157  *dw0 = config->pmc_gpe0_dw0;
158  *dw1 = config->pmc_gpe0_dw1;
159  *dw2 = config->pmc_gpe0_dw2;
160 }
161 
162 static int rtc_failed(uint32_t gen_pmcon_b)
163 {
164  return !!(gen_pmcon_b & RTC_BATTERY_DEAD);
165 }
166 
167 static void clear_rtc_failed(void)
168 {
170 }
171 
172 static int check_rtc_failed(uint32_t gen_pmcon_b)
173 {
174  const int failed = rtc_failed(gen_pmcon_b);
175  if (failed) {
177  printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", failed);
178  }
179 
180  return failed;
181 }
182 
184 {
185  const struct chipset_power_state *ps;
186 
187  if (acpi_pm_state_for_rtc(&ps) < 0)
188  return 1;
189 
190  return check_rtc_failed(ps->gen_pmcon_b);
191 }
192 
194 {
196 }
197 
198 static inline int deep_s3_enabled(void)
199 {
200  uint32_t deep_s3_pol;
201 
202  deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL);
203  return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS));
204 }
205 
206 /* Return 0, 3, or 5 to indicate the previous sleep state. */
208 {
209  /*
210  * Check for any power failure to determine if this a wake from
211  * S5 because the PCH does not set the WAK_STS bit when waking
212  * from a true G3 state.
213  */
214  if (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))
216 
217  /*
218  * If waking from S3 determine if deep S3 is enabled. If not,
219  * need to check both deep sleep well and normal suspend well.
220  * Otherwise just check deep sleep well.
221  */
222  if (prev_sleep_state == ACPI_S3) {
223  /* PWR_FLR represents deep sleep power well loss. */
225 
226  /* If deep s3 isn't enabled check the suspend well too. */
227  if (!deep_s3_enabled())
228  mask |= SUS_PWR_FLR;
229 
230  if (ps->gen_pmcon_a & mask)
232  }
233 
234  return prev_sleep_state;
235 }
236 
238 {
239  uint8_t *pmc;
240 
243 
244  printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts);
245 
246  pmc = pmc_mmio_regs();
249  ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
250  ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
251 
252  printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
253  ps->gen_pmcon_a, ps->gen_pmcon_b);
254 
255  printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
256  ps->gblrst_cause[0], ps->gblrst_cause[1]);
257 }
258 
259 /* STM Support */
261 {
262  return (uint16_t) ACPI_BASE_ADDRESS;
263 }
264 
265 /*
266  * Set which power state system will be after reapplying
267  * the power (from G3 State)
268  */
269 void pmc_soc_set_afterg3_en(const bool on)
270 {
271  uint8_t reg8;
272  uint8_t *const pmcbase = pmc_mmio_regs();
273 
274  reg8 = read8(pmcbase + GEN_PMCON_A);
275  if (on)
276  reg8 &= ~SLEEP_AFTER_POWER_FAIL;
277  else
278  reg8 |= SLEEP_AFTER_POWER_FAIL;
279  write8(pmcbase + GEN_PMCON_A, reg8);
280 }
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 MCSMI_STS_BIT
Definition: pm.h:65
#define SMI_ON_SLP_EN_STS_BIT
Definition: pm.h:71
#define MONITOR_STS_BIT
Definition: pm.h:58
#define SPI_SMI_STS_BIT
Definition: pm.h:56
#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 ESPI_SMI_STS_BIT
Definition: pm.h:54
#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 SERIRQ_SMI_STS_BIT
Definition: pm.h:61
#define DEVMON_STS_BIT
Definition: pm.h:64
#define SWSMI_TMR_STS_BIT
Definition: pm.h:69
static void write8(void *addr, uint8_t val)
Definition: mmio.h:30
static uint32_t read32(const void *addr)
Definition: mmio.h:22
static uint8_t read8(const void *addr)
Definition: mmio.h:12
#define ARRAY_SIZE(a)
Definition: helpers.h:12
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
@ ACPI_S5
Definition: acpi.h:1385
@ ACPI_S3
Definition: acpi.h:1383
#define config_of_soc()
Definition: device.h:394
#define clrbits8(addr, clear)
Definition: mmio.h:24
#define PCH_PWRM_BASE_ADDRESS
Definition: iomap.h:70
#define ACPI_BASE_ADDRESS
Definition: iomap.h:99
#define S3DC_GATE_SUS
Definition: pmc.h:84
#define S3AC_GATE_SUS
Definition: pmc.h:85
#define GBLRST_CAUSE0
Definition: pmc.h:131
#define MS4V
Definition: pmc.h:26
#define PWR_FLR
Definition: pmc.h:30
#define SLEEP_AFTER_POWER_FAIL
Definition: pmc.h:51
#define S3_PWRGATE_POL
Definition: pmc.h:83
#define GEN_PMCON_B
Definition: pmc.h:53
#define ETR
Definition: pmc.h:63
#define DISB
Definition: pmc.h:21
#define GEN_PMCON_A
Definition: pmc.h:14
#define GBLRST_CAUSE1
Definition: pmc.h:133
#define RTC_BATTERY_DEAD
Definition: pmc.h:61
#define SUS_PWR_FLR
Definition: pmc.h:28
#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
void pmc_set_disb(void)
Definition: pmutil.c:121
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 const int mask[4]
Definition: gpio.c:308
uint16_t tco_read_reg(uint16_t tco_reg)
Definition: tco.c:32
static int rtc_failed(uint32_t gen_pmcon_b)
Definition: pmutil.c:162
static int deep_s3_enabled(void)
Definition: pmutil.c:198
static void clear_rtc_failed(void)
Definition: pmutil.c:167
static int check_rtc_failed(uint32_t gen_pmcon_b)
Definition: pmutil.c:172
static struct tegra_pmc_regs * pmc
Definition: clock.c:19
#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
uint16_t tco1_sts
Definition: pm.h:145
uint32_t gen_pmcon_b
Definition: pm.h:150
uint32_t gblrst_cause[2]
Definition: pm.h:151
uint32_t gen_pmcon_a
Definition: pm.h:149