summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Dawson <marshalldawson3rd@gmail.com>2017-10-02 14:03:57 -0600
committerMartin Roth <martinroth@google.com>2017-11-17 17:40:16 +0000
commit081851a9e470cb0236650fd0de33b2f5b0384a32 (patch)
tree5de508304cc7aa043e923c7a6968c14ed39c421a
parent918c8717b2ce70065750119bc26678476d661154 (diff)
downloadcoreboot-081851a9e470cb0236650fd0de33b2f5b0384a32.tar.xz
amd/stoneyridge: Add SlpTyp SMI handler
When an SMI occurs due to SlpType, interpret the type of request being made. If it's S3 or higher, flush the cache and disable further SMIs. Reenable SlpTyp functionality in the ACPI logic and reissue the cycle. BUG=b:65595850 Change-Id: I88d413cdbfc2daf44e8d1142c6532f7034795ead Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com> Reviewed-on: https://review.coreboot.org/21751 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/soc/amd/stoneyridge/smihandler.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/soc/amd/stoneyridge/smihandler.c b/src/soc/amd/stoneyridge/smihandler.c
index f9bd8d736b..a0748fe2fc 100644
--- a/src/soc/amd/stoneyridge/smihandler.c
+++ b/src/soc/amd/stoneyridge/smihandler.c
@@ -17,7 +17,11 @@
#include <console/console.h>
#include <cpu/x86/smm.h>
+#include <cpu/x86/cache.h>
+#include <arch/acpi.h>
+#include <arch/hlt.h>
#include <delay.h>
+#include <device/pci_def.h>
#include <soc/smi.h>
#include <soc/southbridge.h>
@@ -42,6 +46,69 @@ static void sb_apmc_smi_handler(void)
mainboard_smi_apmc(cmd);
}
+static void disable_all_smi_status(void)
+{
+ smi_write32(smi_read32(SMI_SCI_STATUS), SMI_SCI_STATUS);
+ smi_write32(smi_read32(SMI_REG_SMISTS0), SMI_REG_SMISTS0);
+ smi_write32(smi_read32(SMI_REG_SMISTS1), SMI_REG_SMISTS1);
+ smi_write32(smi_read32(SMI_REG_SMISTS2), SMI_REG_SMISTS2);
+ smi_write32(smi_read32(SMI_REG_SMISTS3), SMI_REG_SMISTS3);
+ smi_write32(smi_read32(SMI_REG_SMISTS4), SMI_REG_SMISTS4);
+}
+
+static void sb_slp_typ_handler(void)
+{
+ uint32_t pm1cnt, pci_ctrl;
+ uint8_t slp_typ, rst_ctrl;
+
+ /* Figure out SLP_TYP */
+ pm1cnt = inl(pm_acpi_pm_cnt_blk());
+ printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", pm1cnt);
+ slp_typ = acpi_sleep_from_pm1(pm1cnt);
+
+ /* Do any mainboard sleep handling */
+ mainboard_smi_sleep(slp_typ);
+
+ switch (slp_typ) {
+ case ACPI_S0:
+ printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
+ break;
+ case ACPI_S3:
+ printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
+ break;
+ case ACPI_S4:
+ printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
+ break;
+ case ACPI_S5:
+ printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
+ break;
+ default:
+ printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
+ break;
+ }
+
+ if (slp_typ >= ACPI_S3) {
+ wbinvd();
+
+ disable_all_smi_status();
+
+ /* Do not send SMI before AcpiPm1CntBlkx00[SlpTyp] */
+ pci_ctrl = pm_read32(PM_PCI_CTRL);
+ pci_ctrl &= ~FORCE_SLPSTATE_RETRY;
+ pci_ctrl |= FORCE_STPCLK_RETRY;
+ pm_write32(PM_PCI_CTRL, pci_ctrl);
+
+ /* Enable SlpTyp */
+ rst_ctrl = pm_read8(PM_RST_CTRL1);
+ rst_ctrl |= SLPTYPE_CONTROL_EN;
+ pm_write8(PM_RST_CTRL1, rst_ctrl);
+
+ /* Reissue Pm1 write */
+ outl(pm1cnt | SLP_EN, pm_acpi_pm_cnt_blk());
+ hlt();
+ }
+}
+
int southbridge_io_trap_handler(int smif)
{
return 0;
@@ -53,6 +120,7 @@ int southbridge_io_trap_handler(int smif)
*/
struct smi_sources_t smi_sources[] = {
{ .type = SMITYPE_SMI_CMD_PORT, .handler = sb_apmc_smi_handler },
+ { .type = SMITYPE_SLP_TYP, .handler = sb_slp_typ_handler},
};
static void process_smi_sci(void)