blob: a58c4f01f4e2bb177333ea3452845e0c477611a7 [file] [log] [blame]
Angel Ponsf5627e82020-04-05 15:46:52 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lijian Zhao2b074d92017-08-17 14:25:24 -07002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi.h>
Kyösti Mälkki0c1dd9c2020-06-17 23:37:49 +03004#include <acpi/acpi_gnvs.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07005#include <acpi/acpigen.h>
Arthur Heymansd90154c2022-12-02 13:27:35 +01006#include <arch/ioapic.h>
Lijian Zhao2b074d92017-08-17 14:25:24 -07007#include <arch/smp/mpspec.h>
Patrick Georgi39c3d392019-04-23 12:27:22 +02008#include <console/console.h>
John Zhaodb3f0e32019-03-15 16:54:27 -07009#include <device/mmio.h>
10#include <device/pci_ops.h>
Lijian Zhao2b074d92017-08-17 14:25:24 -070011#include <intelblocks/cpulib.h>
12#include <intelblocks/pmclib.h>
13#include <intelblocks/acpi.h>
John Zhaodb3f0e32019-03-15 16:54:27 -070014#include <intelblocks/p2sb.h>
Lijian Zhao2b074d92017-08-17 14:25:24 -070015#include <soc/cpu.h>
16#include <soc/iomap.h>
17#include <soc/nvs.h>
18#include <soc/pci_devs.h>
19#include <soc/pm.h>
John Zhaodb3f0e32019-03-15 16:54:27 -070020#include <soc/systemagent.h>
Lijian Zhao2b074d92017-08-17 14:25:24 -070021
Elyes HAOUASc3385072019-03-21 15:38:06 +010022#include "chip.h"
23
Shaunak Saha95b61752017-10-04 23:08:40 -070024/*
25 * List of supported C-states in this processor.
26 */
27enum {
28 C_STATE_C0, /* 0 */
29 C_STATE_C1, /* 1 */
30 C_STATE_C1E, /* 2 */
31 C_STATE_C6_SHORT_LAT, /* 3 */
32 C_STATE_C6_LONG_LAT, /* 4 */
33 C_STATE_C7_SHORT_LAT, /* 5 */
34 C_STATE_C7_LONG_LAT, /* 6 */
35 C_STATE_C7S_SHORT_LAT, /* 7 */
36 C_STATE_C7S_LONG_LAT, /* 8 */
37 C_STATE_C8, /* 9 */
38 C_STATE_C9, /* 10 */
39 C_STATE_C10, /* 11 */
40 NUM_C_STATES
41};
42
Shaunak Saha95b61752017-10-04 23:08:40 -070043static const acpi_cstate_t cstate_map[NUM_C_STATES] = {
44 [C_STATE_C0] = {},
45 [C_STATE_C1] = {
46 .latency = 0,
47 .power = C1_POWER,
48 .resource = MWAIT_RES(0, 0),
49 },
50 [C_STATE_C1E] = {
51 .latency = 0,
52 .power = C1_POWER,
53 .resource = MWAIT_RES(0, 1),
54 },
55 [C_STATE_C6_SHORT_LAT] = {
Nico Huber792ed632021-07-26 13:44:19 +000056 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
Shaunak Saha95b61752017-10-04 23:08:40 -070057 .power = C6_POWER,
58 .resource = MWAIT_RES(2, 0),
59 },
60 [C_STATE_C6_LONG_LAT] = {
Nico Huber792ed632021-07-26 13:44:19 +000061 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
Shaunak Saha95b61752017-10-04 23:08:40 -070062 .power = C6_POWER,
63 .resource = MWAIT_RES(2, 1),
64 },
65 [C_STATE_C7_SHORT_LAT] = {
Nico Huber792ed632021-07-26 13:44:19 +000066 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
Shaunak Saha95b61752017-10-04 23:08:40 -070067 .power = C7_POWER,
68 .resource = MWAIT_RES(3, 0),
69 },
70 [C_STATE_C7_LONG_LAT] = {
Nico Huber792ed632021-07-26 13:44:19 +000071 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
Shaunak Saha95b61752017-10-04 23:08:40 -070072 .power = C7_POWER,
73 .resource = MWAIT_RES(3, 1),
74 },
75 [C_STATE_C7S_SHORT_LAT] = {
Nico Huber792ed632021-07-26 13:44:19 +000076 .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
Shaunak Saha95b61752017-10-04 23:08:40 -070077 .power = C7_POWER,
78 .resource = MWAIT_RES(3, 2),
79 },
80 [C_STATE_C7S_LONG_LAT] = {
Nico Huber792ed632021-07-26 13:44:19 +000081 .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
Shaunak Saha95b61752017-10-04 23:08:40 -070082 .power = C7_POWER,
83 .resource = MWAIT_RES(3, 3),
84 },
85 [C_STATE_C8] = {
Nico Huber792ed632021-07-26 13:44:19 +000086 .latency = C_STATE_LATENCY_FROM_LAT_REG(3),
Shaunak Saha95b61752017-10-04 23:08:40 -070087 .power = C8_POWER,
88 .resource = MWAIT_RES(4, 0),
89 },
90 [C_STATE_C9] = {
Nico Huber792ed632021-07-26 13:44:19 +000091 .latency = C_STATE_LATENCY_FROM_LAT_REG(4),
Shaunak Saha95b61752017-10-04 23:08:40 -070092 .power = C9_POWER,
93 .resource = MWAIT_RES(5, 0),
94 },
95 [C_STATE_C10] = {
Nico Huber792ed632021-07-26 13:44:19 +000096 .latency = C_STATE_LATENCY_FROM_LAT_REG(5),
Shaunak Saha95b61752017-10-04 23:08:40 -070097 .power = C10_POWER,
98 .resource = MWAIT_RES(6, 0),
99 },
100};
101
Ronak Kanabarc6c4d002019-01-30 18:53:14 +0530102static int cstate_set_non_s0ix[] = {
Shaunak Saha95b61752017-10-04 23:08:40 -0700103 C_STATE_C1E,
104 C_STATE_C6_LONG_LAT,
105 C_STATE_C7S_LONG_LAT
106};
107
Ronak Kanabarc6c4d002019-01-30 18:53:14 +0530108static int cstate_set_s0ix[] = {
Shaunak Saha95b61752017-10-04 23:08:40 -0700109 C_STATE_C1E,
110 C_STATE_C7S_LONG_LAT,
111 C_STATE_C10
112};
113
Angel Ponse9f10ff2021-10-17 13:28:23 +0200114const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Shaunak Saha95b61752017-10-04 23:08:40 -0700115{
116 static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
117 ARRAY_SIZE(cstate_set_non_s0ix))];
118 int *set;
119 int i;
Kyösti Mälkki28dc7dc2019-07-12 13:10:19 +0300120
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300121 config_t *config = config_of_soc();
Kyösti Mälkki28dc7dc2019-07-12 13:10:19 +0300122
Shaunak Saha95b61752017-10-04 23:08:40 -0700123 int is_s0ix_enable = config->s0ix_enable;
124
125 if (is_s0ix_enable) {
126 *entries = ARRAY_SIZE(cstate_set_s0ix);
127 set = cstate_set_s0ix;
128 } else {
129 *entries = ARRAY_SIZE(cstate_set_non_s0ix);
130 set = cstate_set_non_s0ix;
131 }
132
133 for (i = 0; i < *entries; i++) {
Angel Pons14643b32021-10-17 13:21:05 +0200134 map[i] = cstate_map[set[i]];
Shaunak Saha95b61752017-10-04 23:08:40 -0700135 map[i].ctype = i + 1;
136 }
137 return map;
138}
139
140void soc_power_states_generation(int core_id, int cores_per_package)
141{
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300142 config_t *config = config_of_soc();
Kyösti Mälkki28dc7dc2019-07-12 13:10:19 +0300143
144 /* Generate P-state tables */
Shaunak Saha95b61752017-10-04 23:08:40 -0700145 if (config->eist_enable)
Shaunak Saha95b61752017-10-04 23:08:40 -0700146 generate_p_state_entries(core_id, cores_per_package);
147}
148
Lijian Zhao2b074d92017-08-17 14:25:24 -0700149void soc_fill_fadt(acpi_fadt_t *fadt)
150{
151 const uint16_t pmbase = ACPI_BASE_ADDRESS;
Kyösti Mälkki28dc7dc2019-07-12 13:10:19 +0300152 const struct soc_intel_cannonlake_config *config;
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300153 config = config_of_soc();
Lijian Zhao2b074d92017-08-17 14:25:24 -0700154
Meera Ravindranath48c78702019-12-12 10:37:49 +0530155 fadt->pm_tmr_blk = pmbase + PM1_TMR;
156 fadt->pm_tmr_len = 4;
Kyösti Mälkki88decca2023-04-28 07:04:34 +0300157
158 fill_fadt_extended_pm_io(fadt);
Lijian Zhao2b074d92017-08-17 14:25:24 -0700159
Duncan Laurie174ca432018-09-13 16:28:13 +0000160 if (config->s0ix_enable)
Vaibhav Shankar2da6ec42018-03-19 18:56:38 -0700161 fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0;
Lijian Zhao2b074d92017-08-17 14:25:24 -0700162}
Matt DeVillierb065e812023-10-21 20:44:58 -0500163
164static struct min_sleep_state min_pci_sleep_states[] = {
165 { SA_DEVFN_ROOT, ACPI_DEVICE_SLEEP_D3 },
166 { SA_DEVFN_PEG0, ACPI_DEVICE_SLEEP_D3 },
167 { SA_DEVFN_PEG1, ACPI_DEVICE_SLEEP_D3 },
168 { SA_DEVFN_PEG2, ACPI_DEVICE_SLEEP_D3 },
169 { SA_DEVFN_IGD, ACPI_DEVICE_SLEEP_D3 },
170 { SA_DEVFN_TS, ACPI_DEVICE_SLEEP_D3 },
171 { SA_DEVFN_IPU, ACPI_DEVICE_SLEEP_D3 },
172 { SA_DEVFN_GNA, ACPI_DEVICE_SLEEP_D3 },
173 { PCH_DEVFN_UFS, ACPI_DEVICE_SLEEP_D3 },
174 { PCH_DEVFN_GSPI2, ACPI_DEVICE_SLEEP_D3 },
175 { PCH_DEVFN_ISH, ACPI_DEVICE_SLEEP_D3 },
176 { PCH_DEVFN_XHCI, ACPI_DEVICE_SLEEP_D3 },
177 { PCH_DEVFN_USBOTG, ACPI_DEVICE_SLEEP_D3 },
178 { PCH_DEVFN_CNViWIFI, ACPI_DEVICE_SLEEP_D3 },
179 { PCH_DEVFN_SDCARD, ACPI_DEVICE_SLEEP_D3 },
180 { PCH_DEVFN_I2C0, ACPI_DEVICE_SLEEP_D3 },
181 { PCH_DEVFN_I2C1, ACPI_DEVICE_SLEEP_D3 },
182 { PCH_DEVFN_I2C2, ACPI_DEVICE_SLEEP_D3 },
183 { PCH_DEVFN_I2C3, ACPI_DEVICE_SLEEP_D3 },
184 { PCH_DEVFN_CSE, ACPI_DEVICE_SLEEP_D0 },
185 { PCH_DEVFN_SATA, ACPI_DEVICE_SLEEP_D3 },
186 { PCH_DEVFN_I2C4, ACPI_DEVICE_SLEEP_D3 },
187 { PCH_DEVFN_I2C5, ACPI_DEVICE_SLEEP_D3 },
188 { PCH_DEVFN_UART2, ACPI_DEVICE_SLEEP_D3 },
189 { PCH_DEVFN_EMMC, ACPI_DEVICE_SLEEP_D3 },
190 { PCH_DEVFN_PCIE1, ACPI_DEVICE_SLEEP_D0 },
191 { PCH_DEVFN_PCIE2, ACPI_DEVICE_SLEEP_D0 },
192 { PCH_DEVFN_PCIE3, ACPI_DEVICE_SLEEP_D0 },
193 { PCH_DEVFN_PCIE4, ACPI_DEVICE_SLEEP_D0 },
194 { PCH_DEVFN_PCIE5, ACPI_DEVICE_SLEEP_D0 },
195 { PCH_DEVFN_PCIE6, ACPI_DEVICE_SLEEP_D0 },
196 { PCH_DEVFN_PCIE7, ACPI_DEVICE_SLEEP_D0 },
197 { PCH_DEVFN_PCIE8, ACPI_DEVICE_SLEEP_D0 },
198 { PCH_DEVFN_PCIE9, ACPI_DEVICE_SLEEP_D0 },
199 { PCH_DEVFN_PCIE10, ACPI_DEVICE_SLEEP_D0 },
200 { PCH_DEVFN_PCIE11, ACPI_DEVICE_SLEEP_D0 },
201 { PCH_DEVFN_PCIE12, ACPI_DEVICE_SLEEP_D0 },
202 { PCH_DEVFN_PCIE13, ACPI_DEVICE_SLEEP_D0 },
203 { PCH_DEVFN_PCIE14, ACPI_DEVICE_SLEEP_D0 },
204 { PCH_DEVFN_PCIE15, ACPI_DEVICE_SLEEP_D0 },
205 { PCH_DEVFN_PCIE16, ACPI_DEVICE_SLEEP_D0 },
206 { PCH_DEVFN_PCIE17, ACPI_DEVICE_SLEEP_D0 },
207 { PCH_DEVFN_PCIE18, ACPI_DEVICE_SLEEP_D0 },
208 { PCH_DEVFN_PCIE19, ACPI_DEVICE_SLEEP_D0 },
209 { PCH_DEVFN_PCIE20, ACPI_DEVICE_SLEEP_D0 },
210 { PCH_DEVFN_PCIE21, ACPI_DEVICE_SLEEP_D0 },
211 { PCH_DEVFN_PCIE22, ACPI_DEVICE_SLEEP_D0 },
212 { PCH_DEVFN_PCIE23, ACPI_DEVICE_SLEEP_D0 },
213 { PCH_DEVFN_PCIE24, ACPI_DEVICE_SLEEP_D0 },
214 { PCH_DEVFN_UART0, ACPI_DEVICE_SLEEP_D3 },
215 { PCH_DEVFN_UART1, ACPI_DEVICE_SLEEP_D3 },
216 { PCH_DEVFN_GSPI0, ACPI_DEVICE_SLEEP_D3 },
217 { PCH_DEVFN_GSPI1, ACPI_DEVICE_SLEEP_D3 },
218 { PCH_DEVFN_LPC, ACPI_DEVICE_SLEEP_D0 },
219 { PCH_DEVFN_P2SB, ACPI_DEVICE_SLEEP_D0 },
220 { PCH_DEVFN_HDA, ACPI_DEVICE_SLEEP_D0 },
221 { PCH_DEVFN_SMBUS, ACPI_DEVICE_SLEEP_D0 },
222 { PCH_DEVFN_SPI, ACPI_DEVICE_SLEEP_D3 },
223 { PCH_DEVFN_GBE, ACPI_DEVICE_SLEEP_D3 },
224 { PCH_DEVFN_TRACEHUB, ACPI_DEVICE_SLEEP_D3 },
225};
226
227struct min_sleep_state *soc_get_min_sleep_state_array(size_t *size)
228{
229 *size = ARRAY_SIZE(min_pci_sleep_states);
230 return min_pci_sleep_states;
231}
232
Lijian Zhao2b074d92017-08-17 14:25:24 -0700233uint32_t soc_read_sci_irq_select(void)
234{
Angel Ponsf585c6e2021-06-25 10:09:35 +0200235 return read32p(soc_read_pmc_base() + IRQ_REG);
Lijian Zhao2b074d92017-08-17 14:25:24 -0700236}
237
Kyösti Mälkkic2b0a4f2020-06-28 22:39:59 +0300238void soc_fill_gnvs(struct global_nvs *gnvs)
Lijian Zhao2b074d92017-08-17 14:25:24 -0700239{
Kyösti Mälkki28dc7dc2019-07-12 13:10:19 +0300240 const struct soc_intel_cannonlake_config *config;
Kyösti Mälkkid5f645c2019-09-28 00:20:27 +0300241 config = config_of_soc();
Lijian Zhao2b074d92017-08-17 14:25:24 -0700242
Lijian Zhao2b074d92017-08-17 14:25:24 -0700243 /* Enable DPTF based on mainboard configuration */
244 gnvs->dpte = config->dptf_enable;
245
Lijian Zhao2b074d92017-08-17 14:25:24 -0700246 /* Set USB2/USB3 wake enable bitmaps. */
247 gnvs->u2we = config->usb2_wake_enable_bitmap;
248 gnvs->u3we = config->usb3_wake_enable_bitmap;
249}
250
Lijian Zhao2b074d92017-08-17 14:25:24 -0700251int soc_madt_sci_irq_polarity(int sci)
252{
253 return MP_IRQ_POLARITY_HIGH;
254}
Lijian Zhao5ff742c2018-12-27 17:01:09 -0800255
John Zhaodb3f0e32019-03-15 16:54:27 -0700256static unsigned long soc_fill_dmar(unsigned long current)
257{
John Zhaodb3f0e32019-03-15 16:54:27 -0700258 uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
259 bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
Felix Singerfbf260a2024-04-30 16:25:28 +0200260 const bool emit_igd = is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten;
Patrick Rudolpha9eec2c2020-07-28 12:05:17 +0200261 if (emit_igd) {
John Zhaodb3f0e32019-03-15 16:54:27 -0700262 unsigned long tmp = current;
263
264 current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
265 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
266
267 acpi_dmar_drhd_fixup(tmp, current);
John Zhaodb3f0e32019-03-15 16:54:27 -0700268 }
269
John Zhaodb3f0e32019-03-15 16:54:27 -0700270 uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK;
271 bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED;
272
Felix Singerfbf260a2024-04-30 16:25:28 +0200273 if (is_devfn_enabled(SA_DEVFN_IPU) && ipuvtbar && ipuvten) {
John Zhaodb3f0e32019-03-15 16:54:27 -0700274 unsigned long tmp = current;
275
276 current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar);
277 current += acpi_create_dmar_ds_pci(current, 0, 5, 0);
278
279 acpi_dmar_drhd_fixup(tmp, current);
280 }
281
282 uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK;
283 bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED;
284
285 if (vtvc0bar && vtvc0en) {
286 const unsigned long tmp = current;
287
288 current += acpi_create_dmar_drhd(current,
289 DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
Arthur Heymansd90154c2022-12-02 13:27:35 +0100290 current += acpi_create_dmar_ds_ioapic_from_hw(current,
291 IO_APIC_ADDR, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV,
John Zhaodb3f0e32019-03-15 16:54:27 -0700292 V_P2SB_CFG_IBDF_FUNC);
293 current += acpi_create_dmar_ds_msi_hpet(current,
294 0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV,
295 V_P2SB_CFG_HBDF_FUNC);
296
297 acpi_dmar_drhd_fixup(tmp, current);
298 }
299
Patrick Rudolpha9eec2c2020-07-28 12:05:17 +0200300 /* Add RMRR entry after all DRHD entries */
301 if (emit_igd) {
302 const unsigned long tmp = current;
303
304 current += acpi_create_dmar_rmrr(current, 0,
305 sa_get_gsm_base(), sa_get_tolud_base() - 1);
306 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
307 acpi_dmar_rmrr_fixup(tmp, current);
308 }
John Zhao1159a162019-04-22 10:45:51 -0700309
John Zhaodb3f0e32019-03-15 16:54:27 -0700310 return current;
311}
312
Furquan Shaikh0f007d82020-04-24 06:41:18 -0700313unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
John Zhaodb3f0e32019-03-15 16:54:27 -0700314 struct acpi_rsdp *rsdp)
315{
316 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
317
318 /* Create DMAR table only if we have VT-d capability
319 * and FSP does not override its feature.
320 */
321 if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) ||
322 !(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED))
323 return current;
324
325 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
326 acpi_create_dmar(dmar, DMAR_INTR_REMAP, soc_fill_dmar);
John Zhao1159a162019-04-22 10:45:51 -0700327
John Zhaodb3f0e32019-03-15 16:54:27 -0700328 current += dmar->header.length;
329 current = acpi_align_current(current);
330 acpi_add_table(rsdp, dmar);
331
332 return current;
333}