diff --git a/src/soc/intel/baytrail/baytrail/smm.h b/src/soc/intel/baytrail/baytrail/smm.h index e00944d520..f147f7336e 100644 --- a/src/soc/intel/baytrail/baytrail/smm.h +++ b/src/soc/intel/baytrail/baytrail/smm.h @@ -37,7 +37,13 @@ void *smm_region_start(void); #include void southcluster_smm_clear_state(void); void southcluster_smm_enable_smi(void); -void southcluster_smm_save_gpio_route(uint32_t route); +void southcluster_smm_save_param(int param, uint32_t data); #endif +enum { + SMM_SAVE_PARAM_GPIO_ROUTE = 0, + SMM_SAVE_PARAM_PCIE_WAKE_ENABLE, + SMM_SAVE_PARAM_COUNT +}; + #endif /* _BAYTRAIL_SMM_H_ */ diff --git a/src/soc/intel/baytrail/chip.h b/src/soc/intel/baytrail/chip.h index b312e40103..256ed4f2fa 100644 --- a/src/soc/intel/baytrail/chip.h +++ b/src/soc/intel/baytrail/chip.h @@ -69,6 +69,9 @@ struct soc_intel_baytrail_config { int scc_acpi_mode; int lpe_acpi_mode; + /* Allow PCIe devices to wake system from suspend. */ + int pcie_wake_enable; + /* * Digital Port Hotplug Enable: * 0x04 = Enabled, 2ms short pulse diff --git a/src/soc/intel/baytrail/gpio.c b/src/soc/intel/baytrail/gpio.c index 33a556bf64..43e52ef9a0 100644 --- a/src/soc/intel/baytrail/gpio.c +++ b/src/soc/intel/baytrail/gpio.c @@ -192,7 +192,7 @@ static void setup_gpio_route(const struct soc_gpio_map *sus, route_reg |= ROUTE_SCI << (2 * (i + 8)); } } - southcluster_smm_save_gpio_route(route_reg); + southcluster_smm_save_param(SMM_SAVE_PARAM_GPIO_ROUTE, route_reg); } static void setup_dirqs(const u8 dirq[GPIO_MAX_DIRQS], diff --git a/src/soc/intel/baytrail/pcie.c b/src/soc/intel/baytrail/pcie.c index ce76d6d88f..4498f43a22 100644 --- a/src/soc/intel/baytrail/pcie.c +++ b/src/soc/intel/baytrail/pcie.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "chip.h" @@ -174,10 +175,15 @@ static void check_device_present(device_t dev) static void byt_pcie_enable(device_t dev) { if (is_first_port(dev)) { + struct soc_intel_baytrail_config *config = dev->chip_info; uint32_t reg = pci_read_config32(dev, PHYCTL2_IOSFBCTL); pll_en_off = !!(reg & PLL_OFF_EN); strpfusecfg = pci_read_config32(dev, STRPFUSECFG); + + if (config && config->pcie_wake_enable) + southcluster_smm_save_param( + SMM_SAVE_PARAM_PCIE_WAKE_ENABLE, 1); } /* Check if device is enabled in strapping. */ diff --git a/src/soc/intel/baytrail/smm.c b/src/soc/intel/baytrail/smm.c index d4b3d58350..daf759d206 100644 --- a/src/soc/intel/baytrail/smm.c +++ b/src/soc/intel/baytrail/smm.c @@ -31,13 +31,12 @@ #include #include -/* Save the gpio route register. The settings are committed from - * southcluster_smm_enable_smi(). */ -static uint32_t gpio_route; +/* Save settings which will be committed in SMI functions. */ +static uint32_t smm_save_params[SMM_SAVE_PARAM_COUNT]; -void southcluster_smm_save_gpio_route(uint32_t route) +void southcluster_smm_save_param(int param, uint32_t data) { - gpio_route = route; + smm_save_params[param] = data; } void southcluster_smm_clear_state(void) @@ -70,7 +69,7 @@ static void southcluster_smm_route_gpios(void) const unsigned long gpio_rout = PMC_BASE_ADDRESS + GPIO_ROUT; const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI; uint32_t alt_gpio_reg = 0; - uint32_t route_reg = gpio_route; + uint32_t route_reg = smm_save_params[SMM_SAVE_PARAM_GPIO_ROUTE]; int i; printk(BIOS_DEBUG, "GPIO_ROUT = %08x\n", route_reg); @@ -92,10 +91,12 @@ static void southcluster_smm_route_gpios(void) void southcluster_smm_enable_smi(void) { + uint16_t pm1_events = PWRBTN_EN | GBL_EN; printk(BIOS_DEBUG, "Enabling SMIs.\n"); - /* Configure events Disable pcie wake. */ - enable_pm1(PWRBTN_EN | GBL_EN | PCIEXPWAK_DIS); + if (!smm_save_params[SMM_SAVE_PARAM_PCIE_WAKE_ENABLE]) + pm1_events |= PCIEXPWAK_DIS; + enable_pm1(pm1_events); disable_gpe(PME_B0_EN); /* Set up the GPIO route. */