Angel Pons | ae59387 | 2020-04-04 18:50:57 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Chris Ching | 044dfe9 | 2018-01-03 16:26:36 -0700 | [diff] [blame] | 2 | |
Furquan Shaikh | 76cedd2 | 2020-05-02 10:24:23 -0700 | [diff] [blame] | 3 | #include <acpi/acpi.h> |
Kyösti Mälkki | b0db813 | 2021-01-21 16:34:43 +0200 | [diff] [blame] | 4 | #include <acpi/acpi_pm.h> |
Karthikeyan Ramasubramanian | 589ac69 | 2021-07-15 14:58:23 -0600 | [diff] [blame] | 5 | #include <amdblocks/acpimmio.h> |
| 6 | #include <amdblocks/acpi.h> |
Bill XIE | 516c0a5 | 2020-02-24 23:08:35 +0800 | [diff] [blame] | 7 | #include <bootmode.h> |
Bill XIE | 516c0a5 | 2020-02-24 23:08:35 +0800 | [diff] [blame] | 8 | #include <console/console.h> |
Chris Ching | 044dfe9 | 2018-01-03 16:26:36 -0700 | [diff] [blame] | 9 | #include <halt.h> |
Marshall Dawson | 4ee83b2 | 2019-05-03 11:44:22 -0600 | [diff] [blame] | 10 | #include <security/vboot/vboot_common.h> |
Bill XIE | 516c0a5 | 2020-02-24 23:08:35 +0800 | [diff] [blame] | 11 | #include <soc/southbridge.h> |
Chris Ching | 044dfe9 | 2018-01-03 16:26:36 -0700 | [diff] [blame] | 12 | |
| 13 | void poweroff(void) |
| 14 | { |
Richard Spiegel | e24d795 | 2018-10-26 13:25:01 -0700 | [diff] [blame] | 15 | acpi_write32(MMIO_ACPI_PM1_CNT_BLK, |
| 16 | (SLP_TYP_S5 << SLP_TYP_SHIFT) | SLP_EN); |
Raul E Rangel | 06bc4d7 | 2018-05-25 16:11:39 -0600 | [diff] [blame] | 17 | |
| 18 | /* |
| 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. |
| 22 | */ |
| 23 | if (!ENV_SMM) |
| 24 | halt(); |
Chris Ching | 044dfe9 | 2018-01-03 16:26:36 -0700 | [diff] [blame] | 25 | } |
Marshall Dawson | 4ee83b2 | 2019-05-03 11:44:22 -0600 | [diff] [blame] | 26 | |
Marshall Dawson | 4ee83b2 | 2019-05-03 11:44:22 -0600 | [diff] [blame] | 27 | static void print_num_status_bits(int num_bits, uint32_t status, |
| 28 | const char *const bit_names[]) |
| 29 | { |
| 30 | int i; |
| 31 | |
| 32 | if (!status) |
| 33 | return; |
| 34 | |
| 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); |
| 41 | } |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | static uint16_t print_pm1_status(uint16_t pm1_sts) |
| 46 | { |
| 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", |
| 55 | }; |
| 56 | |
| 57 | if (!pm1_sts) |
| 58 | return 0; |
| 59 | |
| 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"); |
| 63 | |
| 64 | return pm1_sts; |
| 65 | } |
| 66 | |
Aaron Durbin | 746e598 | 2020-08-14 14:48:45 -0600 | [diff] [blame] | 67 | void acpi_fill_pm_gpe_state(struct acpi_pm_gpe_state *state) |
| 68 | { |
| 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; |
| 75 | } |
| 76 | |
Kyösti Mälkki | b0db813 | 2021-01-21 16:34:43 +0200 | [diff] [blame] | 77 | void acpi_pm_gpe_add_events_print_events(void) |
Aaron Durbin | 746e598 | 2020-08-14 14:48:45 -0600 | [diff] [blame] | 78 | { |
Kyösti Mälkki | b0db813 | 2021-01-21 16:34:43 +0200 | [diff] [blame] | 79 | const struct chipset_power_state *ps; |
| 80 | const struct acpi_pm_gpe_state *state; |
| 81 | |
Fabio Aiuto | fdcf698 | 2022-09-11 12:25:13 +0200 | [diff] [blame] | 82 | if (acpi_fetch_pm_state(&ps, PS_CLAIMER_ELOG) < 0) |
Kyösti Mälkki | b0db813 | 2021-01-21 16:34:43 +0200 | [diff] [blame] | 83 | return; |
| 84 | |
| 85 | state = &ps->gpe_state; |
Aaron Durbin | 746e598 | 2020-08-14 14:48:45 -0600 | [diff] [blame] | 86 | print_pm1_status(state->pm1_sts); |
Karthikeyan Ramasubramanian | 589ac69 | 2021-07-15 14:58:23 -0600 | [diff] [blame] | 87 | acpi_log_events(ps); |
Aaron Durbin | 746e598 | 2020-08-14 14:48:45 -0600 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | void acpi_clear_pm_gpe_status(void) |
| 91 | { |
| 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)); |
| 94 | } |
| 95 | |
Marshall Dawson | 26307c7 | 2019-05-03 13:06:55 -0600 | [diff] [blame] | 96 | int acpi_get_sleep_type(void) |
| 97 | { |
| 98 | return acpi_sleep_from_pm1(acpi_read16(MMIO_ACPI_PM1_CNT_BLK)); |
| 99 | } |
| 100 | |
Bill XIE | 516c0a5 | 2020-02-24 23:08:35 +0800 | [diff] [blame] | 101 | int platform_is_resuming(void) |
Marshall Dawson | 4ee83b2 | 2019-05-03 11:44:22 -0600 | [diff] [blame] | 102 | { |
| 103 | if (!(acpi_read16(MMIO_ACPI_PM1_STS) & WAK_STS)) |
| 104 | return 0; |
| 105 | |
Marshall Dawson | 26307c7 | 2019-05-03 13:06:55 -0600 | [diff] [blame] | 106 | return acpi_get_sleep_type() == ACPI_S3; |
Marshall Dawson | 4ee83b2 | 2019-05-03 11:44:22 -0600 | [diff] [blame] | 107 | } |
| 108 | |
| 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) |
| 112 | { |
| 113 | uint16_t pm1; |
| 114 | |
| 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); |
| 119 | } |
| 120 | |
| 121 | void vboot_platform_prepare_reboot(void) |
| 122 | { |
| 123 | set_pm1cnt_s5(); |
| 124 | } |
| 125 | |
| 126 | void acpi_enable_sci(void) |
| 127 | { |
| 128 | uint32_t pm1; |
| 129 | |
| 130 | pm1 = acpi_read32(MMIO_ACPI_PM1_CNT_BLK); |
| 131 | pm1 |= ACPI_PM1_CNT_SCIEN; |
| 132 | acpi_write32(MMIO_ACPI_PM1_CNT_BLK, pm1); |
| 133 | } |
| 134 | |
| 135 | void acpi_disable_sci(void) |
| 136 | { |
| 137 | uint32_t pm1; |
| 138 | |
| 139 | pm1 = acpi_read32(MMIO_ACPI_PM1_CNT_BLK); |
| 140 | pm1 &= ~ACPI_PM1_CNT_SCIEN; |
| 141 | acpi_write32(MMIO_ACPI_PM1_CNT_BLK, pm1); |
| 142 | } |