blob: 14943d66c4adecf88a1c73a267c45094525de547 [file] [log] [blame]
Felix Heldee2a3652021-02-09 23:43:17 +01001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
Felix Heldbe35a3a2021-02-10 16:34:31 +01003#include <acpi/acpi.h>
4#include <amdblocks/acpi.h>
5#include <amdblocks/acpimmio.h>
Felix Heldd51fd302021-02-11 05:02:27 +01006#include <amdblocks/psp.h>
Felix Heldbe35a3a2021-02-10 16:34:31 +01007#include <amdblocks/smi.h>
Felix Helda3a66b62021-02-10 03:29:48 +01008#include <amdblocks/smm.h>
Felix Heldbe35a3a2021-02-10 16:34:31 +01009#include <arch/hlt.h>
10#include <arch/io.h>
11#include <console/console.h>
Felix Held913dcf62021-03-03 19:03:37 +010012#include <cpu/x86/cache.h>
Felix Held3c4fd702021-02-10 03:47:38 +010013#include <cpu/x86/smm.h>
Felix Heldbe35a3a2021-02-10 16:34:31 +010014#include <soc/smi.h>
Felix Held913dcf62021-03-03 19:03:37 +010015#include <soc/smu.h>
16#include <soc/southbridge.h>
Felix Heldbe35a3a2021-02-10 16:34:31 +010017#include <types.h>
18
19static void fch_apmc_smi_handler(void)
20{
21 const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
22
23 switch (cmd) {
24 case APM_CNT_ACPI_ENABLE:
25 acpi_enable_sci();
26 break;
27 case APM_CNT_ACPI_DISABLE:
28 acpi_disable_sci();
Felix Heldd51fd302021-02-11 05:02:27 +010029 break;
30 case APM_CNT_SMMINFO:
31 psp_notify_smm();
32 break;
Felix Heldbe35a3a2021-02-10 16:34:31 +010033 }
34
35 mainboard_smi_apmc(cmd);
36}
37
38static void fch_slp_typ_handler(void)
39{
Felix Held913dcf62021-03-03 19:03:37 +010040 uint32_t pci_ctrl;
Felix Heldbe35a3a2021-02-10 16:34:31 +010041 uint16_t pm1cnt;
Felix Held913dcf62021-03-03 19:03:37 +010042 uint8_t slp_typ, rst_ctrl;
Felix Heldbe35a3a2021-02-10 16:34:31 +010043
44 /* Figure out SLP_TYP */
45 pm1cnt = acpi_read16(MMIO_ACPI_PM1_CNT_BLK);
46 printk(BIOS_SPEW, "SMI#: SLP = 0x%04x\n", pm1cnt);
47 slp_typ = acpi_sleep_from_pm1(pm1cnt);
48
49 /* Do any mainboard sleep handling */
50 mainboard_smi_sleep(slp_typ);
51
52 switch (slp_typ) {
53 case ACPI_S0:
54 printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
55 break;
56 case ACPI_S3:
57 printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
58 break;
59 case ACPI_S4:
60 printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
61 break;
62 case ACPI_S5:
63 printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
64 break;
65 default:
66 printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
67 break;
68 }
69
70 if (slp_typ >= ACPI_S3) {
Felix Held913dcf62021-03-03 19:03:37 +010071 wbinvd();
72
73 clear_all_smi_status();
74
75 /* Do not send SMI before AcpiPm1CntBlkx00[SlpTyp] */
76 pci_ctrl = pm_read32(PM_PCI_CTRL);
77 pci_ctrl &= ~FORCE_SLPSTATE_RETRY;
78 pm_write32(PM_PCI_CTRL, pci_ctrl);
79
80 /* Enable SlpTyp */
81 rst_ctrl = pm_read8(PM_RST_CTRL1);
82 rst_ctrl |= SLPTYPE_CONTROL_EN;
83 pm_write8(PM_RST_CTRL1, rst_ctrl);
84
85 if (slp_typ == ACPI_S3)
86 psp_notify_sx_info(ACPI_S3);
87
88 smu_sx_entry(); /* Leave SlpTypeEn clear, SMU will set */
Felix Heldbe35a3a2021-02-10 16:34:31 +010089 printk(BIOS_ERR, "Error: System did not go to sleep\n");
90 hlt();
91 }
92}
Felix Held3c4fd702021-02-10 03:47:38 +010093
94int southbridge_io_trap_handler(int smif)
95{
96 return 0;
97}
Felix Heldee2a3652021-02-09 23:43:17 +010098
Felix Heldbe35a3a2021-02-10 16:34:31 +010099/*
100 * Table of functions supported in the SMI handler. Note that SMI source setup
101 * in fch.c is unrelated to this list.
102 */
103static const struct smi_sources_t smi_sources[] = {
104 { .type = SMITYPE_SMI_CMD_PORT, .handler = fch_apmc_smi_handler },
105 { .type = SMITYPE_SLP_TYP, .handler = fch_slp_typ_handler},
106};
107
Felix Helda3a66b62021-02-10 03:29:48 +0100108void *get_smi_source_handler(int source)
Felix Heldee2a3652021-02-09 23:43:17 +0100109{
Felix Heldbe35a3a2021-02-10 16:34:31 +0100110 size_t i;
111
112 for (i = 0 ; i < ARRAY_SIZE(smi_sources) ; i++)
113 if (smi_sources[i].type == source)
114 return smi_sources[i].handler;
115
Felix Helda3a66b62021-02-10 03:29:48 +0100116 return NULL;
Felix Heldee2a3652021-02-09 23:43:17 +0100117}