blob: 3f3c53fa74b2a384d2207dfcbd449c43b5655f0b [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
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();
44 clear_alt_status();
45 clear_pmc_status();
46}
47
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030048static void smm_southcluster_route_gpios(void)
Lee Leahy77ff0b12015-05-05 15:07:29 -070049{
Lee Leahy32471722015-04-20 15:20:28 -070050 void *gpio_rout = (void *)(PMC_BASE_ADDRESS + GPIO_ROUT);
Lee Leahy77ff0b12015-05-05 15:07:29 -070051 const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI;
52 uint32_t alt_gpio_reg = 0;
53 uint32_t route_reg = smm_save_params[SMM_SAVE_PARAM_GPIO_ROUTE];
54 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++) {
Lee Leahy32471722015-04-20 15:20:28 -070063 if ((route_reg & ROUTE_MASK) == ROUTE_SMI)
Lee Leahy77ff0b12015-05-05 15:07:29 -070064 alt_gpio_reg |= (1 << i);
Angel Ponsaee7ab22020-03-19 00:31:58 +010065
Lee Leahy77ff0b12015-05-05 15:07:29 -070066 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)
Lee Leahy77ff0b12015-05-05 15:07:29 -070074{
Lee Leahy77ff0b12015-05-05 15:07:29 -070075
76 printk(BIOS_DEBUG, "Enabling SMIs.\n");
77 if (!smm_save_params[SMM_SAVE_PARAM_PCIE_WAKE_ENABLE])
78 pm1_events |= PCIEXPWAK_DIS;
Angel Ponsaee7ab22020-03-19 00:31:58 +010079
Lee Leahy77ff0b12015-05-05 15:07:29 -070080 enable_pm1(pm1_events);
81 disable_gpe(PME_B0_EN);
82
83 /* Set up the GPIO route. */
Kyösti Mälkkifaf20d32019-08-14 05:41:41 +030084 smm_southcluster_route_gpios();
Lee Leahy77ff0b12015-05-05 15:07:29 -070085
Lee Leahy32471722015-04-20 15:20:28 -070086 /*
87 * Enable SMI generation:
Lee Leahy77ff0b12015-05-05 15:07:29 -070088 * - on APMC writes (io 0xb2)
89 * - on writes to SLP_EN (sleep states)
90 * - on writes to GBL_RLS (bios commands)
91 * No SMIs:
92 * - on TCO events
93 * - on microcontroller writes (io 0x62/0x66)
94 */
95 enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
96}
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}