From df6b43f61b074a9c8c09471b586561ca35370408 Mon Sep 17 00:00:00 2001 From: Chen Lin Z Date: Tue, 15 Oct 2024 13:51:12 +0800 Subject: PcAtChipsetPkg: Use DV bit to stop the RTC first when changing the time Legacy BIOS design sets only the Update Cycle Inhibit (SET) bit when changing the RTC time. Update Cycle Inhibit Bit may not be supported by the backend device (Common I2C RTC device). It could add Division Chain Select (DV) bit to stop the RTC first (Write to 0x07), Changing the RTC time and then Set the DV bit back. Signed-off-by: Di Zhang --- PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c | 10 ++++++++++ PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h | 1 + 2 files changed, 11 insertions(+) diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c index ff1b019ce2..5505f6da2e 100644 --- a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c +++ b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c @@ -561,6 +561,7 @@ PcRtcSetTime ( { EFI_STATUS Status; EFI_TIME RtcTime; + RTC_REGISTER_A RegisterA; RTC_REGISTER_B RegisterB; UINT32 TimerVar; @@ -638,6 +639,11 @@ PcRtcSetTime ( RegisterB.Bits.Set = 1; RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data); + RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A); + // + // Set Divider in Reset status, RTC stops + // + RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data | RTC_DIV_RESET); // // Store the century value to RTC before converting to BCD format. // @@ -660,6 +666,10 @@ PcRtcSetTime ( RegisterB.Bits.Set = 0; RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data); + // + // Restore Divider status + // + RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data); // // Release RTC Lock. // diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h index 7e0e98fbcc..cff624f96d 100644 --- a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h +++ b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h @@ -70,6 +70,7 @@ extern PC_RTC_MODULE_GLOBALS mModuleGlobal; // // Register A // +#define RTC_DIV_RESET 0x70 typedef struct { UINT8 Rs : 4; // Rate Selection Bits UINT8 Dv : 3; // Divisor -- cgit