blob: a418ae5bab70a94dbea0c132095cb68a8787ce6f [file] [log] [blame]
Rocky Phaguracced3462020-06-11 11:18:02 -07001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include "chip.h"
4#include <console/console.h>
5#include <device/device.h>
6#include <device/pci_ops.h>
7#include <intelblocks/pmc.h>
8#include <intelblocks/pmclib.h>
9#include <intelblocks/rtc.h>
10#include <reg_script.h>
11#include <soc/pci_devs.h>
12#include <soc/pm.h>
13
14/*
15 * Set which power state system will be after reapplying
16 * the power (from G3 State)
17 */
18void pmc_soc_set_afterg3_en(const bool on)
19{
20 uint8_t reg8;
21 reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B);
22 if (on)
23 reg8 &= ~SLEEP_AFTER_POWER_FAIL;
24 else
25 reg8 |= SLEEP_AFTER_POWER_FAIL;
26 pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8);
27}
28
29#if ENV_RAMSTAGE
30/* Fill up PMC resource structure */
31int pmc_soc_get_resources(struct pmc_resource_config *cfg)
32{
33 cfg->pwrmbase_offset = PWRMBASE;
34 cfg->pwrmbase_addr = PCH_PWRM_BASE_ADDRESS;
35 cfg->pwrmbase_size = PCH_PWRM_BASE_SIZE;
36 cfg->abase_offset = ABASE;
37 cfg->abase_addr = ACPI_BASE_ADDRESS;
38 cfg->abase_size = ACPI_BASE_SIZE;
39
40 return 0;
41}
42
43static const struct reg_script pch_pmc_misc_init_script[] = {
44 /* Enable SCI and clear SLP requests. */
45 REG_IO_RMW32(ACPI_BASE_ADDRESS + PM1_CNT, ~SLP_TYP, SCI_EN),
46 REG_SCRIPT_END
47};
48
49static const struct reg_script pmc_write1_to_clear_script[] = {
50 REG_PCI_OR32(GEN_PMCON_A, 0),
51 REG_PCI_OR32(GEN_PMCON_B, 0),
52 REG_PCI_OR32(GEN_PMCON_B, 0),
53 REG_RES_OR32(PWRMBASE, GBLRST_CAUSE0, 0),
54 REG_RES_OR32(PWRMBASE, GBLRST_CAUSE1, 0),
55 REG_SCRIPT_END
56};
57
58void pmc_soc_init(struct device *dev)
59{
60 pmc_set_power_failure_state(true);
61 pmc_gpe_init();
62
63 /* Note that certain bits may be cleared from running script as
64 * certain bit fields are write 1 to clear. */
65 reg_script_run_on_dev(dev, pch_pmc_misc_init_script);
66 pmc_set_acpi_mode();
67
68 /* Clear registers that contain write-1-to-clear bits. */
69 reg_script_run_on_dev(dev, pmc_write1_to_clear_script);
70}
71#endif
72
73/*
74 * GPE0
75 */
76
77const char *const *soc_std_gpe_sts_array(size_t *gpe_arr)
78{
79 static const char *const gpe_sts_bits[] = {
80 };
81
82 *gpe_arr = ARRAY_SIZE(gpe_sts_bits);
83 return gpe_sts_bits;
84}
85
86uint8_t *pmc_mmio_regs(void)
87{
88 return (void *)(uintptr_t) pci_read_config32(PCH_DEV_PMC, PWRMBASE);
89}
90
91uintptr_t soc_read_pmc_base(void)
92{
93 return (uintptr_t) (pmc_mmio_regs());
94}
95
96uint32_t *soc_pmc_etr_addr(void)
97{
98 /*
99 * The pointer returned must not be cached, because the address depends on the
100 * MMCONF base address and the assigned PCI bus number, which both may change
101 * during the boot process!
102 */
103 return pci_mmio_config32_addr(PCH_DEVFN_PMC << 12, ETR);
104}
105
106void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
107{
108 /* No functionality for this yet */
109}
110
111int rtc_failure(void)
112{
113 u8 reg8;
114 int rtc_failed;
115 /* PMC Controller Device 0x1F, Func 02 */
116 reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B);
117 rtc_failed = reg8 & RTC_BATTERY_DEAD;
118 if (rtc_failed) {
119 reg8 &= ~RTC_BATTERY_DEAD;
120 pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8);
121 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
122 }
123
124 return !!rtc_failed;
125}
126
127/* Return 0, 3, or 5 to indicate the previous sleep state. */
128int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state)
129{
130 /*
131 * Check for any power failure to determine if this a wake from
132 * S5 because the PCH does not set the WAK_STS bit when waking
133 * from a true G3 state.
134 */
135 if (!(ps->pm1_sts & WAK_STS) &&
136 (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR)))
137 prev_sleep_state = ACPI_S5;
138
139 return prev_sleep_state;
140}
141
142void soc_fill_power_state(struct chipset_power_state *ps)
143{
144 uint8_t *pmc;
145
146 ps->gen_pmcon_a = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_A);
147 ps->gen_pmcon_b = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_B);
148
149 pmc = pmc_mmio_regs();
150 ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
151 ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
152
153 printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
154 ps->gen_pmcon_a, ps->gen_pmcon_b);
155
156 printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
157 ps->gblrst_cause[0], ps->gblrst_cause[1]);
158}
159
160/* STM Support */
161uint16_t get_pmbase(void)
162{
163 return ACPI_BASE_ADDRESS;
164}
165
166const char *const *soc_smi_sts_array(size_t *smi_arr)
167{
168 static const char *const smi_sts_bits[] = {
169 [2] = "BIOS",
170 [3] = "LEGACY_USB",
171 [4] = "SLP_SMI",
172 [5] = "APM",
173 [6] = "SWSMI_TMR",
174 [7] = "BIOS_RLS",
175 [8] = "PM1",
176 [9] = "GPE0",
177 [10] = "GPI",
178 [11] = "MCSMI",
179 [12] = "DEVMON",
180 [13] = "TCO",
181 [14] = "PERIODIC",
182 [20] = "PCI_EXP_SMI",
183 [23] = "IE_SMI",
184 [25] = "SCC_SMI",
185 [26] = "SPI",
186 [27] = "GPIO_UNLOCK",
187 [28] = "ESPI_SMI",
188 [29] = "SERIAL_I/O",
189 [30] = "ME_SMI",
190 [31] = "XHCI",
191 };
192
193 *smi_arr = ARRAY_SIZE(smi_sts_bits);
194 return smi_sts_bits;
195}