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