baytrail: add GPIO SMI support
GPIOs which trigger SMIs only set the status bits in the ALT_GPIO_SMI regier. No bits in the SMI_STS register are set. Therefore, the ALT_GPIO_SMI register needs to be read and cleared on every SMI. Additionally, the mainboard_gpi_smi() handler needs to be called as well on every SMI because of this property. BUG=chrome-os-partner:23505 BRANCH=None TEST=Built and booted to recovery screen. Typed 'lidclose' on EC console. SMI occurred which caused the board to be shutdown. Change-Id: Ic204d8b928a0cb4f51f108a649f374d9f94e4f47 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/176391 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/4958 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
parent
59a4cd5578
commit
9f83e873f4
|
@ -198,6 +198,7 @@ uint32_t clear_smi_status(void);
|
||||||
uint16_t clear_pm1_status(void);
|
uint16_t clear_pm1_status(void);
|
||||||
uint32_t clear_tco_status(void);
|
uint32_t clear_tco_status(void);
|
||||||
uint32_t clear_gpe_status(void);
|
uint32_t clear_gpe_status(void);
|
||||||
|
uint32_t clear_alt_status(void);
|
||||||
void enable_smi(uint32_t mask);
|
void enable_smi(uint32_t mask);
|
||||||
void disable_smi(uint32_t mask);
|
void disable_smi(uint32_t mask);
|
||||||
void enable_pm1(uint16_t events);
|
void enable_pm1(uint16_t events);
|
||||||
|
|
|
@ -52,14 +52,15 @@ uint16_t get_pmbase(void)
|
||||||
return pci_read_config16(get_pcu_dev(), ABASE) & 0xfff8;
|
return pci_read_config16(get_pcu_dev(), ABASE) & 0xfff8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_status_bits(uint32_t status, const char *bit_names[])
|
static void print_num_status_bits(int num_bits, uint32_t status,
|
||||||
|
const char *bit_names[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 31; i >= 0; i--) {
|
for (i = num_bits - 1; i >= 0; i--) {
|
||||||
if (status & (1 << i)) {
|
if (status & (1 << i)) {
|
||||||
if (bit_names[i])
|
if (bit_names[i])
|
||||||
printk(BIOS_DEBUG, "%s ", bit_names[i]);
|
printk(BIOS_DEBUG, "%s ", bit_names[i]);
|
||||||
|
@ -69,6 +70,11 @@ static void print_status_bits(uint32_t status, const char *bit_names[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_status_bits(uint32_t status, const char *bit_names[])
|
||||||
|
{
|
||||||
|
print_num_status_bits(32, status, bit_names);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t print_smi_status(uint32_t smi_sts)
|
static uint32_t print_smi_status(uint32_t smi_sts)
|
||||||
{
|
{
|
||||||
static const char *smi_sts_bits[] = {
|
static const char *smi_sts_bits[] = {
|
||||||
|
@ -295,3 +301,50 @@ uint32_t clear_gpe_status(void)
|
||||||
{
|
{
|
||||||
return print_gpe_sts(reset_gpe_status());
|
return print_gpe_sts(reset_gpe_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t reset_alt_status(void)
|
||||||
|
{
|
||||||
|
uint16_t pmbase = get_pmbase();
|
||||||
|
uint32_t alt_gpio_smi = inl(pmbase + ALT_GPIO_SMI);
|
||||||
|
outl(alt_gpio_smi, pmbase + ALT_GPIO_SMI);
|
||||||
|
return alt_gpio_smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t print_alt_sts(uint32_t alt_gpio_smi)
|
||||||
|
{
|
||||||
|
uint32_t alt_gpio_sts;
|
||||||
|
static const char *alt_gpio_smi_sts_bits[] = {
|
||||||
|
[0] = "SUS_GPIO_0",
|
||||||
|
[1] = "SUS_GPIO_1",
|
||||||
|
[2] = "SUS_GPIO_2",
|
||||||
|
[3] = "SUS_GPIO_3",
|
||||||
|
[4] = "SUS_GPIO_4",
|
||||||
|
[5] = "SUS_GPIO_5",
|
||||||
|
[6] = "SUS_GPIO_6",
|
||||||
|
[7] = "SUS_GPIO_7",
|
||||||
|
[8] = "CORE_GPIO_0",
|
||||||
|
[9] = "CORE_GPIO_1",
|
||||||
|
[10] = "CORE_GPIO_2",
|
||||||
|
[11] = "CORE_GPIO_3",
|
||||||
|
[12] = "CORE_GPIO_4",
|
||||||
|
[13] = "CORE_GPIO_5",
|
||||||
|
[14] = "CORE_GPIO_6",
|
||||||
|
[15] = "CORE_GPIO_7",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Status bits are in the upper 16 bits. */
|
||||||
|
alt_gpio_sts = alt_gpio_smi >> 16;
|
||||||
|
if (!alt_gpio_sts)
|
||||||
|
return alt_gpio_smi;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "ALT_GPIO_SMI: ");
|
||||||
|
print_num_status_bits(16, alt_gpio_sts, alt_gpio_smi_sts_bits);
|
||||||
|
printk(BIOS_DEBUG, "\n");
|
||||||
|
|
||||||
|
return alt_gpio_smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t clear_alt_status(void)
|
||||||
|
{
|
||||||
|
return print_alt_sts(reset_alt_status());
|
||||||
|
}
|
||||||
|
|
|
@ -300,7 +300,7 @@ static void southbridge_smi_pm1(void)
|
||||||
elog_add_event(ELOG_TYPE_POWER_BUTTON);
|
elog_add_event(ELOG_TYPE_POWER_BUTTON);
|
||||||
#endif
|
#endif
|
||||||
disable_pm1_control(-1UL);
|
disable_pm1_control(-1UL);
|
||||||
enable_pm1_control(SLP_EN | (SLP_TYP_S5 << 10));
|
enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,4 +396,8 @@ void southbridge_smi_handler(void)
|
||||||
"handler available.\n", i);
|
"handler available.\n", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The GPIO SMI events do not have a status bit in SMI_STS. Therefore,
|
||||||
|
* these events need to be cleared and checked unconditionally. */
|
||||||
|
mainboard_smi_gpi(clear_alt_status());
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ void southcluster_smm_clear_state(void)
|
||||||
clear_pm1_status();
|
clear_pm1_status();
|
||||||
clear_tco_status();
|
clear_tco_status();
|
||||||
clear_gpe_status();
|
clear_gpe_status();
|
||||||
|
clear_alt_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void southcluster_smm_route_gpios(void)
|
static void southcluster_smm_route_gpios(void)
|
||||||
|
|
Loading…
Reference in New Issue