mb/google/nissa/var/rull: Configure Acoustic noise mitigation
[coreboot2.git] / src / soc / amd / common / block / acpi / acpi.c
blob75d4adf8114e18853711e380e63f4424b006664c
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi.h>
4 #include <acpi/acpi_pm.h>
5 #include <amdblocks/acpimmio.h>
6 #include <amdblocks/acpi.h>
7 #include <bootmode.h>
8 #include <console/console.h>
9 #include <halt.h>
10 #include <security/vboot/vboot_common.h>
11 #include <soc/southbridge.h>
13 void poweroff(void)
15 acpi_write32(MMIO_ACPI_PM1_CNT_BLK,
16 (SLP_TYP_S5 << SLP_TYP_SHIFT) | SLP_EN);
19 * Setting SLP_TYP_S5 in PM1 triggers SLP_SMI, which is handled by SMM
20 * to transition to S5 state. If halt is called in SMM, then it prevents
21 * the SMI handler from being triggered and system never enters S5.
23 if (!ENV_SMM)
24 halt();
27 static void print_num_status_bits(int num_bits, uint32_t status,
28 const char *const bit_names[])
30 int i;
32 if (!status)
33 return;
35 for (i = num_bits - 1; i >= 0; i--) {
36 if (status & (1 << i)) {
37 if (bit_names[i])
38 printk(BIOS_DEBUG, "%s ", bit_names[i]);
39 else
40 printk(BIOS_DEBUG, "BIT%d ", i);
45 static uint16_t print_pm1_status(uint16_t pm1_sts)
47 static const char *const pm1_sts_bits[16] = {
48 [0] = "TMROF",
49 [4] = "BMSTATUS",
50 [5] = "GBL",
51 [8] = "PWRBTN",
52 [10] = "RTC",
53 [14] = "PCIEXPWAK",
54 [15] = "WAK",
57 if (!pm1_sts)
58 return 0;
60 printk(BIOS_DEBUG, "PM1_STS: ");
61 print_num_status_bits(ARRAY_SIZE(pm1_sts_bits), pm1_sts, pm1_sts_bits);
62 printk(BIOS_DEBUG, "\n");
64 return pm1_sts;
67 void acpi_fill_pm_gpe_state(struct acpi_pm_gpe_state *state)
69 state->pm1_sts = acpi_read16(MMIO_ACPI_PM1_STS);
70 state->pm1_en = acpi_read16(MMIO_ACPI_PM1_EN);
71 state->gpe0_sts = acpi_read32(MMIO_ACPI_GPE0_STS);
72 state->gpe0_en = acpi_read32(MMIO_ACPI_GPE0_EN);
73 state->previous_sx_state = acpi_get_sleep_type();
74 state->aligning_field = 0;
77 void acpi_pm_gpe_add_events_print_events(void)
79 const struct chipset_power_state *ps;
80 const struct acpi_pm_gpe_state *state;
82 if (acpi_fetch_pm_state(&ps, PS_CLAIMER_ELOG) < 0)
83 return;
85 state = &ps->gpe_state;
86 print_pm1_status(state->pm1_sts);
87 acpi_log_events(ps);
90 void acpi_clear_pm_gpe_status(void)
92 acpi_write16(MMIO_ACPI_PM1_STS, acpi_read16(MMIO_ACPI_PM1_STS));
93 acpi_write32(MMIO_ACPI_GPE0_STS, acpi_read32(MMIO_ACPI_GPE0_STS));
96 int acpi_get_sleep_type(void)
98 return acpi_sleep_from_pm1(acpi_read16(MMIO_ACPI_PM1_CNT_BLK));
101 int platform_is_resuming(void)
103 if (!(acpi_read16(MMIO_ACPI_PM1_STS) & WAK_STS))
104 return 0;
106 return acpi_get_sleep_type() == ACPI_S3;
109 /* If a system reset is about to be requested, modify the PM1 register so it
110 * will never be misinterpreted as an S3 resume. */
111 void set_pm1cnt_s5(void)
113 uint16_t pm1;
115 pm1 = acpi_read16(MMIO_ACPI_PM1_CNT_BLK);
116 pm1 &= ~SLP_TYP;
117 pm1 |= SLP_TYP_S5 << SLP_TYP_SHIFT;
118 acpi_write16(MMIO_ACPI_PM1_CNT_BLK, pm1);
121 void vboot_platform_prepare_reboot(void)
123 set_pm1cnt_s5();
126 void acpi_enable_sci(void)
128 uint32_t pm1;
130 pm1 = acpi_read32(MMIO_ACPI_PM1_CNT_BLK);
131 pm1 |= ACPI_PM1_CNT_SCIEN;
132 acpi_write32(MMIO_ACPI_PM1_CNT_BLK, pm1);
135 void acpi_disable_sci(void)
137 uint32_t pm1;
139 pm1 = acpi_read32(MMIO_ACPI_PM1_CNT_BLK);
140 pm1 &= ~ACPI_PM1_CNT_SCIEN;
141 acpi_write32(MMIO_ACPI_PM1_CNT_BLK, pm1);