blob: 64e560ed423c8407bad34d3bf918440335ebcd16 [file] [log] [blame]
Angel Ponsba38f372020-04-05 15:46:45 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahy77ff0b12015-05-05 15:07:29 -07002
Lee Leahy77ff0b12015-05-05 15:07:29 -07003#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Lee Leahy32471722015-04-20 15:20:28 -07005#include <console/console.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -07006#include <cpu/x86/smm.h>
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +03007#include <cpu/intel/smm_reloc.h>
Lee Leahy32471722015-04-20 15:20:28 -07008#include <device/device.h>
9#include <device/pci.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070010#include <soc/iomap.h>
Lee Leahy32471722015-04-20 15:20:28 -070011#include <soc/pm.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070012#include <soc/smm.h>
13
14/* Save settings which will be committed in SMI functions. */
15static uint32_t smm_save_params[SMM_SAVE_PARAM_COUNT];
16
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030017void smm_southcluster_save_param(int param, uint32_t data)
Lee Leahy77ff0b12015-05-05 15:07:29 -070018{
19 smm_save_params[param] = data;
20}
21
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030022void smm_southbridge_clear_state(void)
Lee Leahy77ff0b12015-05-05 15:07:29 -070023{
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();
Lee Leahy77ff0b12015-05-05 15:07:29 -070029
Lee Leahy77ff0b12015-05-05 15:07:29 -070030 smi_en = inl(get_pmbase() + SMI_EN);
31 if (smi_en & APMC_EN) {
32 printk(BIOS_INFO, "SMI# handler already enabled?\n");
33 return;
34 }
35
36 /* Dump and clear status registers */
37 clear_smi_status();
38 clear_pm1_status();
39 clear_tco_status();
40 clear_gpe_status();
41 clear_alt_status();
42 clear_pmc_status();
43}
44
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030045static void smm_southcluster_route_gpios(void)
Lee Leahy77ff0b12015-05-05 15:07:29 -070046{
Lee Leahy32471722015-04-20 15:20:28 -070047 void *gpio_rout = (void *)(PMC_BASE_ADDRESS + GPIO_ROUT);
Lee Leahy77ff0b12015-05-05 15:07:29 -070048 const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI;
49 uint32_t alt_gpio_reg = 0;
50 uint32_t route_reg = smm_save_params[SMM_SAVE_PARAM_GPIO_ROUTE];
51 int i;
52
53 printk(BIOS_DEBUG, "GPIO_ROUT = %08x\n", route_reg);
54
55 /* Start the routing for the specific gpios. */
56 write32(gpio_rout, route_reg);
57
58 /* Enable SMIs for the gpios that are set to trigger the SMI. */
59 for (i = 0; i < 16; i++) {
Lee Leahy32471722015-04-20 15:20:28 -070060 if ((route_reg & ROUTE_MASK) == ROUTE_SMI)
Lee Leahy77ff0b12015-05-05 15:07:29 -070061 alt_gpio_reg |= (1 << i);
Angel Ponsaee7ab22020-03-19 00:31:58 +010062
Lee Leahy77ff0b12015-05-05 15:07:29 -070063 route_reg >>= 2;
64 }
65 printk(BIOS_DEBUG, "ALT_GPIO_SMI = %08x\n", alt_gpio_reg);
66
67 outl(alt_gpio_reg, alt_gpio_smi);
68}
69
Kyösti Mälkki0778c862020-06-10 12:44:03 +030070static void smm_southbridge_enable(uint16_t pm1_events)
Lee Leahy77ff0b12015-05-05 15:07:29 -070071{
Lee Leahy77ff0b12015-05-05 15:07:29 -070072
73 printk(BIOS_DEBUG, "Enabling SMIs.\n");
74 if (!smm_save_params[SMM_SAVE_PARAM_PCIE_WAKE_ENABLE])
75 pm1_events |= PCIEXPWAK_DIS;
Angel Ponsaee7ab22020-03-19 00:31:58 +010076
Lee Leahy77ff0b12015-05-05 15:07:29 -070077 enable_pm1(pm1_events);
78 disable_gpe(PME_B0_EN);
79
80 /* Set up the GPIO route. */
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030081 smm_southcluster_route_gpios();
Lee Leahy77ff0b12015-05-05 15:07:29 -070082
Lee Leahy32471722015-04-20 15:20:28 -070083 /*
84 * Enable SMI generation:
Lee Leahy77ff0b12015-05-05 15:07:29 -070085 * - on APMC writes (io 0xb2)
86 * - on writes to SLP_EN (sleep states)
87 * - on writes to GBL_RLS (bios commands)
88 * No SMIs:
89 * - on TCO events
90 * - on microcontroller writes (io 0x62/0x66)
91 */
92 enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
93}
94
Kyösti Mälkki0778c862020-06-10 12:44:03 +030095void global_smi_enable(void)
96{
97 smm_southbridge_enable(PWRBTN_EN | GBL_EN);
98}