blob: d7405ccfde27226d36a36c640ada9e4efbcf4679 [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:
Eran Mitrani13e151f2022-11-29 12:54:53 -0800254 /* skip external buses*/
255 if (dev->bus->secondary != 0)
256 return NONE;
Tarun Tulic66ea982022-05-03 20:35:47 +0000257 for (size_t i = 0; i < ARRAY_SIZE(min_pci_sleep_states); i++)
258 if (min_pci_sleep_states[i].pci_dev == dev->path.pci.devfn)
259 return min_pci_sleep_states[i].min_sleep_state;
260 printk(BIOS_WARNING, "Unknown min d_state for %x\n", dev->path.pci.devfn);
261 return NONE;
262
263 default:
264 return NONE;
265 }
266}
267
268/* Generate the LPI constraint table and return the number of devices included */
269void soc_lpi_get_constraints(void *unused)
270{
271 unsigned int num_entries;
272 const struct device *dev;
273 enum dev_sleep_states min_sleep_state;
274
275 num_entries = 0;
276
277 for (dev = all_devices; dev; dev = dev->next) {
278 if (get_min_sleep_state(dev) != NONE)
279 num_entries++;
280 }
281
282 acpigen_emit_byte(RETURN_OP);
283 acpigen_write_package(num_entries);
284
Arthur Heymansaab91212022-11-12 19:10:43 +0100285 size_t cpu_index = 0;
Tarun Tulic66ea982022-05-03 20:35:47 +0000286 for (dev = all_devices; dev; dev = dev->next) {
287 min_sleep_state = get_min_sleep_state(dev);
288 if (min_sleep_state == NONE)
289 continue;
290
291 acpigen_write_package(3);
292 {
Arthur Heymans026978b2022-05-14 16:16:36 +0200293 char path[32] = { 0 };
Tarun Tulic66ea982022-05-03 20:35:47 +0000294 /* Emit the device path */
295 switch (dev->path.type) {
296 case DEVICE_PATH_PCI:
297 acpigen_emit_namestring(acpi_device_path(dev));
298 break;
299
300 case DEVICE_PATH_APIC:
Arthur Heymansaab91212022-11-12 19:10:43 +0100301 snprintf(path, sizeof(path), CONFIG_ACPI_CPU_STRING,
302 cpu_index++);
Tarun Tulic66ea982022-05-03 20:35:47 +0000303 acpigen_emit_namestring(path);
304 break;
305
306 default:
307 /* Unhandled */
308 printk(BIOS_WARNING,
309 "Unhandled device path type %d\n", dev->path.type);
310 acpigen_emit_namestring(NULL);
311 break;
312 }
313
314 acpigen_write_integer(LPI_ENABLED);
315 acpigen_write_package(2);
316 {
317 acpigen_write_integer(LPI_REVISION);
318 acpigen_write_package(2); /* no optional device info */
319 {
320 /* Assume constraints apply to all entries */
321 acpigen_write_integer(LPI_STATES_ALL);
322 acpigen_write_integer(min_sleep_state); /* min D-state */
323 }
324 acpigen_write_package_end();
325 }
326 acpigen_write_package_end();
327 }
328 acpigen_write_package_end();
329 }
330
331 acpigen_write_package_end();
332 printk(BIOS_INFO, "Returning SoC specific constraint package for %d devices\n", num_entries);
333}
334
Subrata Banik2871e0e2020-09-27 11:30:58 +0530335uint32_t soc_read_sci_irq_select(void)
336{
Angel Ponsf585c6e2021-06-25 10:09:35 +0200337 return read32p(soc_read_pmc_base() + IRQ_REG);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530338}
339
340static unsigned long soc_fill_dmar(unsigned long current)
341{
Subrata Banik2871e0e2020-09-27 11:30:58 +0530342 const uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
343 const bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
344
Subrata Banik50134ec2021-06-09 04:14:50 +0530345 if (is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530346 const unsigned long tmp = current;
347
348 current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700349 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IGD, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530350
351 acpi_dmar_drhd_fixup(tmp, current);
352 }
353
Subrata Banik2871e0e2020-09-27 11:30:58 +0530354 const uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK;
355 const bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED;
356
Subrata Banik50134ec2021-06-09 04:14:50 +0530357 if (is_devfn_enabled(SA_DEVFN_IPU) && ipuvtbar && ipuvten) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530358 const unsigned long tmp = current;
359
360 current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700361 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IPU, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530362
363 acpi_dmar_drhd_fixup(tmp, current);
364 }
365
John Zhao24ae31c2021-04-17 13:45:00 -0700366 /* TCSS Thunderbolt root ports */
367 for (unsigned int i = 0; i < MAX_TBT_PCIE_PORT; i++) {
Subrata Banik50134ec2021-06-09 04:14:50 +0530368 if (is_devfn_enabled(SA_DEVFN_TBT(i))) {
John Zhao24ae31c2021-04-17 13:45:00 -0700369 const uint64_t tbtbar = MCHBAR64(TBTxBAR(i)) & VTBAR_MASK;
370 const bool tbten = MCHBAR32(TBTxBAR(i)) & VTBAR_ENABLED;
371 if (tbtbar && tbten) {
372 const unsigned long tmp = current;
373
374 current += acpi_create_dmar_drhd(current, 0, 0, tbtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700375 current += acpi_create_dmar_ds_pci_br(current, 0,
376 SA_DEV_SLOT_TBT, i);
John Zhao24ae31c2021-04-17 13:45:00 -0700377
378 acpi_dmar_drhd_fixup(tmp, current);
379 }
380 }
381 }
382
Subrata Banik2871e0e2020-09-27 11:30:58 +0530383 const uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK;
384 const bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED;
385
386 if (vtvc0bar && vtvc0en) {
387 const unsigned long tmp = current;
388
389 current += acpi_create_dmar_drhd(current,
390 DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
391 current += acpi_create_dmar_ds_ioapic(current,
392 2, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV,
393 V_P2SB_CFG_IBDF_FUNC);
394 current += acpi_create_dmar_ds_msi_hpet(current,
395 0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV,
396 V_P2SB_CFG_HBDF_FUNC);
397
398 acpi_dmar_drhd_fixup(tmp, current);
399 }
400
Subrata Banik2871e0e2020-09-27 11:30:58 +0530401 /* Add RMRR entry */
Subrata Banik50134ec2021-06-09 04:14:50 +0530402 if (is_devfn_enabled(SA_DEVFN_IGD)) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530403 const unsigned long tmp = current;
404 current += acpi_create_dmar_rmrr(current, 0,
405 sa_get_gsm_base(), sa_get_tolud_base() - 1);
John Zhaobaecee12021-04-23 10:29:12 -0700406 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IGD, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530407 acpi_dmar_rmrr_fixup(tmp, current);
408 }
409
410 return current;
411}
412
413unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
414 struct acpi_rsdp *rsdp)
415{
416 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
417
418 /*
419 * Create DMAR table only if we have VT-d capability and FSP does not override its
420 * feature.
421 */
422 if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) ||
423 !(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED))
424 return current;
425
426 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
427 acpi_create_dmar(dmar, DMAR_INTR_REMAP | DMA_CTRL_PLATFORM_OPT_IN_FLAG, soc_fill_dmar);
428 current += dmar->header.length;
429 current = acpi_align_current(current);
430 acpi_add_table(rsdp, dmar);
431
432 return current;
433}
434
Kyösti Mälkkic2b0a4f2020-06-28 22:39:59 +0300435void soc_fill_gnvs(struct global_nvs *gnvs)
Subrata Banik2871e0e2020-09-27 11:30:58 +0530436{
437 config_t *config = config_of_soc();
438
Subrata Banik2871e0e2020-09-27 11:30:58 +0530439 /* Enable DPTF based on mainboard configuration */
440 gnvs->dpte = config->dptf_enable;
441
Subrata Banik2871e0e2020-09-27 11:30:58 +0530442 /* Set USB2/USB3 wake enable bitmaps. */
443 gnvs->u2we = config->usb2_wake_enable_bitmap;
444 gnvs->u3we = config->usb3_wake_enable_bitmap;
Subrata Banik2871e0e2020-09-27 11:30:58 +0530445}
446
Subrata Banik2871e0e2020-09-27 11:30:58 +0530447int soc_madt_sci_irq_polarity(int sci)
448{
449 return MP_IRQ_POLARITY_HIGH;
450}