diff options
author | Marshall Dawson <marshalldawson3rd@gmail.com> | 2016-11-05 18:47:51 -0600 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-11-17 23:08:59 +0100 |
commit | f8a274acf53217129460b5a487396761c174bd54 (patch) | |
tree | 8a83fcef0e7baa711d1ec56adece54dff24a8ad4 | |
parent | 5a043fe08d84490356888d236ee7d190aa195217 (diff) |
rtc: Force negative edge on SET after battery replacement
After the RTC coin cell has been replaced, the Update Cycle Inhibit
bit must see at least one low transition to ensure the RTC counts.
The reset value for this bit is undefined. Examples have been observed
where batteries are installed on a manufacturing line, the bit's state
comes up low, but the RTC does not count.
Change-Id: I05f61efdf941297fa9ec90136124b0c8fe0639c6
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/17370
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
-rw-r--r-- | src/drivers/pc80/rtc/mc146818rtc.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/drivers/pc80/rtc/mc146818rtc.c b/src/drivers/pc80/rtc/mc146818rtc.c index c3026a4dbc..adbc611e14 100644 --- a/src/drivers/pc80/rtc/mc146818rtc.c +++ b/src/drivers/pc80/rtc/mc146818rtc.c @@ -95,7 +95,7 @@ static void cmos_set_checksum(int range_start, int range_end, int cks_loc) #ifndef __SMM__ void cmos_init(bool invalid) { - bool cmos_invalid = invalid; + bool cmos_invalid; bool checksum_invalid = false; bool clear_cmos; size_t i; @@ -114,11 +114,11 @@ void cmos_init(bool invalid) printk(BIOS_DEBUG, "RTC Init\n"); - if (IS_ENABLED(CONFIG_USE_OPTION_TABLE)) { - /* See if there has been a CMOS power problem. */ - x = cmos_read(RTC_VALID); - cmos_invalid = !(x & RTC_VRT); + /* See if there has been a CMOS power problem. */ + x = cmos_read(RTC_VALID); + cmos_invalid = !(x & RTC_VRT); + if (IS_ENABLED(CONFIG_USE_OPTION_TABLE)) { /* See if there is a CMOS checksum error */ checksum_invalid = !cmos_checksum_valid(PC_CKS_RANGE_START, PC_CKS_RANGE_END, PC_CKS_LOC); @@ -128,6 +128,9 @@ void cmos_init(bool invalid) clear_cmos = true; } + if (cmos_invalid || invalid) + cmos_write(cmos_read(RTC_CONTROL) | RTC_SET, RTC_CONTROL); + if (invalid || cmos_invalid || checksum_invalid) { if (clear_cmos) { cmos_write(0, 0x01); |