From f8a274acf53217129460b5a487396761c174bd54 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Sat, 5 Nov 2016 18:47:51 -0600 Subject: 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 Reviewed-on: https://review.coreboot.org/17370 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth Reviewed-by: Paul Menzel --- src/drivers/pc80/rtc/mc146818rtc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/drivers/pc80') 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); -- cgit v1.2.3