summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorMarshall Dawson <marshalldawson3rd@gmail.com>2016-11-05 18:47:51 -0600
committerMartin Roth <martinroth@google.com>2016-11-17 23:08:59 +0100
commitf8a274acf53217129460b5a487396761c174bd54 (patch)
tree8a83fcef0e7baa711d1ec56adece54dff24a8ad4 /src/drivers
parent5a043fe08d84490356888d236ee7d190aa195217 (diff)
downloadcoreboot-f8a274acf53217129460b5a487396761c174bd54.tar.xz
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>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/pc80/rtc/mc146818rtc.c13
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);