Ran Bi has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/31968
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
mediatek/mt8183: Fix RTC initialization flow
1. fix RTC initialization flow 2. fix RTC lpd settings
BUG=b:80501386 BRANCH=none TEST=Boots correctly on Kukui
Change-Id: I6f26edd6699c2f6d9af80c285b70742b44407136 Signed-off-by: Ran Bi ran.bi@mediatek.com --- M src/soc/mediatek/common/include/soc/rtc_common.h M src/soc/mediatek/common/rtc.c M src/soc/mediatek/mt8173/include/soc/rtc.h M src/soc/mediatek/mt8173/rtc.c M src/soc/mediatek/mt8183/include/soc/rtc.h M src/soc/mediatek/mt8183/rtc.c 6 files changed, 77 insertions(+), 35 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/31968/1
diff --git a/src/soc/mediatek/common/include/soc/rtc_common.h b/src/soc/mediatek/common/include/soc/rtc_common.h index 41e772e..b652ad5 100644 --- a/src/soc/mediatek/common/include/soc/rtc_common.h +++ b/src/soc/mediatek/common/include/soc/rtc_common.h @@ -99,7 +99,6 @@ int rtc_writeif_unlock(void); void rtc_xosc_write(u16 val); int rtc_reg_init(void); -u8 rtc_check_state(void); void rtc_boot_common(void);
#endif /* SOC_MEDIATEK_RTC_COMMON_H */ diff --git a/src/soc/mediatek/common/rtc.c b/src/soc/mediatek/common/rtc.c index fd40cb5..647ae1e 100644 --- a/src/soc/mediatek/common/rtc.c +++ b/src/soc/mediatek/common/rtc.c @@ -137,7 +137,7 @@ return rtc_write_trigger(); }
-u8 rtc_check_state(void) +static u8 rtc_check_state(void) { u16 con; u16 pwrky1; @@ -147,6 +147,9 @@ pwrap_read(RTC_POWERKEY1, &pwrky1); pwrap_read(RTC_POWERKEY2, &pwrky2);
+ printk(BIOS_INFO, "[RTC] con = %x, pwrkey1 = %x, pwrkey2 = %x\n", + con, pwrky1, pwrky2); + if (con & RTC_CON_LPSTA_RAW) return RTC_STATE_INIT;
diff --git a/src/soc/mediatek/mt8173/include/soc/rtc.h b/src/soc/mediatek/mt8173/include/soc/rtc.h index fe5cbac..0ee944a 100644 --- a/src/soc/mediatek/mt8173/include/soc/rtc.h +++ b/src/soc/mediatek/mt8173/include/soc/rtc.h @@ -112,7 +112,7 @@
/* external API */ void rtc_osc_init(void); -int rtc_init(u8 recover); +bool rtc_init(u8 recover); void rtc_boot(void);
#endif /* SOC_MEDIATEK_MT8173_RTC_H */ diff --git a/src/soc/mediatek/mt8173/rtc.c b/src/soc/mediatek/mt8173/rtc.c index 5b7d486..056c051 100644 --- a/src/soc/mediatek/mt8173/rtc.c +++ b/src/soc/mediatek/mt8173/rtc.c @@ -71,15 +71,15 @@ }
/* rtc init check */ -int rtc_init(u8 recover) +bool rtc_init(u8 recover) { printk(BIOS_INFO, "[RTC] %s recovery: %d\n", __func__, recover);
if (!rtc_writeif_unlock()) - return 0; + return false;
if (!rtc_gpio_init()) - return 0; + return false;
/* Use SW to detect 32K mode instead of HW */ if (recover) @@ -94,7 +94,7 @@ pwrap_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); pwrap_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); if (!rtc_write_trigger()) - return 0; + return false;
if (recover) pwrap_write_field(PMIC_RG_CHRSTATUS, 0, 0x4, 9); @@ -102,11 +102,11 @@ rtc_xosc_write(0);
if (!rtc_reg_init()) - return 0; + return false; if (!rtc_lpd_init()) - return 0; + return false;
- return 1; + return true; }
/* enable rtc bbpu */ diff --git a/src/soc/mediatek/mt8183/include/soc/rtc.h b/src/soc/mediatek/mt8183/include/soc/rtc.h index 08ebe98..b0c1d4a 100644 --- a/src/soc/mediatek/mt8183/include/soc/rtc.h +++ b/src/soc/mediatek/mt8183/include/soc/rtc.h @@ -106,6 +106,14 @@ RTC_REG_XOSC32_ENB = 1 << 15 };
+enum { + RTC_LPD_OPT_XOSC_AND_EOSC_LPD = 0 << 13, + RTC_LPD_OPT_EOSC_LPD = 1 << 13, + RTC_LPD_OPT_XOSC_LPD = 2 << 13, + RTC_LPD_OPT_F32K_CK_ALIVE = 3 << 13, + RTC_LPD_OPT_MASK = 3 << 13 +}; + /* PMIC TOP Register Definition */ enum { PMIC_RG_SCK_TOP_CON0 = 0x050C @@ -142,7 +150,7 @@ /* external API */ void rtc_bbpu_power_on(void); void rtc_osc_init(void); -int rtc_init(u8 recover); +bool rtc_init(u8 recover); void rtc_boot(void);
#endif /* SOC_MEDIATEK_MT8183_RTC_H */ diff --git a/src/soc/mediatek/mt8183/rtc.c b/src/soc/mediatek/mt8183/rtc.c index d67315b..69e4f0c 100644 --- a/src/soc/mediatek/mt8183/rtc.c +++ b/src/soc/mediatek/mt8183/rtc.c @@ -64,7 +64,8 @@
/* Export 32K clock RTC_32K2V8 */ pwrap_read(RTC_CON, &con); - con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_EOSC32_LPEN); + con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_EOSC32_LPEN + | RTC_CON_XOSC32_LPEN); con |= (RTC_CON_GPEN | RTC_CON_GOE); con &= ~(RTC_CON_F32KOB); pwrap_write(RTC_CON, con); @@ -81,9 +82,17 @@ /* low power detect setting */ static int rtc_lpd_init(void) { - u16 con; + u16 con, sec;
- con = pwrap_read(RTC_CON, &con) | RTC_CON_XOSC32_LPEN; + /* set RTC_LPD_OPT */ + pwrap_read(RTC_AL_SEC, &sec); + sec |= RTC_LPD_OPT_F32K_CK_ALIVE; + pwrap_write(RTC_AL_SEC, sec); + if (!rtc_write_trigger()) + return 0; + + pwrap_read(RTC_CON, &con); + con |= RTC_CON_XOSC32_LPEN; con &= ~RTC_CON_LPRST; pwrap_write(RTC_CON, con); if (!rtc_write_trigger()) @@ -99,7 +108,8 @@ if (!rtc_write_trigger()) return 0;
- con = pwrap_read(RTC_CON, &con) | RTC_CON_EOSC32_LPEN; + pwrap_read(RTC_CON, &con); + con |= RTC_CON_EOSC32_LPEN; con &= ~RTC_CON_LPRST; pwrap_write(RTC_CON, con); if (!rtc_write_trigger()) @@ -115,6 +125,18 @@ if (!rtc_write_trigger()) return 0;
+ pwrap_read(RTC_CON, &con); + con &= ~RTC_CON_XOSC32_LPEN; + pwrap_write(RTC_CON, con); + + /* set RTC_LPD_OPT */ + pwrap_read(RTC_AL_SEC, &sec); + sec &= ~RTC_LPD_OPT_MASK; + sec |= RTC_LPD_OPT_EOSC_LPD; + pwrap_write(RTC_AL_SEC, sec); + if (!rtc_write_trigger()) + return 0; + return 1; }
@@ -142,36 +164,46 @@ }
/* rtc init check */ -int rtc_init(u8 recover) +bool rtc_init(u8 recover) { printk(BIOS_INFO, "[RTC] %s recovery: %d\n", __func__, recover);
- if (!rtc_writeif_unlock()) - return 0; - - if (!rtc_gpio_init()) - return 0; - - /* using dcxo 32K clock */ - rtc_enable_dcxo(); - - if (recover) - mdelay(20); - /* write powerkeys */ pwrap_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); pwrap_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); if (!rtc_write_trigger()) - return 0; + return false; + + if (!rtc_writeif_unlock()) + return false; + + /* using dcxo 32K clock */ + rtc_enable_dcxo(); + if (recover) + mdelay(20); + + if (!rtc_gpio_init()) + return false; + + if (!rtc_hw_init()) + return false;
if (!rtc_reg_init()) - return 0; - if (!rtc_lpd_init()) - return 0; - if (!rtc_hw_init()) - return 0; + return false;
- return 1; + if (!rtc_lpd_init()) + return false; + + /* write powerkeys again to enable lpd */ + pwrap_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); + pwrap_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); + if (!rtc_write_trigger()) + return false; + + if (!rtc_writeif_unlock()) + return false; + + return true; }
/* enable rtc bbpu */
You-Cheng Syu has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 1: Code-Review+1
Hung-Te Lin has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 1:
(2 comments)
https://review.coreboot.org/#/c/31968/1//COMMIT_MSG Commit Message:
https://review.coreboot.org/#/c/31968/1//COMMIT_MSG@9 PS1, Line 9: 1. fix RTC initialization flow : 2. fix RTC lpd settings If there's a specific issue describing details (the 80501386 below is for tracking all firmware changes), we should document here what we are solving(what you see without this patch), how it needs to be fixed, and how it is verified.
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/common/rtc.c File src/soc/mediatek/common/rtc.c:
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/common/rtc.c@150 PS1, Line 150: printk(BIOS_INFO, "[RTC] con = %x, pwrkey1 = %x, pwrkey2 = %x\n", : con, pwrky1, pwrky2); Is this for your local debugging, or it is really helpful to always print this?
YH Lin has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/#/c/31968/1//COMMIT_MSG Commit Message:
https://review.coreboot.org/#/c/31968/1//COMMIT_MSG@12 PS1, Line 12: 80501386 127405695?
Daisuke Nojiri has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 1: Code-Review-1
(7 comments)
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c File src/soc/mediatek/mt8183/rtc.c:
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@25 PS1, Line 25: void Why are we not handling any errors?
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@94 PS1, Line 94: pwrap_read(RTC_CON, &con); : con |= RTC_CON_XOSC32_LPEN; : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con |= RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : pwrap_read(RTC_CON, &con); : con |= RTC_CON_EOSC32_LPEN; : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con |= RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; Can you do this in a sub-routine to avoid repetition? The only difference is XOSC32 and EOSC32. Also, what does this RTC_CON_LPRST toggle do? More comments are appreciated.
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@128 PS1, Line 128: pwrap_read Why do we assume this is always successful?
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@136 PS1, Line 136: pwrap_write This one too and all the calls in the entire file.
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@167 PS1, Line 167: bool I suggest we return int here as an error code and print it in mediatek/common/rtc.c or add printk for each 'return false' below. That way, at least we can tell how rtc_init failed (or succeeded). Currently, all the failures are seen as 'recovery' and the result of the recovery run is invisible.
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@197 PS1, Line 197: write powerkeys again to enable lpd How does writing powerkeys enable LPD? More comments are appreciated. Was it the source of the bug that rtc_lpd_init wasn't called before powerkeys?
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@203 PS1, Line 203: rtc_writeif_unlock Why do you have to unlock again?
Hello Julius Werner, Daisuke Nojiri, You-Cheng Syu, Tristan Hsieh, Hung-Te Lin, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/31968
to look at the new patch set (#2).
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
mediatek/mt8183: Fix RTC initialization flow
1. Fix RTC lpd settings. Rewrite powerkeys after lpd init to enable low power detect function. 2. Rearrange RTC initialization flow. 3. Add return status for rtc_init. 4. Add log if calling pwrap_write or pwrap_read fail.
BUG=b:127405695 BRANCH=none TEST=Boots correctly on Kukui
Change-Id: I6f26edd6699c2f6d9af80c285b70742b44407136 Signed-off-by: Ran Bi ran.bi@mediatek.com --- M src/soc/mediatek/common/include/soc/rtc_common.h M src/soc/mediatek/common/rtc.c M src/soc/mediatek/mt8173/include/soc/rtc.h M src/soc/mediatek/mt8173/rtc.c M src/soc/mediatek/mt8183/include/soc/rtc.h M src/soc/mediatek/mt8183/rtc.c 6 files changed, 289 insertions(+), 158 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/31968/2
Hello Julius Werner, Daisuke Nojiri, You-Cheng Syu, Tristan Hsieh, Hung-Te Lin, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/31968
to look at the new patch set (#3).
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
mediatek/mt8183: Fix RTC initialization flow
1. Fix RTC lpd settings. Rewrite powerkeys after lpd init to enable low power detect function. 2. Rearrange RTC initialization flow. 3. Add return status for rtc_init. 4. Add log if calling pwrap_write or pwrap_read fail.
BUG=b:127405695 BRANCH=none TEST=Boots correctly on Kukui
Change-Id: I6f26edd6699c2f6d9af80c285b70742b44407136 Signed-off-by: Ran Bi ran.bi@mediatek.com --- M src/soc/mediatek/common/include/soc/rtc_common.h M src/soc/mediatek/common/rtc.c M src/soc/mediatek/mt8173/include/soc/rtc.h M src/soc/mediatek/mt8173/rtc.c M src/soc/mediatek/mt8183/include/soc/rtc.h M src/soc/mediatek/mt8183/rtc.c 6 files changed, 299 insertions(+), 162 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/31968/3
Ran Bi has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 3:
(10 comments)
https://review.coreboot.org/#/c/31968/1//COMMIT_MSG Commit Message:
https://review.coreboot.org/#/c/31968/1//COMMIT_MSG@9 PS1, Line 9: 1. fix RTC initialization flow : 2. fix RTC lpd settings
If there's a specific issue describing details (the 80501386 below is for tracking all firmware chan […]
Done
https://review.coreboot.org/#/c/31968/1//COMMIT_MSG@12 PS1, Line 12: 80501386
127405695?
Done
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/common/rtc.c File src/soc/mediatek/common/rtc.c:
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/common/rtc.c@150 PS1, Line 150: printk(BIOS_INFO, "[RTC] con = %x, pwrkey1 = %x, pwrkey2 = %x\n", : con, pwrky1, pwrky2);
Is this for your local debugging, or it is really helpful to always print this?
This log is helpful to get re-init reason. So I would prefer to leave.
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c File src/soc/mediatek/mt8183/rtc.c:
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@25 PS1, Line 25: void
Why are we not handling any errors?
Done
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@94 PS1, Line 94: pwrap_read(RTC_CON, &con); : con |= RTC_CON_XOSC32_LPEN; : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con |= RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : pwrap_read(RTC_CON, &con); : con |= RTC_CON_EOSC32_LPEN; : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con |= RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0; : : con &= ~RTC_CON_LPRST; : pwrap_write(RTC_CON, con); : if (!rtc_write_trigger()) : return 0;
Can you do this in a sub-routine to avoid repetition? The only difference is XOSC32 and EOSC32. […]
Done
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@128 PS1, Line 128: pwrap_read
Why do we assume this is always successful?
Add log if pwrap_read or pwrap_write fail. Because pwrap API is RTC basic API. RTC cannot handle this error if pwrap API fail. The only way is print log or assert.
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@136 PS1, Line 136: pwrap_write
This one too and all the calls in the entire file.
Done
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@167 PS1, Line 167: bool
I suggest we return int here as an error code and print it in mediatek/common/rtc. […]
Done
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@197 PS1, Line 197: write powerkeys again to enable lpd
How does writing powerkeys enable LPD? More comments are appreciated. […]
Yes, the reason of the bug is not write powerkeys again after lpd init.
https://review.coreboot.org/#/c/31968/1/src/soc/mediatek/mt8183/rtc.c@203 PS1, Line 203: rtc_writeif_unlock
Why do you have to unlock again?
Removed
Daisuke Nojiri has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 3:
(3 comments)
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8173/include/soc/... File src/soc/mediatek/mt8173/include/soc/rtc.h:
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8173/include/soc/... PS3, Line 81: 0 Is this intended? If so, please explain in the patch description.
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/include/soc/... File src/soc/mediatek/mt8183/include/soc/rtc.h:
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/include/soc/... PS3, Line 80: 0 This one too
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/rtc.c File src/soc/mediatek/mt8183/rtc.c:
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/rtc.c@177 PS3, Line 177: if (!rtc_write_trigger()) : return false; : : return true; return rtc_write_trigger();
Hello Julius Werner, Daisuke Nojiri, You-Cheng Syu, Tristan Hsieh, Hung-Te Lin, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/31968
to look at the new patch set (#4).
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
mediatek/mt8183: Fix RTC initialization flow
1. Fix RTC lpd settings. Rewrite powerkeys after lpd init to enable low power detect function. 2. Rearrange RTC initialization flow. 3. Add return status for rtc_init. 4. Add log if calling pwrap_write or pwrap_read fail. 5. Increase timeout time to resolve unexpected timeout.
BUG=b:127405695 BRANCH=none TEST=Boots correctly on Kukui
Change-Id: I6f26edd6699c2f6d9af80c285b70742b44407136 Signed-off-by: Ran Bi ran.bi@mediatek.com --- M src/soc/mediatek/common/include/soc/rtc_common.h M src/soc/mediatek/common/rtc.c M src/soc/mediatek/mt8173/include/soc/rtc.h M src/soc/mediatek/mt8173/rtc.c M src/soc/mediatek/mt8183/include/soc/rtc.h M src/soc/mediatek/mt8183/rtc.c 6 files changed, 296 insertions(+), 162 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/31968/4
Ran Bi has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 4:
(3 comments)
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8173/include/soc/... File src/soc/mediatek/mt8173/include/soc/rtc.h:
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8173/include/soc/... PS3, Line 81: 0
Is this intended? If so, please explain in the patch description.
Done
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/include/soc/... File src/soc/mediatek/mt8183/include/soc/rtc.h:
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/include/soc/... PS3, Line 80: 0
This one too
Done
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/rtc.c File src/soc/mediatek/mt8183/rtc.c:
https://review.coreboot.org/#/c/31968/3/src/soc/mediatek/mt8183/rtc.c@177 PS3, Line 177: if (!rtc_write_trigger()) : return false; : : return true;
return rtc_write_trigger();
Done
Daisuke Nojiri has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
Patch Set 4: Code-Review+2
Patrick Georgi has submitted this change and it was merged. ( https://review.coreboot.org/c/coreboot/+/31968 )
Change subject: mediatek/mt8183: Fix RTC initialization flow ......................................................................
mediatek/mt8183: Fix RTC initialization flow
1. Fix RTC lpd settings. Rewrite powerkeys after lpd init to enable low power detect function. 2. Rearrange RTC initialization flow. 3. Add return status for rtc_init. 4. Add log if calling pwrap_write or pwrap_read fail. 5. Increase timeout time to resolve unexpected timeout.
BUG=b:127405695 BRANCH=none TEST=Boots correctly on Kukui
Change-Id: I6f26edd6699c2f6d9af80c285b70742b44407136 Signed-off-by: Ran Bi ran.bi@mediatek.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/31968 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Daisuke Nojiri dnojiri@chromium.org --- M src/soc/mediatek/common/include/soc/rtc_common.h M src/soc/mediatek/common/rtc.c M src/soc/mediatek/mt8173/include/soc/rtc.h M src/soc/mediatek/mt8173/rtc.c M src/soc/mediatek/mt8183/include/soc/rtc.h M src/soc/mediatek/mt8183/rtc.c 6 files changed, 296 insertions(+), 162 deletions(-)
Approvals: build bot (Jenkins): Verified Daisuke Nojiri: Looks good to me, approved
diff --git a/src/soc/mediatek/common/include/soc/rtc_common.h b/src/soc/mediatek/common/include/soc/rtc_common.h index 41e772e..e3c231b 100644 --- a/src/soc/mediatek/common/include/soc/rtc_common.h +++ b/src/soc/mediatek/common/include/soc/rtc_common.h @@ -22,6 +22,11 @@ #include <delay.h> #include <rtc.h> #include <timer.h> +#include <soc/pmic_wrap_common.h> + +#define RTCTAG "[RTC]" +#define rtc_info(fmt, arg ...) printk(BIOS_INFO, RTCTAG "%s,%d: " fmt, \ + __func__, __LINE__, ## arg)
/* * Default values for RTC initialization @@ -93,13 +98,46 @@ RTC_STATE_INIT = 2 };
+/* RTC error code */ +enum { + RTC_STATUS_OK = 0, + RTC_STATUS_POWERKEY_INIT_FAIL, + RTC_STATUS_WRITEIF_UNLOCK_FAIL, + RTC_STATUS_OSC_SETTING_FAIL, + RTC_STATUS_GPIO_INIT_FAIL, + RTC_STATUS_HW_INIT_FAIL, + RTC_STATUS_REG_INIT_FAIL, + RTC_STATUS_LPD_INIT_FAIL +}; + /* external API */ int rtc_busy_wait(void); int rtc_write_trigger(void); int rtc_writeif_unlock(void); -void rtc_xosc_write(u16 val); +int rtc_xosc_write(u16 val); int rtc_reg_init(void); -u8 rtc_check_state(void); void rtc_boot_common(void);
+static inline s32 rtc_read(u16 addr, u16 *rdata) +{ + s32 ret; + + ret = pwrap_read(addr, rdata); + if (ret < 0) + rtc_info("pwrap_read fail: ret=%d\n", ret); + + return ret; +} + +static inline s32 rtc_write(u16 addr, u16 wdata) +{ + s32 ret; + + ret = pwrap_write(addr, wdata); + if (ret < 0) + rtc_info("pwrap_write fail: ret=%d\n", ret); + + return ret; +} + #endif /* SOC_MEDIATEK_RTC_COMMON_H */ diff --git a/src/soc/mediatek/common/rtc.c b/src/soc/mediatek/common/rtc.c index fd40cb5..3b1a600 100644 --- a/src/soc/mediatek/common/rtc.c +++ b/src/soc/mediatek/common/rtc.c @@ -26,10 +26,10 @@ stopwatch_init_usecs_expire(&sw, RTC_CBUSY_TIMEOUT_US);
do { - pwrap_read(RTC_BBPU, &bbpu); + rtc_read(RTC_BBPU, &bbpu); /* Time > 1sec, time out and set recovery mode enable.*/ if (stopwatch_expired(&sw)) { - printk(BIOS_INFO, "[RTC] BBPU CBUSY time out !!\n"); + rtc_info("BBPU CBUSY time out !!\n"); return 0; } } while (bbpu & RTC_BBPU_CBUSY); @@ -39,17 +39,17 @@
int rtc_write_trigger(void) { - pwrap_write(RTC_WRTGR, 1); + rtc_write(RTC_WRTGR, 1); return rtc_busy_wait(); }
/* unlock rtc write interface */ int rtc_writeif_unlock(void) { - pwrap_write(RTC_PROT, RTC_PROT_UNLOCK1); + rtc_write(RTC_PROT, RTC_PROT_UNLOCK1); if (!rtc_write_trigger()) return 0; - pwrap_write(RTC_PROT, RTC_PROT_UNLOCK2); + rtc_write(RTC_PROT, RTC_PROT_UNLOCK2); if (!rtc_write_trigger()) return 0;
@@ -67,39 +67,40 @@ { u16 value;
- pwrap_read(RTC_TC_SEC, &value); + rtc_read(RTC_TC_SEC, &value); time->sec = value; - pwrap_read(RTC_TC_MIN, &value); + rtc_read(RTC_TC_MIN, &value); time->min = value; - pwrap_read(RTC_TC_HOU, &value); + rtc_read(RTC_TC_HOU, &value); time->hour = value; - pwrap_read(RTC_TC_DOM, &value); + rtc_read(RTC_TC_DOM, &value); time->mday = value; - pwrap_read(RTC_TC_MTH, &value); + rtc_read(RTC_TC_MTH, &value); time->mon = value; - pwrap_read(RTC_TC_YEA, &value); + rtc_read(RTC_TC_YEA, &value); time->year = (value + RTC_MIN_YEAR_OFFSET) % 100;
return 0; }
/* set rtc xosc setting */ -void rtc_xosc_write(u16 val) +int rtc_xosc_write(u16 val) { u16 bbpu;
- pwrap_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1); + rtc_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1); udelay(200); - pwrap_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2); + rtc_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2); udelay(200);
- pwrap_write(RTC_OSC32CON, val); + rtc_write(RTC_OSC32CON, val); udelay(200);
- pwrap_read(RTC_BBPU, &bbpu); + rtc_read(RTC_BBPU, &bbpu); bbpu |= RTC_BBPU_KEY | RTC_BBPU_RELOAD; - pwrap_write(RTC_BBPU, bbpu); - rtc_write_trigger(); + rtc_write(RTC_BBPU, bbpu); + + return rtc_write_trigger(); }
/* initialize rtc related registers */ @@ -107,45 +108,47 @@ { u16 irqsta;
- pwrap_write(RTC_IRQ_EN, 0); - pwrap_write(RTC_CII_EN, 0); - pwrap_write(RTC_AL_MASK, 0); - pwrap_write(RTC_AL_YEA, 1970 - RTC_MIN_YEAR); - pwrap_write(RTC_AL_MTH, 1); - pwrap_write(RTC_AL_DOM, 1); - pwrap_write(RTC_AL_DOW, 4); - pwrap_write(RTC_AL_HOU, 0); - pwrap_write(RTC_AL_MIN, 0); - pwrap_write(RTC_AL_SEC, 0); + rtc_write(RTC_IRQ_EN, 0); + rtc_write(RTC_CII_EN, 0); + rtc_write(RTC_AL_MASK, 0); + rtc_write(RTC_AL_YEA, 1970 - RTC_MIN_YEAR); + rtc_write(RTC_AL_MTH, 1); + rtc_write(RTC_AL_DOM, 1); + rtc_write(RTC_AL_DOW, 4); + rtc_write(RTC_AL_HOU, 0); + rtc_write(RTC_AL_MIN, 0); + rtc_write(RTC_AL_SEC, 0);
- pwrap_write(RTC_DIFF, 0); - pwrap_write(RTC_CALI, 0); + rtc_write(RTC_DIFF, 0); + rtc_write(RTC_CALI, 0); if (!rtc_write_trigger()) return 0;
- pwrap_read(RTC_IRQ_STA, &irqsta); /* read clear */ + rtc_read(RTC_IRQ_STA, &irqsta); /* read clear */
/* init time counters after resetting RTC_DIFF and RTC_CALI */ - pwrap_write(RTC_TC_YEA, RTC_DEFAULT_YEA - RTC_MIN_YEAR); - pwrap_write(RTC_TC_MTH, RTC_DEFAULT_MTH); - pwrap_write(RTC_TC_DOM, RTC_DEFAULT_DOM); - pwrap_write(RTC_TC_DOW, RTC_DEFAULT_DOW); - pwrap_write(RTC_TC_HOU, 0); - pwrap_write(RTC_TC_MIN, 0); - pwrap_write(RTC_TC_SEC, 0); + rtc_write(RTC_TC_YEA, RTC_DEFAULT_YEA - RTC_MIN_YEAR); + rtc_write(RTC_TC_MTH, RTC_DEFAULT_MTH); + rtc_write(RTC_TC_DOM, RTC_DEFAULT_DOM); + rtc_write(RTC_TC_DOW, RTC_DEFAULT_DOW); + rtc_write(RTC_TC_HOU, 0); + rtc_write(RTC_TC_MIN, 0); + rtc_write(RTC_TC_SEC, 0);
return rtc_write_trigger(); }
-u8 rtc_check_state(void) +static u8 rtc_check_state(void) { u16 con; u16 pwrky1; u16 pwrky2;
- pwrap_read(RTC_CON, &con); - pwrap_read(RTC_POWERKEY1, &pwrky1); - pwrap_read(RTC_POWERKEY2, &pwrky2); + rtc_read(RTC_CON, &con); + rtc_read(RTC_POWERKEY1, &pwrky1); + rtc_read(RTC_POWERKEY2, &pwrky2); + + rtc_info("con=%x, pwrkey1=%x, pwrkey2=%x\n", con, pwrky1, pwrky2);
if (con & RTC_CON_LPSTA_RAW) return RTC_STATE_INIT; @@ -180,15 +183,14 @@ break; case RTC_STATE_INIT: default: - if (!rtc_init(0)) + if (rtc_init(0)) rtc_init(1); break; }
- pwrap_read(RTC_IRQ_STA, &irqsta); /* Read clear */ - pwrap_read(RTC_BBPU, &bbpu); - pwrap_read(RTC_CON, &con); + rtc_read(RTC_IRQ_STA, &irqsta); /* Read clear */ + rtc_read(RTC_BBPU, &bbpu); + rtc_read(RTC_CON, &con);
- printk(BIOS_INFO, "[RTC] irqsta = %x", irqsta); - printk(BIOS_INFO, " bbpu = %#x, con = %#x\n", bbpu, con); + rtc_info("irqsta=%x, bbpu=%x, con=%x\n", irqsta, bbpu, con); } diff --git a/src/soc/mediatek/mt8173/include/soc/rtc.h b/src/soc/mediatek/mt8173/include/soc/rtc.h index fe5cbac..709b611 100644 --- a/src/soc/mediatek/mt8173/include/soc/rtc.h +++ b/src/soc/mediatek/mt8173/include/soc/rtc.h @@ -78,7 +78,7 @@ RTC_BBPU_RELOAD = 1U << 5, RTC_BBPU_CBUSY = 1U << 6,
- RTC_CBUSY_TIMEOUT_US = 800 + RTC_CBUSY_TIMEOUT_US = 8000 };
enum { diff --git a/src/soc/mediatek/mt8173/rtc.c b/src/soc/mediatek/mt8173/rtc.c index 5b7d486..ca81d26 100644 --- a/src/soc/mediatek/mt8173/rtc.c +++ b/src/soc/mediatek/mt8173/rtc.c @@ -30,11 +30,11 @@ MT6391_GPIO_PULL_DOWN); /* RTC_32K1V8 */
/* Export 32K clock RTC_32K2V8 */ - pwrap_read(RTC_CON, &con); + rtc_read(RTC_CON, &con); con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_LPEN); con |= (RTC_CON_GPEN | RTC_CON_GOE); con &= ~(RTC_CON_F32KOB); - pwrap_write(RTC_CON, con); + rtc_write(RTC_CON, con); return rtc_write_trigger(); }
@@ -46,8 +46,8 @@ /* enable 32K export */ rtc_gpio_init();
- pwrap_write(PMIC_RG_TOP_CKTST2, 0x0); - pwrap_read(RTC_OSC32CON, &con); + rtc_write(PMIC_RG_TOP_CKTST2, 0x0); + rtc_read(RTC_OSC32CON, &con); if ((con & 0x1f) != 0x0) /* check XOSCCALI */ rtc_xosc_write(0x3); } @@ -73,40 +73,62 @@ /* rtc init check */ int rtc_init(u8 recover) { - printk(BIOS_INFO, "[RTC] %s recovery: %d\n", __func__, recover); + int ret;
- if (!rtc_writeif_unlock()) - return 0; + rtc_info("recovery: %d\n", recover);
- if (!rtc_gpio_init()) - return 0; + if (!rtc_writeif_unlock()) { + ret = -RTC_STATUS_WRITEIF_UNLOCK_FAIL; + goto err; + } + + if (!rtc_gpio_init()) { + ret = -RTC_STATUS_GPIO_INIT_FAIL; + goto err; + }
/* Use SW to detect 32K mode instead of HW */ if (recover) pwrap_write_field(PMIC_RG_CHRSTATUS, 0x4, 0x1, 9);
- rtc_xosc_write(0x3); + if (!rtc_xosc_write(0x3)) { + ret = -RTC_STATUS_OSC_SETTING_FAIL; + goto err; + }
if (recover) mdelay(1000);
/* write powerkeys */ - pwrap_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); - pwrap_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); - if (!rtc_write_trigger()) - return 0; + rtc_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); + rtc_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); + if (!rtc_write_trigger()) { + ret = -RTC_STATUS_POWERKEY_INIT_FAIL; + goto err; + }
if (recover) pwrap_write_field(PMIC_RG_CHRSTATUS, 0, 0x4, 9);
- rtc_xosc_write(0); + if (!rtc_xosc_write(0)) { + ret = -RTC_STATUS_OSC_SETTING_FAIL; + goto err; + }
- if (!rtc_reg_init()) - return 0; - if (!rtc_lpd_init()) - return 0; + if (!rtc_reg_init()) { + ret = -RTC_STATUS_REG_INIT_FAIL; + goto err; + }
- return 1; + if (!rtc_lpd_init()) { + ret = -RTC_STATUS_LPD_INIT_FAIL; + goto err; + } + + return RTC_STATUS_OK; +err: + rtc_info("init fail: ret=%d\n", ret); + return ret; }
/* enable rtc bbpu */ @@ -117,9 +139,9 @@
/* pull PWRBB high */ bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_BBPU | RTC_BBPU_PWREN; - pwrap_write(RTC_BBPU, bbpu); + rtc_write(RTC_BBPU, bbpu); ret = rtc_write_trigger(); - printk(BIOS_INFO, "[RTC] %s rtc_write_trigger=%d\n", __func__, ret); + rtc_info("rtc_write_trigger=%d\n", ret);
/* enable DCXO to transform external 32KHz clock to 26MHz clock directly sent to SoC */ @@ -129,8 +151,8 @@ pwrap_write_field(PMIC_RG_DCXO_CON2, BIT(1) | BIT(3) | BIT(5) | BIT(6), 0, 0);
- pwrap_read(RTC_BBPU, &bbpu); - printk(BIOS_INFO, "[RTC] %s done BBPU=%#x\n", __func__, bbpu); + rtc_read(RTC_BBPU, &bbpu); + rtc_info("done BBPU=%#x\n", bbpu);
/* detect hw clock done,close RG_RTC_75K_PDN for low power setting. */ pwrap_write_field(PMIC_RG_TOP_CKPDN2, 0x1, 0, 14); @@ -139,8 +161,8 @@ /* the rtc boot flow entry */ void rtc_boot(void) { - pwrap_write(PMIC_RG_TOP_CKPDN, 0); - pwrap_write(PMIC_RG_TOP_CKPDN2, 0); + rtc_write(PMIC_RG_TOP_CKPDN, 0); + rtc_write(PMIC_RG_TOP_CKPDN2, 0);
rtc_boot_common(); rtc_bbpu_power_on(); diff --git a/src/soc/mediatek/mt8183/include/soc/rtc.h b/src/soc/mediatek/mt8183/include/soc/rtc.h index 08ebe98..3d115fe 100644 --- a/src/soc/mediatek/mt8183/include/soc/rtc.h +++ b/src/soc/mediatek/mt8183/include/soc/rtc.h @@ -77,7 +77,7 @@ RTC_BBPU_RELOAD = 1U << 5, RTC_BBPU_CBUSY = 1U << 6,
- RTC_CBUSY_TIMEOUT_US = 800 + RTC_CBUSY_TIMEOUT_US = 8000 };
enum { @@ -106,6 +106,14 @@ RTC_REG_XOSC32_ENB = 1 << 15 };
+enum { + RTC_LPD_OPT_XOSC_AND_EOSC_LPD = 0 << 13, + RTC_LPD_OPT_EOSC_LPD = 1 << 13, + RTC_LPD_OPT_XOSC_LPD = 2 << 13, + RTC_LPD_OPT_F32K_CK_ALIVE = 3 << 13, + RTC_LPD_OPT_MASK = 3 << 13 +}; + /* PMIC TOP Register Definition */ enum { PMIC_RG_SCK_TOP_CON0 = 0x050C diff --git a/src/soc/mediatek/mt8183/rtc.c b/src/soc/mediatek/mt8183/rtc.c index d67315b..df7501a 100644 --- a/src/soc/mediatek/mt8183/rtc.c +++ b/src/soc/mediatek/mt8183/rtc.c @@ -22,31 +22,37 @@ #define RTC_GPIO_USER_MASK ((1 << 13) - (1 << 8))
/* initialize rtc setting of using dcxo clock */ -static void rtc_enable_dcxo(void) +static int rtc_enable_dcxo(void) { u16 bbpu, con, osc32con, sec;
- pwrap_read(RTC_BBPU, &bbpu); - pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD); + rtc_read(RTC_BBPU, &bbpu); + rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD); rtc_write_trigger();
mdelay(1); - if (!rtc_writeif_unlock()) /* Unlock for reload */ - printk(BIOS_INFO, - "[RTC] %s rtc_writeif_unlock() fail\n", __func__); + if (!rtc_writeif_unlock()) { /* Unlock for reload */ + rtc_info("rtc_writeif_unlock() fail\n"); + return 0; + }
- pwrap_read(RTC_OSC32CON, &osc32con); - rtc_xosc_write((osc32con & ~RTC_EMBCK_SRC_SEL) - | RTC_XOSC32_ENB | RTC_REG_XOSC32_ENB); - pwrap_read(RTC_BBPU, &bbpu); - pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD); + rtc_read(RTC_OSC32CON, &osc32con); + osc32con &= ~RTC_EMBCK_SRC_SEL; + osc32con |= RTC_XOSC32_ENB | RTC_REG_XOSC32_ENB; + if (!rtc_xosc_write(osc32con)) { + rtc_info("rtc_xosc_write() fail\n"); + return 0; + } + rtc_read(RTC_BBPU, &bbpu); + rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD); rtc_write_trigger();
- pwrap_read(RTC_CON, &con); - pwrap_read(RTC_OSC32CON, &osc32con); - pwrap_read(RTC_AL_SEC, &sec); - printk(BIOS_INFO, "[RTC] %s con = 0x%x, osc32con = 0x%x, sec = 0x%x\n", - __func__, con, osc32con, sec); + rtc_read(RTC_CON, &con); + rtc_read(RTC_OSC32CON, &osc32con); + rtc_read(RTC_AL_SEC, &sec); + rtc_info("con=0x%x, osc32con=0x%x, sec=0x%x\n", con, osc32con, sec); + + return 1; }
/* initialize rtc related gpio */ @@ -63,11 +69,13 @@ pwrap_write_field(PMIC_RG_TOP_CKPDN_CON1_CLR, 0x1, 0x1, 1);
/* Export 32K clock RTC_32K2V8 */ - pwrap_read(RTC_CON, &con); - con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_EOSC32_LPEN); + rtc_read(RTC_CON, &con); + con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_EOSC32_LPEN + | RTC_CON_XOSC32_LPEN); con |= (RTC_CON_GPEN | RTC_CON_GOE); con &= ~(RTC_CON_F32KOB); - pwrap_write(RTC_CON, con); + rtc_write(RTC_CON, con); + return rtc_write_trigger(); }
@@ -78,40 +86,60 @@ rtc_gpio_init(); }
+/* enable lpd subroutine */ +static int rtc_lpen(u16 con) +{ + con &= ~RTC_CON_LPRST; + rtc_write(RTC_CON, con); + if (!rtc_write_trigger()) + return 0; + + con |= RTC_CON_LPRST; + rtc_write(RTC_CON, con); + if (!rtc_write_trigger()) + return 0; + + con &= ~RTC_CON_LPRST; + rtc_write(RTC_CON, con); + if (!rtc_write_trigger()) + return 0; + + return 1; +} + /* low power detect setting */ static int rtc_lpd_init(void) { - u16 con; + u16 con, sec;
- con = pwrap_read(RTC_CON, &con) | RTC_CON_XOSC32_LPEN; - con &= ~RTC_CON_LPRST; - pwrap_write(RTC_CON, con); + /* set RTC_LPD_OPT */ + rtc_read(RTC_AL_SEC, &sec); + sec |= RTC_LPD_OPT_F32K_CK_ALIVE; + rtc_write(RTC_AL_SEC, sec); if (!rtc_write_trigger()) return 0;
- con |= RTC_CON_LPRST; - pwrap_write(RTC_CON, con); - if (!rtc_write_trigger()) + /* init XOSC32 to detect 32k clock stop */ + rtc_read(RTC_CON, &con); + con |= RTC_CON_XOSC32_LPEN; + if (!rtc_lpen(con)) return 0;
- con &= ~RTC_CON_LPRST; - pwrap_write(RTC_CON, con); - if (!rtc_write_trigger()) + /* init EOSC32 to detect rtc low power */ + rtc_read(RTC_CON, &con); + con |= RTC_CON_EOSC32_LPEN; + if (!rtc_lpen(con)) return 0;
- con = pwrap_read(RTC_CON, &con) | RTC_CON_EOSC32_LPEN; - con &= ~RTC_CON_LPRST; - pwrap_write(RTC_CON, con); - if (!rtc_write_trigger()) - return 0; + rtc_read(RTC_CON, &con); + con &= ~RTC_CON_XOSC32_LPEN; + rtc_write(RTC_CON, con);
- con |= RTC_CON_LPRST; - pwrap_write(RTC_CON, con); - if (!rtc_write_trigger()) - return 0; - - con &= ~RTC_CON_LPRST; - pwrap_write(RTC_CON, con); + /* set RTC_LPD_OPT */ + rtc_read(RTC_AL_SEC, &sec); + sec &= ~RTC_LPD_OPT_MASK; + sec |= RTC_LPD_OPT_EOSC_LPD; + rtc_write(RTC_AL_SEC, sec); if (!rtc_write_trigger()) return 0;
@@ -122,56 +150,93 @@ { u16 bbpu;
- pwrap_read(RTC_BBPU, &bbpu); - pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_INIT); + rtc_read(RTC_BBPU, &bbpu); + rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_INIT); rtc_write_trigger();
udelay(500);
- pwrap_read(RTC_BBPU, &bbpu); - pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD); + rtc_read(RTC_BBPU, &bbpu); + rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD); rtc_write_trigger();
- pwrap_read(RTC_BBPU, &bbpu); + rtc_read(RTC_BBPU, &bbpu); if (bbpu & RTC_BBPU_INIT) { - printk(BIOS_INFO, "[RTC] %s:%d timeout\n", __func__, __LINE__); + rtc_info("timeout\n"); return false; }
return true; }
+/* write powerkeys to enable rtc functions */ +static int rtc_powerkey_init(void) +{ + rtc_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); + rtc_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); + return rtc_write_trigger(); +} + /* rtc init check */ int rtc_init(u8 recover) { - printk(BIOS_INFO, "[RTC] %s recovery: %d\n", __func__, recover); + int ret;
- if (!rtc_writeif_unlock()) - return 0; + rtc_info("recovery: %d\n", recover);
- if (!rtc_gpio_init()) - return 0; + /* write powerkeys to enable rtc functions */ + if (!rtc_powerkey_init()) { + ret = -RTC_STATUS_POWERKEY_INIT_FAIL; + goto err; + } + + /* write interface unlock need to be set after powerkey match */ + if (!rtc_writeif_unlock()) { + ret = -RTC_STATUS_WRITEIF_UNLOCK_FAIL; + goto err; + }
/* using dcxo 32K clock */ - rtc_enable_dcxo(); + if (!rtc_enable_dcxo()) { + ret = -RTC_STATUS_OSC_SETTING_FAIL; + goto err; + }
if (recover) mdelay(20);
- /* write powerkeys */ - pwrap_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); - pwrap_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); - if (!rtc_write_trigger()) - return 0; + if (!rtc_gpio_init()) { + ret = -RTC_STATUS_GPIO_INIT_FAIL; + goto err; + }
- if (!rtc_reg_init()) - return 0; - if (!rtc_lpd_init()) - return 0; - if (!rtc_hw_init()) - return 0; + if (!rtc_hw_init()) { + ret = -RTC_STATUS_HW_INIT_FAIL; + goto err; + }
- return 1; + if (!rtc_reg_init()) { + ret = -RTC_STATUS_REG_INIT_FAIL; + goto err; + } + + if (!rtc_lpd_init()) { + ret = -RTC_STATUS_LPD_INIT_FAIL; + goto err; + } + + /* After lpd init, powerkeys need to be written again to enable + * low power detect function. + */ + if (!rtc_powerkey_init()) { + ret = -RTC_STATUS_POWERKEY_INIT_FAIL; + goto err; + } + + return RTC_STATUS_OK; +err: + rtc_info("init fail: ret=%d\n", ret); + return ret; }
/* enable rtc bbpu */ @@ -185,12 +250,12 @@
/* pull PWRBB high */ bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_RELOAD | RTC_BBPU_PWREN; - pwrap_write(RTC_BBPU, bbpu); + rtc_write(RTC_BBPU, bbpu); ret = rtc_write_trigger(); - printk(BIOS_INFO, "[RTC] %s rtc_write_trigger=%d\n", __func__, ret); + rtc_info("rtc_write_trigger=%d\n", ret);
- pwrap_read(RTC_BBPU, &bbpu); - printk(BIOS_INFO, "[RTC] %s done BBPU=%#x\n", __func__, bbpu); + rtc_read(RTC_BBPU, &bbpu); + rtc_info("done BBPU=%#x\n", bbpu); }
void poweroff(void) @@ -198,11 +263,10 @@ u16 bbpu;
if (!rtc_writeif_unlock()) - printk(BIOS_INFO, - "[RTC] %s rtc_writeif_unlock() fail\n", __func__); + rtc_info("rtc_writeif_unlock() fail\n"); /* pull PWRBB low */ bbpu = RTC_BBPU_KEY | RTC_BBPU_RELOAD | RTC_BBPU_PWREN; - pwrap_write(RTC_BBPU, bbpu); + rtc_write(RTC_BBPU, bbpu);
pmic_set_power_hold(false); halt(); @@ -211,28 +275,28 @@ static void dcxo_init(void) { /* Buffer setting */ - pwrap_write(PMIC_RG_DCXO_CW15, 0xA2AA); - pwrap_write(PMIC_RG_DCXO_CW13, 0x98E9); - pwrap_write(PMIC_RG_DCXO_CW16, 0x9855); + rtc_write(PMIC_RG_DCXO_CW15, 0xA2AA); + rtc_write(PMIC_RG_DCXO_CW13, 0x98E9); + rtc_write(PMIC_RG_DCXO_CW16, 0x9855);
/* 26M enable control */ /* Enable clock buffer XO_SOC, XO_CEL */ - pwrap_write(PMIC_RG_DCXO_CW00, 0x4805); - pwrap_write(PMIC_RG_DCXO_CW11, 0x8000); + rtc_write(PMIC_RG_DCXO_CW00, 0x4805); + rtc_write(PMIC_RG_DCXO_CW11, 0x8000);
/* Load thermal coefficient */ - pwrap_write(PMIC_RG_TOP_TMA_KEY, 0x9CA7); - pwrap_write(PMIC_RG_DCXO_CW21, 0x12A7); - pwrap_write(PMIC_RG_DCXO_ELR0, 0xD004); - pwrap_write(PMIC_RG_TOP_TMA_KEY, 0x0000); + rtc_write(PMIC_RG_TOP_TMA_KEY, 0x9CA7); + rtc_write(PMIC_RG_DCXO_CW21, 0x12A7); + rtc_write(PMIC_RG_DCXO_ELR0, 0xD004); + rtc_write(PMIC_RG_TOP_TMA_KEY, 0x0000);
/* Adjust OSC FPM setting */ - pwrap_write(PMIC_RG_DCXO_CW07, 0x8FFE); + rtc_write(PMIC_RG_DCXO_CW07, 0x8FFE);
/* Re-Calibrate OSC current */ - pwrap_write(PMIC_RG_DCXO_CW09, 0x008F); + rtc_write(PMIC_RG_DCXO_CW09, 0x008F); udelay(100); - pwrap_write(PMIC_RG_DCXO_CW09, 0x408F); + rtc_write(PMIC_RG_DCXO_CW09, 0x408F); mdelay(5); }