1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <acpi/acpi_pm.h>
5 #include <acpi/acpigen.h>
6 #include <arch/ioapic.h>
7 #include <arch/smp/mpspec.h>
8 #include <console/console.h>
10 #include <cpu/intel/common/common.h>
11 #include <cpu/intel/msr.h>
12 #include <cpu/intel/turbo.h>
13 #include <cpu/x86/lapic.h>
14 #include <intelblocks/acpi_wake_source.h>
15 #include <intelblocks/acpi.h>
16 #include <intelblocks/lpc_lib.h>
17 #include <intelblocks/pmclib.h>
18 #include <intelblocks/sgx.h>
19 #include <intelblocks/tco.h>
20 #include <intelblocks/uart.h>
22 #include <soc/intel/common/tco.h>
23 #include <soc/iomap.h>
26 #define CPUID_6_EAX_ISST (1 << 7)
28 #define ACPI_SCI_IRQ 9
30 void ioapic_get_sci_pin(u8
*gsi
, u8
*irq
, u8
*flags
)
32 int sci_irq
= ACPI_SCI_IRQ
;
35 scis
= soc_read_sci_irq_select();
37 scis
>>= SCI_IRQ_ADJUST
;
39 /* Determine how SCI is routed. */
44 sci_irq
= scis
- SCIS_IRQ9
+ 9;
50 sci_irq
= scis
- SCIS_IRQ20
+ 20;
53 printk(BIOS_DEBUG
, "Invalid SCI route! Defaulting to IRQ%d.\n", sci_irq
);
58 *irq
= (sci_irq
< 16) ? sci_irq
: ACPI_SCI_IRQ
;
59 *flags
= MP_IRQ_TRIGGER_LEVEL
| soc_madt_sci_irq_polarity(sci_irq
);
61 printk(BIOS_DEBUG
, "SCI is IRQ %d, GSI %d\n", *irq
, *gsi
);
65 static const uintptr_t default_ioapic_bases
[] = { IO_APIC_ADDR
};
67 __weak
size_t soc_get_ioapic_info(const uintptr_t *ioapic_bases
[])
69 *ioapic_bases
= default_ioapic_bases
;
70 return ARRAY_SIZE(default_ioapic_bases
);
73 unsigned long acpi_fill_madt(unsigned long current
)
75 const uintptr_t *ioapic_table
;
76 size_t ioapic_entries
;
79 if (!CONFIG(ACPI_COMMON_MADT_LAPIC
))
80 current
= acpi_create_madt_lapics_with_nmis_hybrid(current
);
83 ioapic_entries
= soc_get_ioapic_info(&ioapic_table
);
85 /* Default SOC IOAPIC entry */
86 ASSERT(ioapic_table
[0] == IO_APIC_ADDR
);
88 for (int i
= 1; i
< ioapic_entries
; i
++)
89 current
+= acpi_create_madt_ioapic_from_hw((void *)current
, ioapic_table
[i
]);
94 void acpi_fill_fadt(acpi_fadt_t
*fadt
)
96 const uint16_t pmbase
= ACPI_BASE_ADDRESS
;
99 fadt
->pm1a_evt_blk
= pmbase
+ PM1_STS
;
100 fadt
->pm1a_cnt_blk
= pmbase
+ PM1_CNT
;
102 fadt
->gpe0_blk
= pmbase
+ GPE0_STS(0);
104 fadt
->pm1_evt_len
= 4;
105 fadt
->pm1_cnt_len
= 2;
107 /* GPE0 STS/EN pairs each 32 bits wide. */
108 fadt
->gpe0_blk_len
= 2 * GPE0_REG_MAX
* sizeof(uint32_t);
111 if (CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_USE_GPE1
)) {
112 fadt
->gpe1_blk
= pmbase
+ GPE1_STS(0);
113 fadt
->gpe1_blk_len
= 2 * GPE1_REG_MAX
* sizeof(uint32_t);
115 * NOTE: gpe1 is after gpe0, which has _STS and _EN register sets.
116 * gpe1_base is the starting bit offset for GPE1.
118 fadt
->gpe1_base
= fadt
->gpe0_blk_len
/ 2 * 8;
121 fill_fadt_extended_pm_io(fadt
);
123 fadt
->flags
|= ACPI_FADT_WBINVD
| ACPI_FADT_C1_SUPPORTED
|
124 ACPI_FADT_SLEEP_BUTTON
|
125 ACPI_FADT_SEALED_CASE
| ACPI_FADT_S4_RTC_WAKE
;
127 if (CONFIG(USE_PM_ACPI_TIMER
))
128 fadt
->flags
|= ACPI_FADT_PLATFORM_CLOCK
;
131 unsigned long southbridge_write_acpi_tables(const struct device
*device
,
132 unsigned long current
,
133 struct acpi_rsdp
*rsdp
)
135 if (CONFIG(SOC_INTEL_COMMON_BLOCK_UART
)) {
136 current
= acpi_write_dbg2_pci_uart(rsdp
, current
,
138 ACPI_ACCESS_SIZE_DWORD_ACCESS
);
141 return acpi_write_hpet(device
, current
, rsdp
);
145 void acpi_fill_soc_wake(uint32_t *pm1_en
, uint32_t *gpe0_en
,
146 const struct chipset_power_state
*ps
)
151 * Save wake source information for calculating ACPI _SWS values
153 * @pm1: PM1_STS register with only enabled events set
154 * @gpe0: GPE0_STS registers with only enabled events set
156 * return the number of registers in the gpe0 array
159 int soc_fill_acpi_wake(const struct chipset_power_state
*ps
, uint32_t *pm1
, uint32_t **gpe0
)
161 static uint32_t gpe0_sts
[GPE0_REG_MAX
];
162 uint32_t gpe0_en
[GPE0_REG_MAX
];
167 * PM1_EN to check the basic wake events which can happen through
168 * powerbtn or any other wake source like lidopen, key board press etc.
171 pm1_en
|= WAK_STS
| PWRBTN_EN
;
173 memcpy(gpe0_en
, ps
->gpe0_en
, sizeof(gpe0_en
));
175 acpi_fill_soc_wake(&pm1_en
, gpe0_en
, ps
);
177 *pm1
= ps
->pm1_sts
& pm1_en
;
179 /* Mask off GPE0 status bits that are not enabled */
180 *gpe0
= &gpe0_sts
[0];
181 for (i
= 0; i
< GPE0_REG_MAX
; i
++)
182 gpe0_sts
[i
] = ps
->gpe0_sts
[i
] & gpe0_en
[i
];
187 int common_calculate_power_ratio(int tdp
, int p1_ratio
, int ratio
)
193 * M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
195 * Power = (ratio / p1_ratio) * m * tdp
198 m
= (110000 - ((p1_ratio
- ratio
) * 625)) / 11;
201 power
= ((ratio
* 100000 / p1_ratio
) / 100);
202 power
*= (m
/ 100) * (tdp
/ 1000);
208 static void generate_c_state_entries(void)
210 const acpi_cstate_t
*c_state_map
;
213 c_state_map
= soc_get_cstate_map(&entries
);
215 /* Generate C-state tables */
216 acpigen_write_CST_package(c_state_map
, entries
);
219 void generate_p_state_entries(int core
, int cores_per_package
)
221 int ratio_min
, ratio_max
, ratio_turbo
, ratio_step
;
222 int coord_type
, power_max
, num_entries
;
223 int ratio
, power
, clock
, clock_max
;
226 coord_type
= cpu_get_coord_type();
227 ratio_min
= cpu_get_min_ratio();
228 ratio_max
= cpu_get_max_ratio();
229 clock_max
= (ratio_max
* cpu_get_bus_clock()) / KHz
;
230 turbo
= (get_turbo_state() == TURBO_ENABLED
);
232 /* Calculate CPU TDP in mW */
233 power_max
= cpu_get_power_max();
235 /* Write _PCT indicating use of FFixedHW */
236 acpigen_write_empty_PCT();
238 /* Write _PPC with no limit on supported P-state */
239 acpigen_write_PPC_NVS();
240 /* Write PSD indicating configured coordination type */
241 acpigen_write_PSD_package(core
, 1, coord_type
);
243 /* Add P-state entries in _PSS table */
244 acpigen_write_name("_PSS");
246 /* Determine ratio points */
247 ratio_step
= PSS_RATIO_STEP
;
249 num_entries
= ((ratio_max
- ratio_min
) / ratio_step
) + 1;
250 if (((ratio_max
- ratio_min
) % ratio_step
) > 0)
254 if (num_entries
> PSS_MAX_ENTRIES
)
256 } while (num_entries
> PSS_MAX_ENTRIES
);
258 /* _PSS package count depends on Turbo */
259 acpigen_write_package(num_entries
);
261 /* P[T] is Turbo state if enabled */
263 ratio_turbo
= cpu_get_max_turbo_ratio();
265 /* Add entry for Turbo ratio */
266 acpigen_write_PSS_package(clock_max
+ 1, /* MHz */
268 PSS_LATENCY_TRANSITION
,/* lat1 */
269 PSS_LATENCY_BUSMASTER
,/* lat2 */
270 ratio_turbo
<< 8, /* control */
271 ratio_turbo
<< 8); /* status */
275 /* First regular entry is max non-turbo ratio */
276 acpigen_write_PSS_package(clock_max
, /* MHz */
278 PSS_LATENCY_TRANSITION
,/* lat1 */
279 PSS_LATENCY_BUSMASTER
,/* lat2 */
280 ratio_max
<< 8, /* control */
281 ratio_max
<< 8); /* status */
284 /* Generate the remaining entries */
285 for (ratio
= ratio_min
+ ((num_entries
- 1) * ratio_step
);
286 ratio
>= ratio_min
; ratio
-= ratio_step
) {
287 /* Calculate power at this ratio */
288 power
= common_calculate_power_ratio(power_max
, ratio_max
, ratio
);
289 clock
= (ratio
* cpu_get_bus_clock()) / KHz
;
291 acpigen_write_PSS_package(clock
, /* MHz */
293 PSS_LATENCY_TRANSITION
,/* lat1 */
294 PSS_LATENCY_BUSMASTER
,/* lat2 */
295 ratio
<< 8, /* control */
296 ratio
<< 8); /* status */
298 /* Fix package length */
302 __weak acpi_tstate_t
*soc_get_tss_table(int *entries
)
308 void generate_t_state_entries(int core
, int cores_per_package
)
310 acpi_tstate_t
*soc_tss_table
;
313 soc_tss_table
= soc_get_tss_table(&entries
);
317 /* Indicate SW_ALL coordination for T-states */
318 acpigen_write_TSD_package(core
, cores_per_package
, SW_ALL
);
320 /* Indicate FixedHW so OS will use MSR */
321 acpigen_write_empty_PTC();
323 /* Set NVS controlled T-state limit */
324 acpigen_write_TPC("\\TLVL");
326 /* Write TSS table for MSR access */
327 acpigen_write_TSS_package(entries
, soc_tss_table
);
330 static void generate_cppc_entries(int core_id
)
332 u32 version
= CPPC_VERSION_2
;
334 if (CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID
))
335 version
= CPPC_VERSION_3
;
337 if (!(CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPPC
) &&
338 cpuid_eax(6) & CPUID_6_EAX_ISST
))
341 /* Generate GCPC package in first logical core */
343 struct cppc_config cppc_config
;
344 cpu_init_cppc_config(&cppc_config
, version
);
345 acpigen_write_CPPC_package(&cppc_config
);
348 /* Write _CPC entry for each logical core */
349 if (CONFIG(SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID
))
350 acpigen_write_CPPC_hybrid_method(core_id
);
352 acpigen_write_CPPC_method();
355 __weak
void soc_power_states_generation(int core_id
,
356 int cores_per_package
)
360 static void generate_cpu_entry(int cpu
, int core
, int cores_per_package
)
362 /* Generate processor \_SB.CPUx */
363 acpigen_write_processor_device(cpu
* cores_per_package
+ core
);
365 /* Generate C-state tables */
366 generate_c_state_entries();
368 generate_cppc_entries(core
);
370 /* Soc specific power states generation */
371 soc_power_states_generation(core
, cores_per_package
);
373 acpigen_write_processor_device_end();
376 void generate_cpu_entries(const struct device
*device
)
379 int totalcores
= dev_count_cpu();
380 unsigned int num_virt
;
381 unsigned int num_phys
;
383 cpu_read_topology(&num_phys
, &num_virt
);
385 int numcpus
= totalcores
/ num_virt
;
387 printk(BIOS_DEBUG
, "Found %d CPU(s) with %d/%d physical/logical core(s) each.\n",
388 numcpus
, num_phys
, num_virt
);
390 for (cpu_id
= 0; cpu_id
< numcpus
; cpu_id
++)
391 for (core_id
= 0; core_id
< num_virt
; core_id
++)
392 generate_cpu_entry(cpu_id
, core_id
, num_virt
);
394 /* PPKG is usually used for thermal management
395 of the first and only package. */
396 acpigen_write_processor_package("PPKG", 0, num_virt
);
398 /* Add a method to notify processor nodes */
399 acpigen_write_processor_cnot(num_virt
);
401 if (CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_ENABLE
))
406 static bool fill_wdat_timeout_entry(acpi_wdat_entry_t
*entry
)
408 uint16_t tcobase
= tco_get_bar();
413 memset((void *)entry
, 0, sizeof(acpi_wdat_entry_t
));
415 entry
->action
= ACPI_WDAT_SET_COUNTDOWN
;
416 entry
->instruction
= ACPI_WDAT_WRITE_COUNTDOWN
| ACPI_WDAT_PRESERVE_REGISTER
;
417 entry
->mask
= TCO_TMR_MASK
;
418 entry
->register_region
.space_id
= ACPI_ADDRESS_SPACE_IO
;
419 entry
->register_region
.addrl
= tcobase
+ TCO_TMR
;
420 entry
->register_region
.access_size
= ACPI_WDAT_ACCESS_SIZE_WORD
;
425 static bool fill_wdat_boot_status_entry(acpi_wdat_entry_t
*entry
, uint8_t action
,
426 uint8_t instruction
, uint32_t value
)
428 uint16_t tcobase
= tco_get_bar();
433 memset((void *)entry
, 0, sizeof(acpi_wdat_entry_t
));
435 entry
->action
= action
;
436 entry
->instruction
= instruction
;
437 entry
->value
= value
;
438 entry
->mask
= TCO2_STS_SECOND_TO
;
439 entry
->register_region
.space_id
= ACPI_ADDRESS_SPACE_IO
;
440 entry
->register_region
.addrl
= tcobase
+ TCO_MESSAGE1
;
441 entry
->register_region
.access_size
= ACPI_WDAT_ACCESS_SIZE_BYTE
;
446 static bool fill_wdat_run_state_entry(acpi_wdat_entry_t
*entry
, uint8_t action
,
447 uint8_t instruction
, uint32_t value
)
449 uint16_t tcobase
= tco_get_bar();
454 memset((void *)entry
, 0, sizeof(acpi_wdat_entry_t
));
456 entry
->action
= action
;
457 entry
->instruction
= instruction
;
458 entry
->value
= value
;
459 entry
->mask
= TCO1_TMR_HLT
;
460 entry
->register_region
.space_id
= ACPI_ADDRESS_SPACE_IO
;
461 entry
->register_region
.addrl
= tcobase
+ TCO1_CNT
;
462 entry
->register_region
.access_size
= ACPI_WDAT_ACCESS_SIZE_WORD
;
467 static bool fill_wdat_ping_entry(acpi_wdat_entry_t
*entry
)
469 uint16_t tcobase
= tco_get_bar();
474 memset((void *)entry
, 0, sizeof(acpi_wdat_entry_t
));
476 entry
->action
= ACPI_WDAT_RESET
;
477 entry
->instruction
= ACPI_WDAT_WRITE_VALUE
;
480 entry
->register_region
.space_id
= ACPI_ADDRESS_SPACE_IO
;
481 entry
->register_region
.addrl
= tcobase
+ TCO_RLD
;
482 entry
->register_region
.access_size
= ACPI_WDAT_ACCESS_SIZE_WORD
;
487 unsigned long acpi_soc_fill_wdat(acpi_wdat_t
*wdat
, unsigned long current
)
492 uint16_t tcobase
= tco_get_bar();
497 wdat
->pci_segment
= 0xff;
498 wdat
->pci_bus
= 0xff;
499 wdat
->pci_device
= 0xff;
500 wdat
->pci_function
= 0xff;
502 wdat
->timer_period
= tco_get_timer_period();
503 wdat
->min_count
= tco_get_timer_min_value();
504 wdat
->max_count
= tco_get_timer_max_value();
505 wdat
->flags
= ACPI_WDAT_FLAG_ENABLED
;
508 acpi_wdat_entry_t
*entry
= (acpi_wdat_entry_t
*)current
;
510 /* Write countdown */
511 if (!fill_wdat_timeout_entry(entry
))
516 /* Get boot status */
517 if (!fill_wdat_boot_status_entry(entry
, ACPI_WDAT_GET_STATUS
,
518 ACPI_WDAT_READ_VALUE
, TCO2_STS_SECOND_TO
))
523 /* Set boot status */
524 if (!fill_wdat_boot_status_entry(entry
, ACPI_WDAT_SET_STATUS
,
525 ACPI_WDAT_WRITE_VALUE
| ACPI_WDAT_PRESERVE_REGISTER
,
531 /* Get running status */
532 if (!fill_wdat_run_state_entry(entry
, ACPI_WDAT_GET_RUNNING_STATE
,
533 ACPI_WDAT_READ_VALUE
, 0))
538 /* Start the watchdog */
539 if (!fill_wdat_run_state_entry(entry
, ACPI_WDAT_SET_RUNNING_STATE
,
540 ACPI_WDAT_WRITE_VALUE
| ACPI_WDAT_PRESERVE_REGISTER
,
546 /* Get stopped status */
547 if (!fill_wdat_run_state_entry(entry
, ACPI_WDAT_GET_STOPPED_STATE
,
548 ACPI_WDAT_READ_VALUE
, TCO1_TMR_HLT
))
553 /* Stop the watchdog */
554 if (!fill_wdat_run_state_entry(entry
, ACPI_WDAT_SET_STOPPED_STATE
,
555 ACPI_WDAT_WRITE_VALUE
| ACPI_WDAT_PRESERVE_REGISTER
,
562 if (!fill_wdat_ping_entry(entry
))
567 wdat
->entries
= ((unsigned long)entry
- current
) / sizeof(acpi_wdat_entry_t
);
569 return (unsigned long)entry
;
572 wdat
->flags
= ACPI_WDAT_FLAG_DISABLED
;
573 printk(BIOS_ERR
, "Fail to populate WDAT ACPI Table");