diff --git a/src/soc/intel/baytrail/elog.c b/src/soc/intel/baytrail/elog.c index 8c6be9f319..f50d1301f3 100644 --- a/src/soc/intel/baytrail/elog.c +++ b/src/soc/intel/baytrail/elog.c @@ -42,6 +42,10 @@ static void log_power_and_resets(const struct chipset_power_state *ps) elog_add_event(ELOG_TYPE_SUS_POWER_FAIL); } + if (ps->gen_pmcon1 & RPS) { + elog_add_event(ELOG_TYPE_RTC_RESET); + } + if (ps->tco_sts & SECOND_TO_STS) { elog_add_event(ELOG_TYPE_TCO_RESET); } diff --git a/src/soc/intel/baytrail/pmutil.c b/src/soc/intel/baytrail/pmutil.c index 5d37a1366d..aee37261be 100644 --- a/src/soc/intel/baytrail/pmutil.c +++ b/src/soc/intel/baytrail/pmutil.c @@ -358,7 +358,7 @@ void clear_pmc_status(void) prsts = read32(PMC_BASE_ADDRESS + PRSTS); gen_pmcon1 = read32(PMC_BASE_ADDRESS + GEN_PMCON1); - /* Clear the status bits. */ - write32(PMC_BASE_ADDRESS + GEN_PMCON1, gen_pmcon1); + /* Clear the status bits. The RPS field is cleared on a 0 write. */ + write32(PMC_BASE_ADDRESS + GEN_PMCON1, gen_pmcon1 & ~RPS); write32(PMC_BASE_ADDRESS + PRSTS, prsts); } diff --git a/src/soc/intel/baytrail/southcluster.c b/src/soc/intel/baytrail/southcluster.c index a416115b8c..1ee5edc660 100644 --- a/src/soc/intel/baytrail/southcluster.c +++ b/src/soc/intel/baytrail/southcluster.c @@ -20,10 +20,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -117,6 +119,27 @@ static void sc_read_resources(device_t dev) sc_add_io_resources(dev); } +static void sc_rtc_init(void) +{ + uint32_t gen_pmcon1; + int rtc_fail; + struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); + + if (ps != NULL) { + gen_pmcon1 = ps->gen_pmcon1; + } else { + gen_pmcon1 = read32(PMC_BASE_ADDRESS + GEN_PMCON1); + } + + rtc_fail = !!(gen_pmcon1 & RPS); + + if (rtc_fail) { + printk(BIOS_DEBUG, "RTC failure.\n"); + } + + rtc_init(rtc_fail); +} + static void sc_init(device_t dev) { int i; @@ -136,6 +159,8 @@ static void sc_init(device_t dev) /* Route SCI to IRQ9 */ write32(actl, (read32(actl) & ~SCIS_MASK) | SCIS_IRQ9); + + sc_rtc_init(); } /*