From 7f4ec968695e918da49fc9b9163188188b71f05b Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 19 Dec 2017 10:27:45 +0530 Subject: soc/intel/skylake: Implement pmc_soc_restore_power_failure as per EDS TEST=KBL_RVP is able to power on after reconnecting power supply. Change-Id: Ic707164a576ffb25418eb6553843cd8edc608800 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/22839 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Aaron Durbin --- src/soc/intel/skylake/include/soc/pm.h | 8 ++--- src/soc/intel/skylake/pmc.c | 62 ++++++++++++++++++++++++---------- src/soc/intel/skylake/smihandler.c | 24 +------------ 3 files changed, 47 insertions(+), 47 deletions(-) (limited to 'src/soc') diff --git a/src/soc/intel/skylake/include/soc/pm.h b/src/soc/intel/skylake/include/soc/pm.h index 00578180eb..e904658397 100644 --- a/src/soc/intel/skylake/include/soc/pm.h +++ b/src/soc/intel/skylake/include/soc/pm.h @@ -135,14 +135,10 @@ #define GBLRST_CAUSE0_THERMTRIP (1 << 5) -#define MAINBOARD_POWER_OFF 0 -#define MAINBOARD_POWER_ON 1 -#define MAINBOARD_POWER_KEEP 2 - /* This is defined as ETR3 in EDS. We named it as ETR here for consistency */ #define ETR 0xac -# define CF9_LOCK (1 << 31) -# define CF9_GLB_RST (1 << 20) +#define CF9_LOCK (1 << 31) +#define CF9_GLB_RST (1 << 20) #define PRSTS 0x10 diff --git a/src/soc/intel/skylake/pmc.c b/src/soc/intel/skylake/pmc.c index 91b319c55b..92d0f9e358 100644 --- a/src/soc/intel/skylake/pmc.c +++ b/src/soc/intel/skylake/pmc.c @@ -73,43 +73,58 @@ static const struct reg_script pmc_write1_to_clear_script[] = { REG_SCRIPT_END }; +/* + * Set which power state system will be after reapplying + * the power (from G3 State) + */ +static void pmc_set_afterg3(struct device *dev, int s5pwr) +{ + uint8_t reg8; + + reg8 = pci_read_config8(dev, GEN_PMCON_B); + + switch (s5pwr) { + case MAINBOARD_POWER_STATE_OFF: + reg8 |= 1; + break; + case MAINBOARD_POWER_STATE_ON: + reg8 &= ~1; + break; + case MAINBOARD_POWER_STATE_PREVIOUS: + default: + break; + } + + pci_write_config8(dev, GEN_PMCON_B, reg8); +} + static void pch_power_options(struct device *dev) { - u16 reg16; const char *state; /* Get the chip configuration */ - int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + int pwr_on = pmc_get_mainboard_power_failure_state_choice(); /* * Which state do we want to goto after g3 (power restored)? - * 0 == S0 Full On - * 1 == S5 Soft Off - * - * If the option is not existent (Laptops), use Kconfig setting. + * 0 == S5 Soft Off + * 1 == S0 Full On + * 2 == Keep Previous State */ - /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/ - //get_option(&pwr_on, "power_on_after_fail"); - pwr_on = MAINBOARD_POWER_ON; - reg16 = pci_read_config16(dev, GEN_PMCON_B); - reg16 &= 0xfffe; switch (pwr_on) { - case MAINBOARD_POWER_OFF: - reg16 |= 1; + case MAINBOARD_POWER_STATE_OFF: state = "off"; break; - case MAINBOARD_POWER_ON: - reg16 &= ~1; + case MAINBOARD_POWER_STATE_ON: state = "on"; break; - case MAINBOARD_POWER_KEEP: - reg16 &= ~1; + case MAINBOARD_POWER_STATE_PREVIOUS: state = "state keep"; break; default: state = "undefined"; } - pci_write_config16(dev, GEN_PMCON_B, reg16); + pmc_set_afterg3(dev, pwr_on); printk(BIOS_INFO, "Set power %s after power failure.\n", state); /* Set up GPE configuration. */ @@ -178,4 +193,15 @@ void pmc_soc_init(struct device *dev) /* Clear registers that contain write-1-to-clear bits. */ reg_script_run_on_dev(dev, pmc_write1_to_clear_script); } + +/* + * Set PMC register to know which state system should be after + * power reapplied + */ +void pmc_soc_restore_power_failure(void) +{ + pmc_set_afterg3(PCH_DEV_PMC, + pmc_get_mainboard_power_failure_state_choice()); +} + #endif diff --git a/src/soc/intel/skylake/smihandler.c b/src/soc/intel/skylake/smihandler.c index 211432cd35..9ec6b87ca6 100644 --- a/src/soc/intel/skylake/smihandler.c +++ b/src/soc/intel/skylake/smihandler.c @@ -120,21 +120,10 @@ static void busmaster_disable_on_bus(int bus) } } - static void southbridge_smi_sleep(void) { - u8 reg8; u32 reg32; u8 slp_typ; - u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; - - /* save and recover RTC port values */ - u8 tmp70, tmp72; - tmp70 = inb(0x70); - tmp72 = inb(0x72); - get_option(&s5pwr, "power_on_after_fail"); - outb(tmp70, 0x70); - outb(tmp72, 0x72); /* First, disable further SMIs */ pmc_disable_smi(SLP_SMI_EN); @@ -173,21 +162,10 @@ static void southbridge_smi_sleep(void) break; case ACPI_S5: printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n"); - /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/ - s5pwr = MAINBOARD_POWER_ON; /* Disable all GPE */ pmc_disable_all_gpe(); - /* - * Always set the flag in case CMOS was changed on runtime. For - * "KEEP", switch to "OFF" - KEEP is software emulated - */ - reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B); - if (s5pwr == MAINBOARD_POWER_ON) - reg8 &= ~1; - else - reg8 |= 1; - pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8); + pmc_soc_restore_power_failure(); /* also iterates over all bridges on bus 0 */ busmaster_disable_on_bus(0); -- cgit v1.2.3