aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/apollolake/include/soc/pm.h5
-rw-r--r--src/soc/intel/apollolake/pmutil.c18
2 files changed, 22 insertions, 1 deletions
diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h
index 34b9f965ae..e8ec645b1f 100644
--- a/src/soc/intel/apollolake/include/soc/pm.h
+++ b/src/soc/intel/apollolake/include/soc/pm.h
@@ -173,8 +173,13 @@
#define COLD_BOOT_STS (1 << 27)
#define COLD_RESET_STS (1 << 26)
#define WARM_RESET_STS (1 << 25)
+#define GLOBAL_RESET_STS (1 << 24)
#define SRS (1 << 20)
+#define MS4V (1 << 18)
#define RPS (1 << 2)
+#define GEN_PMCON1_CLR1_BITS (COLD_BOOT_STS | COLD_RESET_STS | \
+ WARM_RESET_STS | GLOBAL_RESET_STS | \
+ SRS | MS4V)
#define GEN_PMCON2 0x1024
#define GEN_PMCON3 0x1028
# define SLP_S3_ASSERT_WIDTH_SHIFT 10
diff --git a/src/soc/intel/apollolake/pmutil.c b/src/soc/intel/apollolake/pmutil.c
index dbaed70ca3..05590bd8f8 100644
--- a/src/soc/intel/apollolake/pmutil.c
+++ b/src/soc/intel/apollolake/pmutil.c
@@ -232,5 +232,21 @@ int soc_get_rtc_failed(void)
int vbnv_cmos_failed(void)
{
- return rtc_failed(read32((void *)(read_pmc_mmio_bar() + GEN_PMCON1)));
+ uintptr_t pmc_bar = read_pmc_mmio_bar();
+ uint32_t gen_pmcon1 = read32((void *)(pmc_bar + GEN_PMCON1));
+ int rtc_failure = rtc_failed(gen_pmcon1);
+
+ if (rtc_failure) {
+ printk(BIOS_INFO, "RTC failed!\n");
+
+ /* We do not want to write 1 to clear-1 bits. Set them to 0. */
+ gen_pmcon1 &= ~GEN_PMCON1_CLR1_BITS;
+
+ /* RPS is write 0 to clear. */
+ gen_pmcon1 &= ~RPS;
+
+ write32((void *)(pmc_bar + GEN_PMCON1), gen_pmcon1);
+ }
+
+ return rtc_failure;
}