blob: a8521c5bdae5c0f3334d990ec5e049689c3b1466 [file] [log] [blame]
Felix Held4a8cd722020-04-18 22:26:39 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Marc Jones24484842017-05-04 21:17:45 -06002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi.h>
Marshall Dawson4ee83b22019-05-03 11:44:22 -06004#include <amdblocks/acpi.h>
Felix Helde4a7e462021-03-09 16:42:17 +01005#include <amdblocks/acpimmio.h>
Felix Helda5a52952020-12-01 18:14:01 +01006#include <amdblocks/smi.h>
Felix Helda3a66b62021-02-10 03:29:48 +01007#include <amdblocks/smm.h>
Felix Helde4a7e462021-03-09 16:42:17 +01008#include <arch/hlt.h>
9#include <arch/io.h>
10#include <console/console.h>
11#include <cpu/x86/cache.h>
12#include <cpu/x86/smm.h>
John E. Kabat Jr7057a272017-10-16 20:23:00 -060013#include <elog.h>
Felix Helde4a7e462021-03-09 16:42:17 +010014#include <soc/smi.h>
15#include <soc/southbridge.h>
Felix Held2e978972021-02-10 16:48:23 +010016#include <types.h>
John E. Kabat Jr7057a272017-10-16 20:23:00 -060017
Fred Reitbergerf73a3a52022-10-14 14:04:04 -040018/*
19 * stoneyridge does not implement the APM_CNT_SMMINFO handler,
20 * so it needs a special version
21 */
22static void stoneyridge_fch_apmc_smi_handler(void)
Marc Jones24484842017-05-04 21:17:45 -060023{
Marshall Dawson66e62da2017-09-27 13:32:38 -060024 const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
Marc Jones24484842017-05-04 21:17:45 -060025
26 switch (cmd) {
Marshall Dawsone9b862e2017-09-22 15:14:46 -060027 case APM_CNT_ACPI_ENABLE:
Raul E Rangelc7ab9f42021-12-06 10:53:54 -070028 acpi_clear_pm_gpe_status();
Marshall Dawson4ee83b22019-05-03 11:44:22 -060029 acpi_enable_sci();
Marc Jones24484842017-05-04 21:17:45 -060030 break;
Marshall Dawsone9b862e2017-09-22 15:14:46 -060031 case APM_CNT_ACPI_DISABLE:
Marshall Dawson4ee83b22019-05-03 11:44:22 -060032 acpi_disable_sci();
Marc Jones24484842017-05-04 21:17:45 -060033 break;
Patrick Georgid61839c2018-12-03 16:10:33 +010034 case APM_CNT_ELOG_GSMI:
Julius Wernercd49cce2019-03-05 16:53:33 -080035 if (CONFIG(ELOG_GSMI))
Felix Held90bcdb42021-03-08 23:54:18 +010036 handle_smi_gsmi();
John E. Kabat Jr7057a272017-10-16 20:23:00 -060037 break;
Matt DeVillier9cc16032020-01-19 00:17:29 -060038 case APM_CNT_SMMSTORE:
39 if (CONFIG(SMMSTORE))
Felix Held90bcdb42021-03-08 23:54:18 +010040 handle_smi_store();
Matt DeVillier9cc16032020-01-19 00:17:29 -060041 break;
Marc Jones24484842017-05-04 21:17:45 -060042 }
43
44 mainboard_smi_apmc(cmd);
45}
46
Felix Helda2db88e2021-02-10 16:46:11 +010047static void fch_slp_typ_handler(void)
Marshall Dawson081851a2017-10-02 14:03:57 -060048{
Marshall Dawsone1b1ec72018-10-07 21:45:47 -060049 uint32_t pci_ctrl, reg32;
50 uint16_t pm1cnt, reg16;
Marshall Dawson081851a2017-10-02 14:03:57 -060051 uint8_t slp_typ, rst_ctrl;
52
53 /* Figure out SLP_TYP */
Richard Spiegele24d7952018-10-26 13:25:01 -070054 pm1cnt = acpi_read16(MMIO_ACPI_PM1_CNT_BLK);
Marshall Dawsone1b1ec72018-10-07 21:45:47 -060055 printk(BIOS_SPEW, "SMI#: SLP = 0x%04x\n", pm1cnt);
Marshall Dawson081851a2017-10-02 14:03:57 -060056 slp_typ = acpi_sleep_from_pm1(pm1cnt);
57
58 /* Do any mainboard sleep handling */
59 mainboard_smi_sleep(slp_typ);
60
61 switch (slp_typ) {
62 case ACPI_S0:
63 printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
64 break;
65 case ACPI_S3:
66 printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
67 break;
68 case ACPI_S4:
69 printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
70 break;
71 case ACPI_S5:
72 printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
73 break;
74 default:
75 printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
76 break;
77 }
78
79 if (slp_typ >= ACPI_S3) {
John E. Kabat Jr7057a272017-10-16 20:23:00 -060080 /* Sleep Type Elog S3, S4, and S5 entry */
Kyösti Mälkki9dd1a122019-11-06 11:04:27 +020081 elog_gsmi_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);
John E. Kabat Jr7057a272017-10-16 20:23:00 -060082
Marshall Dawson081851a2017-10-02 14:03:57 -060083 wbinvd();
84
Felix Held4f69ab72021-02-10 01:26:07 +010085 clear_all_smi_status();
Marshall Dawson081851a2017-10-02 14:03:57 -060086
87 /* Do not send SMI before AcpiPm1CntBlkx00[SlpTyp] */
88 pci_ctrl = pm_read32(PM_PCI_CTRL);
89 pci_ctrl &= ~FORCE_SLPSTATE_RETRY;
90 pci_ctrl |= FORCE_STPCLK_RETRY;
91 pm_write32(PM_PCI_CTRL, pci_ctrl);
92
93 /* Enable SlpTyp */
94 rst_ctrl = pm_read8(PM_RST_CTRL1);
95 rst_ctrl |= SLPTYPE_CONTROL_EN;
96 pm_write8(PM_RST_CTRL1, rst_ctrl);
97
Richard Spiegelb74e3992018-08-20 13:52:44 -070098 /*
99 * Before the final command, check if there's pending wake
100 * event. Read enable first, so that reading the actual status
101 * is as close as possible to entering S3. The idea is to
102 * minimize the opportunity for a wake event to happen before
103 * actually entering S3. If there's a pending wake event, log
104 * it and continue normal path. S3 will fail and the wake event
105 * becomes a SCI.
106 */
Julius Wernercd49cce2019-03-05 16:53:33 -0800107 if (CONFIG(ELOG_GSMI)) {
Richard Spiegele24d7952018-10-26 13:25:01 -0700108 reg16 = acpi_read16(MMIO_ACPI_PM1_EN);
109 reg16 &= acpi_read16(MMIO_ACPI_PM1_STS);
Richard Spiegelb74e3992018-08-20 13:52:44 -0700110 if (reg16)
111 elog_add_extended_event(
112 ELOG_SLEEP_PENDING_PM1_WAKE,
113 (u32)reg16);
114
Richard Spiegele24d7952018-10-26 13:25:01 -0700115 reg32 = acpi_read32(MMIO_ACPI_GPE0_EN);
116 reg32 &= acpi_read32(MMIO_ACPI_GPE0_STS);
Richard Spiegelb74e3992018-08-20 13:52:44 -0700117 if (reg32)
118 elog_add_extended_event(
119 ELOG_SLEEP_PENDING_GPE0_WAKE,
120 reg32);
Julius Wernercd49cce2019-03-05 16:53:33 -0800121 } /* if (CONFIG(ELOG_GSMI)) */
Richard Spiegelb74e3992018-08-20 13:52:44 -0700122
Richard Spiegele24d7952018-10-26 13:25:01 -0700123 /*
124 * An IO cycle is required to trigger the STPCLK/STPGNT
125 * handshake when the Pm1 write is reissued.
126 */
Marshall Dawson19cae7c2019-05-03 13:06:55 -0600127 outw(pm1cnt | SLP_EN, pm_read16(PM1_CNT_BLK));
Marshall Dawson081851a2017-10-02 14:03:57 -0600128 hlt();
129 }
130}
131
Marshall Dawson36a23562017-09-28 17:21:09 -0600132/*
133 * Table of functions supported in the SMI handler. Note that SMI source setup
134 * in southbridge.c is unrelated to this list.
135 */
Daniel Kurtz963419a2018-04-17 17:45:01 -0600136static const struct smi_sources_t smi_sources[] = {
Fred Reitbergerf73a3a52022-10-14 14:04:04 -0400137 { .type = SMITYPE_SMI_CMD_PORT, .handler = stoneyridge_fch_apmc_smi_handler },
Felix Helda2db88e2021-02-10 16:46:11 +0100138 { .type = SMITYPE_SLP_TYP, .handler = fch_slp_typ_handler},
Marshall Dawson36a23562017-09-28 17:21:09 -0600139};
140
Felix Helda3a66b62021-02-10 03:29:48 +0100141void *get_smi_source_handler(int source)
Marc Jones24484842017-05-04 21:17:45 -0600142{
Felix Held2e978972021-02-10 16:48:23 +0100143 size_t i;
Marc Jones24484842017-05-04 21:17:45 -0600144
Marshall Dawson36a23562017-09-28 17:21:09 -0600145 for (i = 0 ; i < ARRAY_SIZE(smi_sources) ; i++)
146 if (smi_sources[i].type == source)
147 return smi_sources[i].handler;
148
149 return NULL;
150}