From d3476809955ffb69447cc02a5ea893ebd1da3eb3 Mon Sep 17 00:00:00 2001 From: Shaunak Saha Date: Sat, 8 Jul 2017 01:08:40 -0700 Subject: soc/intel/skylake: Add support in SKL for PMC common code Change-Id: I3742f9c22d990edd918713155ae0bb1853663b6f Signed-off-by: Shaunak Saha Reviewed-on: https://review.coreboot.org/20499 Reviewed-by: Aaron Durbin Tested-by: build bot (Jenkins) --- src/soc/intel/skylake/romstage/power_state.c | 135 ++++-------------------- src/soc/intel/skylake/romstage/romstage.c | 11 ++ src/soc/intel/skylake/romstage/romstage_fsp20.c | 5 +- 3 files changed, 35 insertions(+), 116 deletions(-) (limited to 'src/soc/intel/skylake/romstage') diff --git a/src/soc/intel/skylake/romstage/power_state.c b/src/soc/intel/skylake/romstage/power_state.c index 19f43c3a93..78650fa590 100644 --- a/src/soc/intel/skylake/romstage/power_state.c +++ b/src/soc/intel/skylake/romstage/power_state.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include @@ -27,63 +26,26 @@ #include #include #include -#include #include #include #include +#include #include #include - -static struct chipset_power_state power_state CAR_GLOBAL; - -static struct chipset_power_state *get_power_state(void) -{ - return car_get_var_ptr(&power_state); -} - -static void migrate_power_state(int is_recovery) -{ - struct chipset_power_state *ps_cbmem; - struct chipset_power_state *ps_car; - - ps_car = get_power_state(); - ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem)); - - if (ps_cbmem == NULL) { - printk(BIOS_DEBUG, "Not adding power state to cbmem!\n"); - return; - } - memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem)); -} -ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state) +#include /* Return 0, 3, or 5 to indicate the previous sleep state. */ -static uint32_t prev_sleep_state(struct chipset_power_state *ps) +int soc_prev_sleep_state(const struct chipset_power_state *ps, + int prev_sleep_state) { - /* Default to S0. */ - uint32_t prev_sleep_state = ACPI_S0; - - if (ps->pm1_sts & WAK_STS) { - switch (acpi_sleep_from_pm1(ps->pm1_cnt)) { - case ACPI_S3: - if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) - prev_sleep_state = ACPI_S3; - break; - case ACPI_S5: - prev_sleep_state = ACPI_S5; - break; - } - /* Clear SLP_TYP. */ - outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT); - } else { - /* - * Check for any power failure to determine if this a wake from - * S5 because the PCH does not set the WAK_STS bit when waking - * from a true G3 state. - */ - if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR)) - prev_sleep_state = ACPI_S5; - } + + /* + * Check for any power failure to determine if this a wake from + * S5 because the PCH does not set the WAK_STS bit when waking + * from a true G3 state. + */ + if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR)) + prev_sleep_state = ACPI_S5; /* * If waking from S3 determine if deep S3 is enabled. If not, @@ -101,57 +63,21 @@ static uint32_t prev_sleep_state(struct chipset_power_state *ps) if (ps->gen_pmcon_b & mask) prev_sleep_state = ACPI_S5; } - return prev_sleep_state; } -static void dump_power_state(struct chipset_power_state *ps) -{ - printk(BIOS_DEBUG, "PM1_STS: %04x\n", ps->pm1_sts); - printk(BIOS_DEBUG, "PM1_EN: %04x\n", ps->pm1_en); - printk(BIOS_DEBUG, "PM1_CNT: %08x\n", ps->pm1_cnt); - printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", - ps->tco1_sts, ps->tco2_sts); - - printk(BIOS_DEBUG, "GPE0_STS: %08x %08x %08x %08x\n", - ps->gpe0_sts[0], ps->gpe0_sts[1], - ps->gpe0_sts[2], ps->gpe0_sts[3]); - printk(BIOS_DEBUG, "GPE0_EN: %08x %08x %08x %08x\n", - ps->gpe0_en[0], ps->gpe0_en[1], - ps->gpe0_en[2], ps->gpe0_en[3]); - - printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", - ps->gen_pmcon_a, ps->gen_pmcon_b); - - printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", - ps->gblrst_cause[0], ps->gblrst_cause[1]); - - printk(BIOS_DEBUG, "Previous Sleep State: S%d\n", - ps->prev_sleep_state); -} - -/* Fill power state structure from ACPI PM registers */ -struct chipset_power_state *fill_power_state(void) +void soc_fill_power_state(struct chipset_power_state *ps) { uint16_t tcobase; uint8_t *pmc; - struct chipset_power_state *ps = get_power_state(); tcobase = smbus_tco_regs(); - ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS); - ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN); - ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); ps->tco1_sts = inw(tcobase + TCO1_STS); ps->tco2_sts = inw(tcobase + TCO2_STS); - ps->gpe0_sts[0] = inl(ACPI_BASE_ADDRESS + GPE0_STS(0)); - ps->gpe0_sts[1] = inl(ACPI_BASE_ADDRESS + GPE0_STS(1)); - ps->gpe0_sts[2] = inl(ACPI_BASE_ADDRESS + GPE0_STS(2)); - ps->gpe0_sts[3] = inl(ACPI_BASE_ADDRESS + GPE0_STS(3)); - ps->gpe0_en[0] = inl(ACPI_BASE_ADDRESS + GPE0_EN(0)); - ps->gpe0_en[1] = inl(ACPI_BASE_ADDRESS + GPE0_EN(1)); - ps->gpe0_en[2] = inl(ACPI_BASE_ADDRESS + GPE0_EN(2)); - ps->gpe0_en[3] = inl(ACPI_BASE_ADDRESS + GPE0_EN(3)); + + printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", + ps->tco1_sts, ps->tco2_sts); ps->gen_pmcon_a = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_A); ps->gen_pmcon_b = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_B); @@ -160,36 +86,17 @@ struct chipset_power_state *fill_power_state(void) ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); - ps->prev_sleep_state = prev_sleep_state(ps); - - dump_power_state(ps); + printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", + ps->gen_pmcon_a, ps->gen_pmcon_b); - return ps; + printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", + ps->gblrst_cause[0], ps->gblrst_cause[1]); } int acpi_get_sleep_type(void) { struct chipset_power_state *ps; - ps = get_power_state(); + ps = pmc_get_power_state(); return ps->prev_sleep_state; } - -int vboot_platform_is_resuming(void) -{ - return acpi_sleep_from_pm1(inl(ACPI_BASE_ADDRESS + PM1_CNT)) == ACPI_S3; -} - -/* - * The PM1 control is set to S5 when vboot requests a reboot because the power - * state code above may not have collected it's data yet. Therefore, set it to - * S5 when vboot requests a reboot. That's necessary if vboot fails in the - * resume path and requests a reboot. This prevents a reboot loop where the - * error is continually hit on the failing vboot resume path. - */ -void vboot_platform_prepare_reboot(void) -{ - uint16_t port = ACPI_BASE_ADDRESS + PM1_CNT; - - outl((inl(port) & ~(SLP_TYP)) | (SLP_TYP_S5 << SLP_TYP_SHIFT), port); -} diff --git a/src/soc/intel/skylake/romstage/romstage.c b/src/soc/intel/skylake/romstage/romstage.c index 50c050ef45..215b07c074 100644 --- a/src/soc/intel/skylake/romstage/romstage.c +++ b/src/soc/intel/skylake/romstage/romstage.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -256,3 +257,13 @@ void soc_after_ram_init(struct romstage_params *params) */ pmc_set_disb(); } + +struct chipset_power_state *fill_power_state(void) +{ + struct chipset_power_state *ps; + + ps = pmc_get_power_state(); + pmc_fill_power_state(ps); + + return ps; +} diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c index cbf934e8bd..d4a5e34199 100644 --- a/src/soc/intel/skylake/romstage/romstage_fsp20.c +++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -119,9 +120,9 @@ asmlinkage void car_stage_entry(void) /* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */ systemagent_early_init(); - ps = fill_power_state(); + ps = pmc_get_power_state(); timestamp_add_now(TS_START_ROMSTAGE); - s3wake = ps->prev_sleep_state == ACPI_S3; + s3wake = pmc_fill_power_state(ps) == ACPI_S3; fsp_memory_init(s3wake); pmc_set_disb(); if (!s3wake) -- cgit v1.2.3