soc: Remove copyright notices
[coreboot.git] / src / soc / intel / braswell / smm.c
blobc470f93f6dd81a99b5922579970ec24f7a475c13
1 /*
2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; version 2 of
8 * the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/io.h>
17 #include <device/mmio.h>
18 #include <console/console.h>
19 #include <cpu/x86/smm.h>
20 #include <cpu/intel/smm_reloc.h>
21 #include <device/device.h>
22 #include <device/pci.h>
23 #include <soc/iomap.h>
24 #include <soc/pm.h>
25 #include <soc/smm.h>
27 /* Save settings which will be committed in SMI functions. */
28 static uint32_t smm_save_params[SMM_SAVE_PARAM_COUNT];
30 void smm_southcluster_save_param(int param, uint32_t data)
32 smm_save_params[param] = data;
35 void smm_southbridge_clear_state(void)
37 uint32_t smi_en;
39 /* Log events from chipset before clearing */
40 if (CONFIG(ELOG))
41 southcluster_log_state();
43 printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
44 printk(BIOS_SPEW, " pmbase = 0x%04x\n", get_pmbase());
46 smi_en = inl(get_pmbase() + SMI_EN);
47 if (smi_en & APMC_EN) {
48 printk(BIOS_INFO, "SMI# handler already enabled?\n");
49 return;
52 /* Dump and clear status registers */
53 clear_smi_status();
54 clear_pm1_status();
55 clear_tco_status();
56 clear_gpe_status();
57 clear_alt_status();
58 clear_pmc_status();
61 static void smm_southcluster_route_gpios(void)
63 void *gpio_rout = (void *)(PMC_BASE_ADDRESS + GPIO_ROUT);
64 const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI;
65 uint32_t alt_gpio_reg = 0;
66 uint32_t route_reg = smm_save_params[SMM_SAVE_PARAM_GPIO_ROUTE];
67 int i;
69 printk(BIOS_DEBUG, "GPIO_ROUT = %08x\n", route_reg);
71 /* Start the routing for the specific gpios. */
72 write32(gpio_rout, route_reg);
74 /* Enable SMIs for the gpios that are set to trigger the SMI. */
75 for (i = 0; i < 16; i++) {
76 if ((route_reg & ROUTE_MASK) == ROUTE_SMI)
77 alt_gpio_reg |= (1 << i);
78 route_reg >>= 2;
80 printk(BIOS_DEBUG, "ALT_GPIO_SMI = %08x\n", alt_gpio_reg);
82 outl(alt_gpio_reg, alt_gpio_smi);
85 void smm_southbridge_enable_smi(void)
87 uint16_t pm1_events = PWRBTN_EN | GBL_EN;
89 printk(BIOS_DEBUG, "Enabling SMIs.\n");
90 if (!smm_save_params[SMM_SAVE_PARAM_PCIE_WAKE_ENABLE])
91 pm1_events |= PCIEXPWAK_DIS;
92 enable_pm1(pm1_events);
93 disable_gpe(PME_B0_EN);
95 /* Set up the GPIO route. */
96 smm_southcluster_route_gpios();
99 * Enable SMI generation:
100 * - on APMC writes (io 0xb2)
101 * - on writes to SLP_EN (sleep states)
102 * - on writes to GBL_RLS (bios commands)
103 * No SMIs:
104 * - on TCO events
105 * - on microcontroller writes (io 0x62/0x66)
107 enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
110 void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
113 * Issue SMI to set the gnvs pointer in SMM.
114 * tcg and smi1 are unused.
116 * EAX = APM_CNT_GNVS_UPDATE
117 * EBX = gnvs pointer
118 * EDX = APM_CNT
120 asm volatile (
121 "outb %%al, %%dx\n\t"
122 : /* ignore result */
123 : "a" (APM_CNT_GNVS_UPDATE),
124 "b" ((uint32_t)gnvs),
125 "d" (APM_CNT)