blob: 9420b005e2ba7c084bc2b55409e6cb9c65613fa2 [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>
Arthur Heymansd90154c2022-12-02 13:27:35 +01006#include <arch/ioapic.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +05307#include <device/mmio.h>
8#include <arch/smp/mpspec.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +05309#include <console/console.h>
10#include <device/device.h>
11#include <device/pci_ops.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053012#include <intelblocks/cpulib.h>
13#include <intelblocks/pmclib.h>
14#include <intelblocks/acpi.h>
15#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>
20#include <soc/soc_chip.h>
21#include <soc/systemagent.h>
Tarun Tulic66ea982022-05-03 20:35:47 +000022#include <cpu/cpu.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053023#include <types.h>
Subrata Banik2871e0e2020-09-27 11:30:58 +053024
Tarun Tulic66ea982022-05-03 20:35:47 +000025
26#define DEFAULT_CPU_D_STATE D0
27#define LPI_STATES_ALL 0xff
28#define LPI_REVISION 0
29#define LPI_ENABLED 1
30
31
Subrata Banik2871e0e2020-09-27 11:30:58 +053032/*
33 * List of supported C-states in this processor.
34 */
35enum {
36 C_STATE_C0, /* 0 */
37 C_STATE_C1, /* 1 */
38 C_STATE_C1E, /* 2 */
39 C_STATE_C6_SHORT_LAT, /* 3 */
40 C_STATE_C6_LONG_LAT, /* 4 */
41 C_STATE_C7_SHORT_LAT, /* 5 */
42 C_STATE_C7_LONG_LAT, /* 6 */
43 C_STATE_C7S_SHORT_LAT, /* 7 */
44 C_STATE_C7S_LONG_LAT, /* 8 */
45 C_STATE_C8, /* 9 */
46 C_STATE_C9, /* 10 */
47 C_STATE_C10, /* 11 */
48 NUM_C_STATES
49};
50
Subrata Banik2871e0e2020-09-27 11:30:58 +053051static const acpi_cstate_t cstate_map[NUM_C_STATES] = {
52 [C_STATE_C0] = {},
53 [C_STATE_C1] = {
54 .latency = C1_LATENCY,
55 .power = C1_POWER,
56 .resource = MWAIT_RES(0, 0),
57 },
58 [C_STATE_C1E] = {
59 .latency = C1_LATENCY,
60 .power = C1_POWER,
61 .resource = MWAIT_RES(0, 1),
62 },
63 [C_STATE_C6_SHORT_LAT] = {
64 .latency = C6_LATENCY,
65 .power = C6_POWER,
66 .resource = MWAIT_RES(2, 0),
67 },
68 [C_STATE_C6_LONG_LAT] = {
69 .latency = C6_LATENCY,
70 .power = C6_POWER,
71 .resource = MWAIT_RES(2, 1),
72 },
73 [C_STATE_C7_SHORT_LAT] = {
74 .latency = C7_LATENCY,
75 .power = C7_POWER,
76 .resource = MWAIT_RES(3, 0),
77 },
78 [C_STATE_C7_LONG_LAT] = {
79 .latency = C7_LATENCY,
80 .power = C7_POWER,
81 .resource = MWAIT_RES(3, 1),
82 },
83 [C_STATE_C7S_SHORT_LAT] = {
84 .latency = C7_LATENCY,
85 .power = C7_POWER,
86 .resource = MWAIT_RES(3, 2),
87 },
88 [C_STATE_C7S_LONG_LAT] = {
89 .latency = C7_LATENCY,
90 .power = C7_POWER,
91 .resource = MWAIT_RES(3, 3),
92 },
93 [C_STATE_C8] = {
94 .latency = C8_LATENCY,
95 .power = C8_POWER,
96 .resource = MWAIT_RES(4, 0),
97 },
98 [C_STATE_C9] = {
99 .latency = C9_LATENCY,
100 .power = C9_POWER,
101 .resource = MWAIT_RES(5, 0),
102 },
103 [C_STATE_C10] = {
104 .latency = C10_LATENCY,
105 .power = C10_POWER,
106 .resource = MWAIT_RES(6, 0),
107 },
108};
109
110static int cstate_set_non_s0ix[] = {
111 C_STATE_C1,
112 C_STATE_C6_LONG_LAT,
113 C_STATE_C7S_LONG_LAT
114};
115
116static int cstate_set_s0ix[] = {
117 C_STATE_C1,
Bernardo Perez Priegob4a09c02021-06-21 10:49:47 -0700118 C_STATE_C6_LONG_LAT,
Subrata Banik2871e0e2020-09-27 11:30:58 +0530119 C_STATE_C10
120};
121
Tarun Tulic66ea982022-05-03 20:35:47 +0000122enum dev_sleep_states {
123 D0, /* 0 */
124 D1, /* 1 */
125 D2, /* 2 */
126 D3, /* 3 */
127 NONE
128};
129
Angel Ponse9f10ff2021-10-17 13:28:23 +0200130const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
Subrata Banik2871e0e2020-09-27 11:30:58 +0530131{
132 static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
133 ARRAY_SIZE(cstate_set_non_s0ix))];
134 int *set;
135 int i;
136
137 config_t *config = config_of_soc();
138
139 int is_s0ix_enable = config->s0ix_enable;
140
141 if (is_s0ix_enable) {
142 *entries = ARRAY_SIZE(cstate_set_s0ix);
143 set = cstate_set_s0ix;
144 } else {
145 *entries = ARRAY_SIZE(cstate_set_non_s0ix);
146 set = cstate_set_non_s0ix;
147 }
148
149 for (i = 0; i < *entries; i++) {
Angel Pons14643b32021-10-17 13:21:05 +0200150 map[i] = cstate_map[set[i]];
Subrata Banik2871e0e2020-09-27 11:30:58 +0530151 map[i].ctype = i + 1;
152 }
153 return map;
154}
155
156void soc_power_states_generation(int core_id, int cores_per_package)
157{
158 config_t *config = config_of_soc();
159
160 if (config->eist_enable)
161 /* Generate P-state tables */
162 generate_p_state_entries(core_id, cores_per_package);
163}
164
165void soc_fill_fadt(acpi_fadt_t *fadt)
166{
167 const uint16_t pmbase = ACPI_BASE_ADDRESS;
168
169 config_t *config = config_of_soc();
170
171 fadt->pm_tmr_blk = pmbase + PM1_TMR;
172 fadt->pm_tmr_len = 4;
173 fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
174 fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
175 fadt->x_pm_tmr_blk.bit_offset = 0;
176 fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
Elyes Haouas987f1f42022-10-11 13:56:30 +0200177 fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
Subrata Banik2871e0e2020-09-27 11:30:58 +0530178 fadt->x_pm_tmr_blk.addrh = 0x0;
179
180 if (config->s0ix_enable)
181 fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0;
182}
183
Tarun Tulic66ea982022-05-03 20:35:47 +0000184static const struct {
185 uint8_t pci_dev;
186 enum dev_sleep_states min_sleep_state;
187} min_pci_sleep_states[] = {
188 { SA_DEVFN_ROOT, D3 },
189 { SA_DEVFN_CPU_PCIE1_0, D3 },
190 { SA_DEVFN_IGD, D3 },
191 { SA_DEVFN_DPTF, D3 },
192 { SA_DEVFN_IPU, D3 },
193 { SA_DEVFN_CPU_PCIE6_0, D3 },
194 { SA_DEVFN_CPU_PCIE6_2, D3 },
195 { SA_DEVFN_TBT0, D3 },
196 { SA_DEVFN_TBT1, D3 },
197 { SA_DEVFN_TBT2, D3 },
198 { SA_DEVFN_TBT3, D3 },
199 { SA_DEVFN_GNA, D3 },
200 { SA_DEVFN_TCSS_XHCI, D3 },
201 { SA_DEVFN_TCSS_XDCI, D3 },
202 { SA_DEVFN_TCSS_DMA0, D3 },
203 { SA_DEVFN_TCSS_DMA1, D3 },
204 { SA_DEVFN_VMD, D3 },
205 { PCH_DEVFN_I2C6, D3 },
206 { PCH_DEVFN_I2C7, D3 },
207 { PCH_DEVFN_THC0, D3 },
208 { PCH_DEVFN_THC1, D3 },
209 { PCH_DEVFN_XHCI, D3 },
210 { PCH_DEVFN_USBOTG, D3 },
211 { PCH_DEVFN_SRAM, D3 },
212 { PCH_DEVFN_CNVI_WIFI, D3 },
213 { PCH_DEVFN_I2C0, D3 },
214 { PCH_DEVFN_I2C1, D3 },
215 { PCH_DEVFN_I2C2, D3 },
216 { PCH_DEVFN_I2C3, D3 },
217 { PCH_DEVFN_CSE, D0 },
218 { PCH_DEVFN_SATA, D3 },
219 { PCH_DEVFN_I2C4, D3 },
220 { PCH_DEVFN_I2C5, D3 },
221 { PCH_DEVFN_UART2, D3 },
222 { PCH_DEVFN_PCIE1, D0 },
223 { PCH_DEVFN_PCIE2, D0 },
224 { PCH_DEVFN_PCIE3, D0 },
225 { PCH_DEVFN_PCIE4, D0 },
226 { PCH_DEVFN_PCIE5, D0 },
227 { PCH_DEVFN_PCIE6, D0 },
228 { PCH_DEVFN_PCIE7, D0 },
229 { PCH_DEVFN_PCIE8, D0 },
230 { PCH_DEVFN_PCIE9, D0 },
231 { PCH_DEVFN_PCIE10, D0 },
232 { PCH_DEVFN_PCIE11, D0 },
233 { PCH_DEVFN_PCIE12, D0 },
234 { PCH_DEVFN_UART0, D3 },
235 { PCH_DEVFN_UART1, D3 },
236 { PCH_DEVFN_GSPI0, D3 },
237 { PCH_DEVFN_GSPI1, D3 },
238 { PCH_DEVFN_ESPI, D0 },
239 { PCH_DEVFN_PMC, D0 },
240 { PCH_DEVFN_HDA, D0 },
241 { PCH_DEVFN_SPI, D3 },
242 { PCH_DEVFN_GBE, D3 },
243};
244
245static enum dev_sleep_states get_min_sleep_state(const struct device *dev)
246{
247 if (!is_dev_enabled(dev))
248 return NONE;
249
250 switch (dev->path.type) {
251 case DEVICE_PATH_APIC:
252 return DEFAULT_CPU_D_STATE;
253
254 case DEVICE_PATH_PCI:
Eran Mitrani13e151f2022-11-29 12:54:53 -0800255 /* skip external buses*/
256 if (dev->bus->secondary != 0)
257 return NONE;
Tarun Tulic66ea982022-05-03 20:35:47 +0000258 for (size_t i = 0; i < ARRAY_SIZE(min_pci_sleep_states); i++)
259 if (min_pci_sleep_states[i].pci_dev == dev->path.pci.devfn)
260 return min_pci_sleep_states[i].min_sleep_state;
261 printk(BIOS_WARNING, "Unknown min d_state for %x\n", dev->path.pci.devfn);
262 return NONE;
263
264 default:
265 return NONE;
266 }
267}
268
269/* Generate the LPI constraint table and return the number of devices included */
270void soc_lpi_get_constraints(void *unused)
271{
272 unsigned int num_entries;
273 const struct device *dev;
274 enum dev_sleep_states min_sleep_state;
275
276 num_entries = 0;
277
278 for (dev = all_devices; dev; dev = dev->next) {
279 if (get_min_sleep_state(dev) != NONE)
280 num_entries++;
281 }
282
283 acpigen_emit_byte(RETURN_OP);
284 acpigen_write_package(num_entries);
285
Arthur Heymansaab91212022-11-12 19:10:43 +0100286 size_t cpu_index = 0;
Tarun Tulic66ea982022-05-03 20:35:47 +0000287 for (dev = all_devices; dev; dev = dev->next) {
288 min_sleep_state = get_min_sleep_state(dev);
289 if (min_sleep_state == NONE)
290 continue;
291
292 acpigen_write_package(3);
293 {
Arthur Heymans026978b2022-05-14 16:16:36 +0200294 char path[32] = { 0 };
Tarun Tulic66ea982022-05-03 20:35:47 +0000295 /* Emit the device path */
296 switch (dev->path.type) {
297 case DEVICE_PATH_PCI:
298 acpigen_emit_namestring(acpi_device_path(dev));
299 break;
300
301 case DEVICE_PATH_APIC:
Arthur Heymansaab91212022-11-12 19:10:43 +0100302 snprintf(path, sizeof(path), CONFIG_ACPI_CPU_STRING,
303 cpu_index++);
Tarun Tulic66ea982022-05-03 20:35:47 +0000304 acpigen_emit_namestring(path);
305 break;
306
307 default:
308 /* Unhandled */
309 printk(BIOS_WARNING,
310 "Unhandled device path type %d\n", dev->path.type);
311 acpigen_emit_namestring(NULL);
312 break;
313 }
314
315 acpigen_write_integer(LPI_ENABLED);
316 acpigen_write_package(2);
317 {
318 acpigen_write_integer(LPI_REVISION);
319 acpigen_write_package(2); /* no optional device info */
320 {
321 /* Assume constraints apply to all entries */
322 acpigen_write_integer(LPI_STATES_ALL);
323 acpigen_write_integer(min_sleep_state); /* min D-state */
324 }
325 acpigen_write_package_end();
326 }
327 acpigen_write_package_end();
328 }
329 acpigen_write_package_end();
330 }
331
332 acpigen_write_package_end();
333 printk(BIOS_INFO, "Returning SoC specific constraint package for %d devices\n", num_entries);
334}
335
Subrata Banik2871e0e2020-09-27 11:30:58 +0530336uint32_t soc_read_sci_irq_select(void)
337{
Angel Ponsf585c6e2021-06-25 10:09:35 +0200338 return read32p(soc_read_pmc_base() + IRQ_REG);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530339}
340
341static unsigned long soc_fill_dmar(unsigned long current)
342{
Subrata Banik2871e0e2020-09-27 11:30:58 +0530343 const uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
344 const bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
345
Subrata Banik50134ec2021-06-09 04:14:50 +0530346 if (is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530347 const unsigned long tmp = current;
348
349 current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700350 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IGD, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530351
352 acpi_dmar_drhd_fixup(tmp, current);
353 }
354
Subrata Banik2871e0e2020-09-27 11:30:58 +0530355 const uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK;
356 const bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED;
357
Subrata Banik50134ec2021-06-09 04:14:50 +0530358 if (is_devfn_enabled(SA_DEVFN_IPU) && ipuvtbar && ipuvten) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530359 const unsigned long tmp = current;
360
361 current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700362 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IPU, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530363
364 acpi_dmar_drhd_fixup(tmp, current);
365 }
366
John Zhao24ae31c2021-04-17 13:45:00 -0700367 /* TCSS Thunderbolt root ports */
368 for (unsigned int i = 0; i < MAX_TBT_PCIE_PORT; i++) {
Subrata Banik50134ec2021-06-09 04:14:50 +0530369 if (is_devfn_enabled(SA_DEVFN_TBT(i))) {
John Zhao24ae31c2021-04-17 13:45:00 -0700370 const uint64_t tbtbar = MCHBAR64(TBTxBAR(i)) & VTBAR_MASK;
371 const bool tbten = MCHBAR32(TBTxBAR(i)) & VTBAR_ENABLED;
372 if (tbtbar && tbten) {
373 const unsigned long tmp = current;
374
375 current += acpi_create_dmar_drhd(current, 0, 0, tbtbar);
John Zhaobaecee12021-04-23 10:29:12 -0700376 current += acpi_create_dmar_ds_pci_br(current, 0,
377 SA_DEV_SLOT_TBT, i);
John Zhao24ae31c2021-04-17 13:45:00 -0700378
379 acpi_dmar_drhd_fixup(tmp, current);
380 }
381 }
382 }
383
Subrata Banik2871e0e2020-09-27 11:30:58 +0530384 const uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK;
385 const bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED;
386
387 if (vtvc0bar && vtvc0en) {
388 const unsigned long tmp = current;
389
390 current += acpi_create_dmar_drhd(current,
391 DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
Arthur Heymansd90154c2022-12-02 13:27:35 +0100392 current += acpi_create_dmar_ds_ioapic_from_hw(current,
393 IO_APIC_ADDR, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV,
Subrata Banik2871e0e2020-09-27 11:30:58 +0530394 V_P2SB_CFG_IBDF_FUNC);
395 current += acpi_create_dmar_ds_msi_hpet(current,
396 0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV,
397 V_P2SB_CFG_HBDF_FUNC);
398
399 acpi_dmar_drhd_fixup(tmp, current);
400 }
401
Subrata Banik2871e0e2020-09-27 11:30:58 +0530402 /* Add RMRR entry */
Subrata Banik50134ec2021-06-09 04:14:50 +0530403 if (is_devfn_enabled(SA_DEVFN_IGD)) {
Subrata Banik2871e0e2020-09-27 11:30:58 +0530404 const unsigned long tmp = current;
405 current += acpi_create_dmar_rmrr(current, 0,
406 sa_get_gsm_base(), sa_get_tolud_base() - 1);
John Zhaobaecee12021-04-23 10:29:12 -0700407 current += acpi_create_dmar_ds_pci(current, 0, SA_DEV_SLOT_IGD, 0);
Subrata Banik2871e0e2020-09-27 11:30:58 +0530408 acpi_dmar_rmrr_fixup(tmp, current);
409 }
410
411 return current;
412}
413
414unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
415 struct acpi_rsdp *rsdp)
416{
417 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
418
419 /*
420 * Create DMAR table only if we have VT-d capability and FSP does not override its
421 * feature.
422 */
423 if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) ||
424 !(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED))
425 return current;
426
427 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
428 acpi_create_dmar(dmar, DMAR_INTR_REMAP | DMA_CTRL_PLATFORM_OPT_IN_FLAG, soc_fill_dmar);
429 current += dmar->header.length;
430 current = acpi_align_current(current);
431 acpi_add_table(rsdp, dmar);
432
433 return current;
434}
435
Kyösti Mälkkic2b0a4f2020-06-28 22:39:59 +0300436void soc_fill_gnvs(struct global_nvs *gnvs)
Subrata Banik2871e0e2020-09-27 11:30:58 +0530437{
438 config_t *config = config_of_soc();
439
Subrata Banik2871e0e2020-09-27 11:30:58 +0530440 /* Enable DPTF based on mainboard configuration */
441 gnvs->dpte = config->dptf_enable;
442
Subrata Banik2871e0e2020-09-27 11:30:58 +0530443 /* Set USB2/USB3 wake enable bitmaps. */
444 gnvs->u2we = config->usb2_wake_enable_bitmap;
445 gnvs->u3we = config->usb3_wake_enable_bitmap;
Subrata Banik2871e0e2020-09-27 11:30:58 +0530446}
447
Subrata Banik2871e0e2020-09-27 11:30:58 +0530448int soc_madt_sci_irq_polarity(int sci)
449{
450 return MP_IRQ_POLARITY_HIGH;
451}