blob: 3f3c53fa74b2a384d2207dfcbd449c43b5655f0b [file] [log] [blame]
Angel Ponsc3f58f62020-04-05 15:46:41 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin7837be62013-10-21 22:32:00 -05002
Aaron Durbin7837be62013-10-21 22:32:00 -05003#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Angel Ponsc5bcd282020-07-07 18:16:35 +02005#include <console/console.h>
Aaron Durbin7837be62013-10-21 22:32:00 -05006#include <cpu/x86/smm.h>
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +03007#include <cpu/intel/smm_reloc.h>
Angel Ponsc5bcd282020-07-07 18:16:35 +02008#include <device/device.h>
9#include <device/pci.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070010#include <soc/iomap.h>
Angel Ponsb5320b22020-07-07 18:27:30 +020011#include <soc/pm.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070012#include <soc/smm.h>
Aaron Durbin7837be62013-10-21 22:32:00 -050013
Kein Yuan35110232014-02-22 12:26:55 -080014/* Save settings which will be committed in SMI functions. */
15static uint32_t smm_save_params[SMM_SAVE_PARAM_COUNT];
Aaron Durbin59a4cd52013-11-11 12:09:28 -060016
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030017void smm_southcluster_save_param(int param, uint32_t data)
Aaron Durbin59a4cd52013-11-11 12:09:28 -060018{
Kein Yuan35110232014-02-22 12:26:55 -080019 smm_save_params[param] = data;
Aaron Durbin59a4cd52013-11-11 12:09:28 -060020}
21
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030022void smm_southbridge_clear_state(void)
Aaron Durbin7837be62013-10-21 22:32:00 -050023{
24 uint32_t smi_en;
25
26 /* Log events from chipset before clearing */
Kyösti Mälkki056fbe42019-11-06 12:07:05 +020027 if (CONFIG(ELOG))
28 southcluster_log_state();
Aaron Durbin7837be62013-10-21 22:32:00 -050029
30 printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
31 printk(BIOS_SPEW, " pmbase = 0x%04x\n", get_pmbase());
32
33 smi_en = inl(get_pmbase() + SMI_EN);
34 if (smi_en & APMC_EN) {
35 printk(BIOS_INFO, "SMI# handler already enabled?\n");
36 return;
37 }
38
39 /* Dump and clear status registers */
40 clear_smi_status();
41 clear_pm1_status();
42 clear_tco_status();
43 clear_gpe_status();
Aaron Durbin9f83e872013-11-11 14:45:27 -060044 clear_alt_status();
Aaron Durbin19edc3a2014-01-09 11:17:37 -060045 clear_pmc_status();
Aaron Durbin7837be62013-10-21 22:32:00 -050046}
47
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030048static void smm_southcluster_route_gpios(void)
Aaron Durbin59a4cd52013-11-11 12:09:28 -060049{
Angel Ponse80d17f2020-07-07 17:25:38 +020050 void *gpio_rout = (void *)(PMC_BASE_ADDRESS + GPIO_ROUT);
Aaron Durbin59a4cd52013-11-11 12:09:28 -060051 const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI;
52 uint32_t alt_gpio_reg = 0;
Kein Yuan35110232014-02-22 12:26:55 -080053 uint32_t route_reg = smm_save_params[SMM_SAVE_PARAM_GPIO_ROUTE];
Aaron Durbin59a4cd52013-11-11 12:09:28 -060054 int i;
55
56 printk(BIOS_DEBUG, "GPIO_ROUT = %08x\n", route_reg);
57
58 /* Start the routing for the specific gpios. */
59 write32(gpio_rout, route_reg);
60
61 /* Enable SMIs for the gpios that are set to trigger the SMI. */
62 for (i = 0; i < 16; i++) {
Angel Ponsc5bcd282020-07-07 18:16:35 +020063 if ((route_reg & ROUTE_MASK) == ROUTE_SMI)
Aaron Durbin59a4cd52013-11-11 12:09:28 -060064 alt_gpio_reg |= (1 << i);
Angel Ponsc5bcd282020-07-07 18:16:35 +020065
Aaron Durbin59a4cd52013-11-11 12:09:28 -060066 route_reg >>= 2;
67 }
68 printk(BIOS_DEBUG, "ALT_GPIO_SMI = %08x\n", alt_gpio_reg);
69
70 outl(alt_gpio_reg, alt_gpio_smi);
71}
72
Kyösti Mälkki0778c862020-06-10 12:44:03 +030073static void smm_southbridge_enable(uint16_t pm1_events)
Aaron Durbin7837be62013-10-21 22:32:00 -050074{
Aaron Durbin59a4cd52013-11-11 12:09:28 -060075
Aaron Durbin7837be62013-10-21 22:32:00 -050076 printk(BIOS_DEBUG, "Enabling SMIs.\n");
Kein Yuan35110232014-02-22 12:26:55 -080077 if (!smm_save_params[SMM_SAVE_PARAM_PCIE_WAKE_ENABLE])
78 pm1_events |= PCIEXPWAK_DIS;
Angel Pons26b49cc2020-07-07 17:17:51 +020079
Kein Yuan35110232014-02-22 12:26:55 -080080 enable_pm1(pm1_events);
Aaron Durbin7837be62013-10-21 22:32:00 -050081 disable_gpe(PME_B0_EN);
82
Aaron Durbin59a4cd52013-11-11 12:09:28 -060083 /* Set up the GPIO route. */
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030084 smm_southcluster_route_gpios();
Aaron Durbin59a4cd52013-11-11 12:09:28 -060085
Angel Pons26b49cc2020-07-07 17:17:51 +020086 /*
87 * Enable SMI generation:
Aaron Durbin7837be62013-10-21 22:32:00 -050088 * - on APMC writes (io 0xb2)
89 * - on writes to SLP_EN (sleep states)
90 * - on writes to GBL_RLS (bios commands)
91 * No SMIs:
Aaron Durbin766482d2014-01-09 10:44:06 -060092 * - on TCO events
Aaron Durbin7837be62013-10-21 22:32:00 -050093 * - on microcontroller writes (io 0x62/0x66)
94 */
Aaron Durbin766482d2014-01-09 10:44:06 -060095 enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
Aaron Durbin7837be62013-10-21 22:32:00 -050096}
97
Kyösti Mälkki0778c862020-06-10 12:44:03 +030098void global_smi_enable(void)
99{
100 smm_southbridge_enable(PWRBTN_EN | GBL_EN);
101}