blob: 1c820c27505bf1673dec76021d4dccbd1406d742 [file] [log] [blame]
Subrata Banik2871e0e2020-09-27 11:30:58 +05301/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <acpi/acpi.h>
4#include <acpi/acpi_gnvs.h>
5#include <acpi/acpigen.h>
6#include <device/mmio.h>
7#include <arch/smp/mpspec.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +05308#include <console/console.h>
9#include <device/device.h>
10#include <device/pci_ops.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053011#include <intelblocks/cpulib.h>
12#include <intelblocks/pmclib.h>
13#include <intelblocks/acpi.h>
14#include <soc/cpu.h>
15#include <soc/iomap.h>
16#include <soc/nvs.h>
17#include <soc/pci_devs.h>
18#include <soc/pm.h>
19#include <soc/soc_chip.h>
20#include <soc/systemagent.h>
Tarun Tulic66ea982022-05-03 20:35:47 +000021#include <cpu/cpu.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053022#include <types.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053023
Tarun Tulic66ea982022-05-03 20:35:47 +000024
25#define DEFAULT_CPU_D_STATE D0
26#define LPI_STATES_ALL 0xff
27#define LPI_REVISION 0
28#define LPI_ENABLED 1
29
30
Subrata Banik2871e0e2020-09-27 11:30:58 +053031/*
32 * List of supported C-states in this processor.
33 */
34enum {
35 C_STATE_C0, /* 0 */
36 C_STATE_C1, /* 1 */
37 C_STATE_C1E, /* 2 */
38 C_STATE_C6_SHORT_LAT, /* 3 */
39 C_STATE_C6_LONG_LAT, /* 4 */
40 C_STATE_C7_SHORT_LAT, /* 5 */
41 C_STATE_C7_LONG_LAT, /* 6 */
42 C_STATE_C7S_SHORT_LAT, /* 7 */
43 C_STATE_C7S_LONG_LAT, /* 8 */
44 C_STATE_C8, /* 9 */
45 C_STATE_C9, /* 10 */
46 C_STATE_C10, /* 11 */
47 NUM_C_STATES
48};
49
Subrata Banik2871e0e2020-09-27 11:30:58 +053050static const acpi_cstate_t cstate_map[NUM_C_STATES] = {
51 [C_STATE_C0] = {},
52 [C_STATE_C1] = {
53 .latency = C1_LATENCY,
54 .power = C1_POWER,
55 .resource = MWAIT_RES(0, 0),
56 },
57 [C_STATE_C1E] = {
58 .latency = C1_LATENCY,
59 .power = C1_POWER,
60 .resource = MWAIT_RES(0, 1),
61 },
62 [C_STATE_C6_SHORT_LAT] = {
63 .latency = C6_LATENCY,
64 .power = C6_POWER,
65 .resource = MWAIT_RES(2, 0),
66 },
67 [C_STATE_C6_LONG_LAT] = {
68 .latency = C6_LATENCY,
69 .power = C6_POWER,
70 .resource = MWAIT_RES(2, 1),
71 },
72 [C_STATE_C7_SHORT_LAT] = {
73 .latency = C7_LATENCY,
74 .power = C7_POWER,
75 .resource = MWAIT_RES(3, 0),
76 },
77 [C_STATE_C7_LONG_LAT] = {
78 .latency = C7_LATENCY,
79 .power = C7_POWER,
80 .resource = MWAIT_RES(3, 1),
81 },
82 [C_STATE_C7S_SHORT_LAT] = {
83 .latency = C7_LATENCY,
84 .power = C7_POWER,
85 .resource = MWAIT_RES(3, 2),
86 },
87 [C_STATE_C7S_LONG_LAT] = {
88 .latency = C7_LATENCY,
89 .power = C7_POWER,
90 .resource = MWAIT_RES(3, 3),
91 },
92 [C_STATE_C8] = {
93 .latency = C8_LATENCY,
94 .power = C8_POWER,
95 .resource = MWAIT_RES(4, 0),
96 },
97 [C_STATE_C9] = {
98 .latency = C9_LATENCY,
99 .power = C9_POWER,
100 .resource = MWAIT_RES(5, 0),
101 },
102 [C_STATE_C10] = {
103 .latency = C10_LATENCY,
104 .power = C10_POWER,
105 .resource = MWAIT_RES(6, 0),
106 },
107};
108
109static int cstate_set_non_s0ix[] = {
110 C_STATE_C1,
111 C_STATE_C6_LONG_LAT,
112 C_STATE_C7S_LONG_LAT
113};
114
115static int cstate_set_s0ix[] = {
116 C_STATE_C1,
Bernardo Perez Priegob4a09c02021-06-21 10:49:47 -0700117 C_STATE_C6_LONG_LAT,
Subrata Banik2871e0e2020-09-27 11:30:58 +0530118 C_STATE_C10
119};
120
Tarun Tulic66ea982022-05-03 20:35:47 +0000121enum dev_sleep_states {
122 D0, /* 0 */
123 D1, /* 1 */
124 D2, /* 2 */
125 D3, /* 3 */
126 NONE
127};
128
Angel Ponse9f10ff2021-10-17 13:28:23 +0200129const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Subrata Banik2871e0e2020-09-27 11:30:58 +0530130{
131 static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
132 ARRAY_SIZE(cstate_set_non_s0ix))];
133 int *set;
134 int i;
135
136 config_t *config = config_of_soc();
137
138 int is_s0ix_enable = config->s0ix_enable;
139
140 if (is_s0ix_enable) {
141 *entries = ARRAY_SIZE(cstate_set_s0ix);
142 set = cstate_set_s0ix;
143 } else {
144 *entries = ARRAY_SIZE(cstate_set_non_s0ix);
145 set = cstate_set_non_s0ix;
146 }
147
148 for (i = 0; i < *entries; i++) {
Angel Pons14643b32021-10-17 13:21:05 +0200149 map[i] = cstate_map[set[i]];
Subrata Banik2871e0e2020-09-27 11:30:58 +0530150 map[i].ctype = i + 1;
151 }
152 return map;
153}
154
155void soc_power_states_generation(int core_id, int cores_per_package)
156{
157 config_t *config = config_of_soc();
158
159 if (config->eist_enable)
160 /* Generate P-state tables */
161 generate_p_state_entries(core_id, cores_per_package);
162}
163
164void soc_fill_fadt(acpi_fadt_t *fadt)
165{
166 const uint16_t pmbase = ACPI_BASE_ADDRESS;
167
168 config_t *config = config_of_soc();
169
170 fadt->pm_tmr_blk = pmbase + PM1_TMR;
171 fadt->pm_tmr_len = 4;
172 fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
173 fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
174 fadt->x_pm_tmr_blk.bit_offset = 0;
175 fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
Elyes Haouas987f1f42022-10-11 13:56:30 +0200176 fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
Subrata Banik2871e0e2020-09-27 11:30:58 +0530177 fadt->x_pm_tmr_blk.addrh = 0x0;
178
179 if (config->s0ix_enable)
180 fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0;
181}
182
Tarun Tulic66ea982022-05-03 20:35:47 +0000183static const struct {
184 uint8_t pci_dev;
185 enum dev_sleep_states min_sleep_state;
186} min_pci_sleep_states[] = {
187 { SA_DEVFN_ROOT, D3 },
188 { SA_DEVFN_CPU_PCIE1_0, D3 },
189 { SA_DEVFN_IGD, D3 },
190 { SA_DEVFN_DPTF, D3 },
191 { SA_DEVFN_IPU, D3 },
192 { SA_DEVFN_CPU_PCIE6_0, D3 },
193 { SA_DEVFN_CPU_PCIE6_2, D3 },
194 { SA_DEVFN_TBT0, D3 },
195 { SA_DEVFN_TBT1, D3 },
196 { SA_DEVFN_TBT2, D3 },
197 { SA_DEVFN_TBT3, D3 },
198 { SA_DEVFN_GNA, D3 },
199 { SA_DEVFN_TCSS_XHCI, D3 },
200 { SA_DEVFN_TCSS_XDCI, D3 },
201 { SA_DEVFN_TCSS_DMA0, D3 },
202 { SA_DEVFN_TCSS_DMA1, D3 },
203 { SA_DEVFN_VMD, D3 },
204 { PCH_DEVFN_I2C6, D3 },
205 { PCH_DEVFN_I2C7, D3 },
206 { PCH_DEVFN_THC0, D3 },
207 { PCH_DEVFN_THC1, D3 },
208 { PCH_DEVFN_XHCI, D3 },
209 { PCH_DEVFN_USBOTG, D3 },
210 { PCH_DEVFN_SRAM, D3 },
211 { PCH_DEVFN_CNVI_WIFI, D3 },
212 { PCH_DEVFN_I2C0, D3 },
213 { PCH_DEVFN_I2C1, D3 },
214 { PCH_DEVFN_I2C2, D3 },
215 { PCH_DEVFN_I2C3, D3 },
216 { PCH_DEVFN_CSE, D0 },
217 { PCH_DEVFN_SATA, D3 },
218 { PCH_DEVFN_I2C4, D3 },
219 { PCH_DEVFN_I2C5, D3 },
220 { PCH_DEVFN_UART2, D3 },
221 { PCH_DEVFN_PCIE1, D0 },
222 { PCH_DEVFN_PCIE2, D0 },
223 { PCH_DEVFN_PCIE3, D0 },
224 { PCH_DEVFN_PCIE4, D0 },
225 { PCH_DEVFN_PCIE5, D0 },
226 { PCH_DEVFN_PCIE6, D0 },
227 { PCH_DEVFN_PCIE7, D0 },
228 { PCH_DEVFN_PCIE8, D0 },
229 { PCH_DEVFN_PCIE9, D0 },
230 { PCH_DEVFN_PCIE10, D0 },
231 { PCH_DEVFN_PCIE11, D0 },
232 { PCH_DEVFN_PCIE12, D0 },
233 { PCH_DEVFN_UART0, D3 },
234 { PCH_DEVFN_UART1, D3 },
235 { PCH_DEVFN_GSPI0, D3 },
236 { PCH_DEVFN_GSPI1, D3 },
237 { PCH_DEVFN_ESPI, D0 },
238 { PCH_DEVFN_PMC, D0 },
239 { PCH_DEVFN_HDA, D0 },
240 { PCH_DEVFN_SPI, D3 },
241 { PCH_DEVFN_GBE, D3 },
242};
243
244static enum dev_sleep_states get_min_sleep_state(const struct device *dev)
245{
246 if (!is_dev_enabled(dev))
247 return NONE;
248
249 switch (dev->path.type) {
250 case DEVICE_PATH_APIC:
251 return DEFAULT_CPU_D_STATE;
252
253 case DEVICE_PATH_PCI:
254 for (size_t i = 0; i < ARRAY_SIZE(min_pci_sleep_states); i++)
255 if (min_pci_sleep_states[i].pci_dev == dev->path.pci.devfn)
256 return min_pci_sleep_states[i].min_sleep_state;
257 printk(BIOS_WARNING, "Unknown min d_state for %x\n", dev->path.pci.devfn);
258 return NONE;
259
260 default:
261 return NONE;
262 }
263}
264
265/* Generate the LPI constraint table and return the number of devices included */
266void soc_lpi_get_constraints(void *unused)
267{
268 unsigned int num_entries;
269 const struct device *dev;
270 enum dev_sleep_states min_sleep_state;
271
272 num_entries = 0;
273
274 for (dev = all_devices; dev; dev = dev->next) {
275 if (get_min_sleep_state(dev) != NONE)
276 num_entries++;
277 }
278
279 acpigen_emit_byte(RETURN_OP);
280 acpigen_write_package(num_entries);
281
282 for (dev = all_devices; dev; dev = dev->next) {
283 min_sleep_state = get_min_sleep_state(dev);
284 if (min_sleep_state == NONE)
285 continue;
286
287 acpigen_write_package(3);
288 {
Arthur Heymans026978b2022-05-14 16:16:36 +0200289 char path[32] = { 0 };
Tarun Tulic66ea982022-05-03 20:35:47 +0000290 /* Emit the device path */
291 switch (dev->path.type) {
292 case DEVICE_PATH_PCI:
293 acpigen_emit_namestring(acpi_device_path(dev));
294 break;
295
296 case DEVICE_PATH_APIC:
Tarun Tulic66ea982022-05-03 20:35:47 +0000297 /* Lookup CPU id */
298 for (size_t i = 0; i < CONFIG_MAX_CPUS; i++) {
299 if (cpu_get_apic_id(i) == dev->path.apic.apic_id) {
300 snprintf(path, sizeof(path),
301 CONFIG_ACPI_CPU_STRING, i);
302 break;
303 }
304 }
305
306 acpigen_emit_namestring(path);
307 break;
308
309 default:
310 /* Unhandled */
311 printk(BIOS_WARNING,
312 "Unhandled device path type %d\n", dev->path.type);
313 acpigen_emit_namestring(NULL);
314 break;
315 }
316
317 acpigen_write_integer(LPI_ENABLED);
318 acpigen_write_package(2);
319 {
320 acpigen_write_integer(LPI_REVISION);
321 acpigen_write_package(2); /* no optional device info */
322 {
323 /* Assume constraints apply to all entries */
324 acpigen_write_integer(LPI_STATES_ALL);
325 acpigen_write_integer(min_sleep_state); /* min D-state */
326 }
327 acpigen_write_package_end();
328 }
329 acpigen_write_package_end();
330 }
331 acpigen_write_package_end();
332 }
333
334 acpigen_write_package_end();
335 printk(BIOS_INFO, "Returning SoC specific constraint package for %d devices\n", num_entries);
336}
337
Subrata Banik2871e0e2020-09-27 11:30:58 +0530338uint32_t soc_read_sci_irq_select(void)
339{
Angel Ponsf585c6e2021-06-25 10:09:35 +0200340 return read32p(soc_read_pmc_base() + IRQ_REG);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530341}
342
343static unsigned long soc_fill_dmar(unsigned long current)
344{
Subrata Banik2871e0e2020-09-27 11:30:58 +0530345 const uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
346 const bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
347
Subrata Banik50134ec2021-06-09 04:14:50 +0530348 if (is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530349 const unsigned long tmp = current;
350
351 current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700352 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IGD, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530353
354 acpi_dmar_drhd_fixup(tmp, current);
355 }
356
Subrata Banik2871e0e2020-09-27 11:30:58 +0530357 const uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK;
358 const bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED;
359
Subrata Banik50134ec2021-06-09 04:14:50 +0530360 if (is_devfn_enabled(SA_DEVFN_IPU) && ipuvtbar && ipuvten) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530361 const unsigned long tmp = current;
362
363 current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700364 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IPU, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530365
366 acpi_dmar_drhd_fixup(tmp, current);
367 }
368
John Zhao24ae31c2021-04-17 13:45:00 -0700369 /* TCSS Thunderbolt root ports */
370 for (unsigned int i = 0; i < MAX_TBT_PCIE_PORT; i++) {
Subrata Banik50134ec2021-06-09 04:14:50 +0530371 if (is_devfn_enabled(SA_DEVFN_TBT(i))) {
John Zhao24ae31c2021-04-17 13:45:00 -0700372 const uint64_t tbtbar = MCHBAR64(TBTxBAR(i)) & VTBAR_MASK;
373 const bool tbten = MCHBAR32(TBTxBAR(i)) & VTBAR_ENABLED;
374 if (tbtbar && tbten) {
375 const unsigned long tmp = current;
376
377 current += acpi_create_dmar_drhd(current, 0, 0, tbtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700378 current += acpi_create_dmar_ds_pci_br(current, 0,
379 SA_DEV_SLOT_TBT, i);
John Zhao24ae31c2021-04-17 13:45:00 -0700380
381 acpi_dmar_drhd_fixup(tmp, current);
382 }
383 }
384 }
385
Subrata Banik2871e0e2020-09-27 11:30:58 +0530386 const uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK;
387 const bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED;
388
389 if (vtvc0bar && vtvc0en) {
390 const unsigned long tmp = current;
391
392 current += acpi_create_dmar_drhd(current,
393 DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
394 current += acpi_create_dmar_ds_ioapic(current,
395 2, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV,
396 V_P2SB_CFG_IBDF_FUNC);
397 current += acpi_create_dmar_ds_msi_hpet(current,
398 0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV,
399 V_P2SB_CFG_HBDF_FUNC);
400
401 acpi_dmar_drhd_fixup(tmp, current);
402 }
403
Subrata Banik2871e0e2020-09-27 11:30:58 +0530404 /* Add RMRR entry */
Subrata Banik50134ec2021-06-09 04:14:50 +0530405 if (is_devfn_enabled(SA_DEVFN_IGD)) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530406 const unsigned long tmp = current;
407 current += acpi_create_dmar_rmrr(current, 0,
408 sa_get_gsm_base(), sa_get_tolud_base() - 1);
John Zhaobaecee12021-04-23 10:29:12 -0700409 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IGD, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530410 acpi_dmar_rmrr_fixup(tmp, current);
411 }
412
413 return current;
414}
415
416unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
417 struct acpi_rsdp *rsdp)
418{
419 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
420
421 /*
422 * Create DMAR table only if we have VT-d capability and FSP does not override its
423 * feature.
424 */
425 if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) ||
426 !(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED))
427 return current;
428
429 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
430 acpi_create_dmar(dmar, DMAR_INTR_REMAP | DMA_CTRL_PLATFORM_OPT_IN_FLAG, soc_fill_dmar);
431 current += dmar->header.length;
432 current = acpi_align_current(current);
433 acpi_add_table(rsdp, dmar);
434
435 return current;
436}
437
Kyösti Mälkkic2b0a4f2020-06-28 22:39:59 +0300438void soc_fill_gnvs(struct global_nvs *gnvs)
Subrata Banik2871e0e2020-09-27 11:30:58 +0530439{
440 config_t *config = config_of_soc();
441
Subrata Banik2871e0e2020-09-27 11:30:58 +0530442 /* Enable DPTF based on mainboard configuration */
443 gnvs->dpte = config->dptf_enable;
444
Subrata Banik2871e0e2020-09-27 11:30:58 +0530445 /* Set USB2/USB3 wake enable bitmaps. */
446 gnvs->u2we = config->usb2_wake_enable_bitmap;
447 gnvs->u3we = config->usb3_wake_enable_bitmap;
Subrata Banik2871e0e2020-09-27 11:30:58 +0530448}
449
Subrata Banik2871e0e2020-09-27 11:30:58 +0530450int soc_madt_sci_irq_polarity(int sci)
451{
452 return MP_IRQ_POLARITY_HIGH;
453}