blob: b057ab23fce8df5c14be76ffd282b0349909aae3 [file] [log] [blame]
Jingle Hsue07ea4c2020-07-01 18:26:49 +08001/* 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
Angel Pons6a2ece72021-04-17 13:30:40 +02008#define __SIMPLE_DEVICE__
9
Jingle Hsue07ea4c2020-07-01 18:26:49 +080010#include <console/console.h>
Angel Pons6a2ece72021-04-17 13:30:40 +020011#include <device/pci.h>
12#include <intelblocks/pmclib.h>
13#include <intelblocks/rtc.h>
14#include <soc/pci_devs.h>
15#include <soc/pm.h>
16#include <soc/pmc.h>
17#include <types.h>
18
19/*
20 * SMI
21 */
22
23const char *const *soc_smi_sts_array(size_t *smi_arr)
24{
25 static const char *const smi_sts_bits[] = {
26 [2] = "BIOS",
27 [3] = "LEGACY_USB",
28 [4] = "SLP_SMI",
29 [5] = "APM",
30 [6] = "SWSMI_TMR",
31 [7] = "BIOS_RLS",
32 [8] = "PM1",
33 [9] = "GPE0",
34 [10] = "GPI",
35 [11] = "MCSMI",
36 [12] = "DEVMON",
37 [13] = "TCO",
38 [14] = "PERIODIC",
39 [20] = "PCI_EXP_SMI",
40 [23] = "IE_SMI",
41 [25] = "SCC_SMI",
42 [26] = "SPI",
43 [27] = "GPIO_UNLOCK",
44 [28] = "ESPI_SMI",
45 [29] = "SERIAL_I/O",
46 [30] = "ME_SMI",
47 [31] = "XHCI",
48 };
49
50 *smi_arr = ARRAY_SIZE(smi_sts_bits);
51 return smi_sts_bits;
52}
53
54/*
55 * TCO
56 */
57
58const char *const *soc_tco_sts_array(size_t *tco_arr)
59{
60 static const char *const tco_sts_bits[] = {
61 [0] = "NMI2SMI",
62 [1] = "OS_TCO",
63 [2] = "TCO_INT",
64 [3] = "TIMEOUT",
65 [7] = "NEWCENTURY",
66 [8] = "BIOSWR",
67 [9] = "CPUSCI",
68 [10] = "CPUSMI",
69 [12] = "CPUSERR",
70 [13] = "SLVSEL",
71 [16] = "INTRD_DET",
72 [17] = "SECOND_TO",
73 [20] = "SMLINK_SLV"
74 };
75
76 *tco_arr = ARRAY_SIZE(tco_sts_bits);
77 return tco_sts_bits;
78}
79
80/*
81 * GPE0
82 */
83
84const char *const *soc_std_gpe_sts_array(size_t *gpe_arr)
85{
86 static const char *const gpe_sts_bits[] = {
87 };
88
89 *gpe_arr = ARRAY_SIZE(gpe_sts_bits);
90 return gpe_sts_bits;
91}
92
93uint8_t *pmc_mmio_regs(void)
94{
95 return (void *)(uintptr_t) pci_read_config32(PCH_DEV_PMC, PWRMBASE);
96}
97
98uintptr_t soc_read_pmc_base(void)
99{
100 return (uintptr_t) (pmc_mmio_regs());
101}
102
103uint32_t *soc_pmc_etr_addr(void)
104{
105 /*
106 * The pointer returned must not be cached, because the address depends on the
107 * MMCONF base address and the assigned PCI bus number, which both may change
108 * during the boot process!
109 */
110 return pci_mmio_config32_addr(PCH_DEVFN_PMC << 12, ETR);
111}
112
113void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
114{
115 /* No functionality for this yet */
116}
Jingle Hsue07ea4c2020-07-01 18:26:49 +0800117
118int soc_get_rtc_failed(void)
119{
120 uint32_t pmcon_b = pci_s_read_config32(PCH_DEV_PMC, GEN_PMCON_B);
121 int rtc_fail = !!(pmcon_b & RTC_BATTERY_DEAD);
122
123 if (rtc_fail)
124 printk(BIOS_ERR, "%s: RTC battery dead or removed\n", __func__);
125
126 return rtc_fail;
127}
Angel Pons6a2ece72021-04-17 13:30:40 +0200128
129int rtc_failure(void)
130{
131 u8 reg8;
132 int rtc_failed;
133 /* PMC Controller Device 0x1F, Func 02 */
134 reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B);
135 rtc_failed = reg8 & RTC_BATTERY_DEAD;
136 if (rtc_failed) {
137 reg8 &= ~RTC_BATTERY_DEAD;
138 pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8);
139 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
140 }
141
142 return !!rtc_failed;
143}
144
145/* Return 0, 3, or 5 to indicate the previous sleep state. */
146int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state)
147{
148 /*
149 * Check for any power failure to determine if this a wake from
150 * S5 because the PCH does not set the WAK_STS bit when waking
151 * from a true G3 state.
152 */
153 if (!(ps->pm1_sts & WAK_STS) &&
154 (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR)))
155 prev_sleep_state = ACPI_S5;
156
157 return prev_sleep_state;
158}
159
160void soc_fill_power_state(struct chipset_power_state *ps)
161{
162 uint8_t *pmc;
163
164 ps->gen_pmcon_a = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_A);
165 ps->gen_pmcon_b = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_B);
166
167 pmc = pmc_mmio_regs();
168 ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
169 ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
170
171 printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
172 ps->gen_pmcon_a, ps->gen_pmcon_b);
173
174 printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
175 ps->gblrst_cause[0], ps->gblrst_cause[1]);
176}
177
178/* STM Support */
179uint16_t get_pmbase(void)
180{
181 return ACPI_BASE_ADDRESS;
182}
183
184/*
185 * Set which power state system will be after reapplying
186 * the power (from G3 State)
187 */
188void pmc_soc_set_afterg3_en(const bool on)
189{
190 uint8_t reg8;
191 reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B);
192 if (on)
193 reg8 &= ~SLEEP_AFTER_POWER_FAIL;
194 else
195 reg8 |= SLEEP_AFTER_POWER_FAIL;
196 pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8);
197}