2 * This file is part of the coreboot project.
4 * Copyright (C) 2013 Google Inc.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <device/device.h>
18 #include <device/pci.h>
19 #include <console/console.h>
22 #include <cpu/x86/smm.h>
25 #include <baytrail/iomap.h>
26 #include <baytrail/pmc.h>
27 #include <baytrail/smm.h>
29 /* Save the gpio route register. The settings are committed from
30 * southcluster_smm_enable_smi(). */
31 static uint32_t gpio_route
;
33 void southcluster_smm_save_gpio_route(uint32_t route
)
38 void southcluster_smm_clear_state(void)
42 /* Log events from chipset before clearing */
43 southcluster_log_state();
45 printk(BIOS_DEBUG
, "Initializing Southbridge SMI...");
46 printk(BIOS_SPEW
, " pmbase = 0x%04x\n", get_pmbase());
48 smi_en
= inl(get_pmbase() + SMI_EN
);
49 if (smi_en
& APMC_EN
) {
50 printk(BIOS_INFO
, "SMI# handler already enabled?\n");
54 /* Dump and clear status registers */
63 static void southcluster_smm_route_gpios(void)
65 u32
*gpio_rout
= (u32
*)(PMC_BASE_ADDRESS
+ GPIO_ROUT
);
66 const unsigned short alt_gpio_smi
= ACPI_BASE_ADDRESS
+ ALT_GPIO_SMI
;
67 uint32_t alt_gpio_reg
= 0;
68 uint32_t route_reg
= gpio_route
;
71 printk(BIOS_DEBUG
, "GPIO_ROUT = %08x\n", route_reg
);
73 /* Start the routing for the specific gpios. */
74 write32(gpio_rout
, route_reg
);
76 /* Enable SMIs for the gpios that are set to trigger the SMI. */
77 for (i
= 0; i
< 16; i
++) {
78 if ((route_reg
& ROUTE_MASK
) == ROUTE_SMI
) {
79 alt_gpio_reg
|= (1 << i
);
83 printk(BIOS_DEBUG
, "ALT_GPIO_SMI = %08x\n", alt_gpio_reg
);
85 outl(alt_gpio_reg
, alt_gpio_smi
);
88 void southcluster_smm_enable_smi(void)
91 printk(BIOS_DEBUG
, "Enabling SMIs.\n");
92 /* Configure events Disable pcie wake. */
93 enable_pm1(PWRBTN_EN
| GBL_EN
| PCIEXPWAK_DIS
);
94 disable_gpe(PME_B0_EN
);
96 /* Set up the GPIO route. */
97 southcluster_smm_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)
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
121 "outb %%al, %%dx\n\t"
122 : /* ignore result */
123 : "a" (APM_CNT_GNVS_UPDATE
),
124 "b" ((uint32_t)gnvs
),