soc/mediatek/mt8196: Fix RTC protection register unlock failure

Add flow of checking RTC unlock protection state after RTC protection
unlock sequence. On failure, retry this flow several times.
Additionally, change the time of CBUSY maximum timeout to 1 second.

BRANCH=rauru
BUG=b:392197855
TEST=emerge-rauru coreboot chromeos-bootimage, when suspend/warmboot/
coldboot, RTC boots and works normally.
After 15 tests, the boot time will increase by approximately 1.3ms from
890.508ms to 891.832ms

Signed-off-by: Shunxi Zhang <ot_shunxi.zhang@mediatek.com>
Change-Id: Id4d537d9c60dc7520c446f1816ef95f9f1e0ff80
Reviewed-on: https://review.coreboot.org/c/coreboot/+/87638
Reviewed-by: Shunxi Zhang <ot_shunxi.zhang@mediatek.corp-partner.google.com>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Reviewed-by: Yidi Lin <yidilin@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Shunxi Zhang 2025-05-09 18:39:36 +08:00 committed by Yidi Lin
commit 5cf460dce9
3 changed files with 49 additions and 14 deletions

View file

@ -49,6 +49,11 @@
#define RG_FQMTR_DATA 0x54a
#define RTC_SPAR_MACRO 0x5d8
#define RTC_SPAR_PROT_STAT_SHIFT 6
#define RTC_SPAR_PROT_STAT_MASK 0x3
#define RTC_PROT_UNLOCK_SUCCESS 0x3
#define RG_FQMTR_CLK_CK_PDN_SET 0x10c
#define RG_FQMTR_CLK_CK_PDN_MASK 0x1
#define RG_FQMTR_CLK_CK_PDN_SHIFT 5

View file

@ -12,6 +12,7 @@
#include <soc/rtc_common.h>
#include <soc/rtc_reg_common.h>
#include <stdbool.h>
#include <timer.h>
#include <types.h>
/* RTC registers */
@ -21,7 +22,7 @@ enum {
RTC_BBPU_RELOAD = BIT(5),
RTC_BBPU_CBUSY = BIT(6),
RTC_CBUSY_TIMEOUT_US = 8000,
RTC_CBUSY_TIMEOUT_US = USECS_PER_SEC,
};
enum {
@ -59,6 +60,7 @@ enum {
#define BBPU_RELOAD_TIMEOUT_US 100000
#define EOSC_CHECK_CLK_TIMEOUT_US 1000000
#define RECOVERY_RETRY_COUNT 3
#define PROT_UNLOCK_RETRY_COUNT 3
struct rtc_clk_freq {
u16 fqm26m_ck;

View file

@ -33,6 +33,34 @@ void rtc_write(u16 addr, u16 wdata)
mt6685_write16(addr, wdata);
}
static u16 rtc_get_prot_stat(void)
{
u16 val;
u16 state = 0;
udelay(100);
rtc_read(RTC_SPAR_MACRO, &val);
state = (val >> RTC_SPAR_PROT_STAT_SHIFT) & RTC_SPAR_PROT_STAT_MASK;
return state;
}
static bool mt6685_writeif_unlock(void)
{
if (!retry(PROT_UNLOCK_RETRY_COUNT,
rtc_writeif_unlock() &&
rtc_get_prot_stat() == RTC_PROT_UNLOCK_SUCCESS)) {
printk(BIOS_ERR, "%s: retry failed!!\n", __func__);
return false;
}
return true;
}
static bool rtc_eosc_check_clock(const struct rtc_clk_freq *result)
{
if ((result->fqm26m_ck >= 3 && result->fqm26m_ck <= 7) &&
@ -319,7 +347,7 @@ static bool rtc_init_after_recovery(void)
/* write powerkeys */
if (!rtc_powerkey_init())
return false;
if (!rtc_writeif_unlock())
if (!mt6685_writeif_unlock())
return false;
if (!rtc_gpio_init())
return false;
@ -332,7 +360,7 @@ static bool rtc_init_after_recovery(void)
if (!rtc_powerkey_init())
return false;
if (!rtc_writeif_unlock())
if (!mt6685_writeif_unlock())
return false;
secure_rtc_init();
@ -366,9 +394,9 @@ static bool rtc_first_boot_init(void)
if (!rtc_write_trigger())
return false;
if (!rtc_writeif_unlock()) {
if (!mt6685_writeif_unlock()) {
printk(BIOS_ERR,
"%s: rtc_writeif_unlock failed after BBPU written\n", __func__);
"%s: mt6685_writeif_unlock failed after BBPU written\n", __func__);
return false;
}
@ -387,9 +415,9 @@ static bool rtc_first_boot_init(void)
return false;
}
if (!rtc_writeif_unlock()) {
if (!mt6685_writeif_unlock()) {
printk(BIOS_ERR,
"%s: rtc_writeif_unlock failed after POWERKEY written\n", __func__);
"%s: mt6685_writeif_unlock failed after POWERKEY written\n", __func__);
return false;
}
@ -402,9 +430,9 @@ static bool rtc_first_boot_init(void)
return false;
}
if (!rtc_writeif_unlock()) {
if (!mt6685_writeif_unlock()) {
printk(BIOS_ERR,
"%s rtc_writeif_unlock failed after BBPU written\n", __func__);
"%s mt6685_writeif_unlock failed after BBPU written\n", __func__);
return false;
}
@ -418,9 +446,9 @@ static bool rtc_first_boot_init(void)
return false;
}
if (!rtc_writeif_unlock()) {
if (!mt6685_writeif_unlock()) {
printk(BIOS_ERR,
"%s rtc_writeif_unlock failed after POWERKEY written\n", __func__);
"%s mt6685_writeif_unlock failed after POWERKEY written\n", __func__);
return false;
}
@ -444,8 +472,8 @@ static void rtc_enable_dcxo(void)
u16 con, osc32con, sec;
/* Unlock for reload */
if (!rtc_writeif_unlock())
printk(BIOS_ERR, "rtc_writeif_unlock() failed\n");
if (!mt6685_writeif_unlock())
printk(BIOS_ERR, "mt6685_writeif_unlock() failed\n");
rtc_read(RTC_BBPU, &rdata);
rtc_write(RTC_BBPU, rdata | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
@ -525,7 +553,7 @@ void rtc_boot(void)
rtc_read(RTC_BBPU, &rtc_bbpu);
rtc_write(RTC_BBPU, rtc_bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
if (!rtc_write_trigger() || !rtc_writeif_unlock()) {
if (!rtc_write_trigger() || !mt6685_writeif_unlock()) {
rtc_recovery_flow();
} else {
rtc_read(RTC_POWERKEY1, &rtc_pwrkey1);