blob: 124bc8fbee5b8dba4607a68dab0d0f5012f31db8 [file] [log] [blame]
/*
* Copyright (c) 2020, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <rtc.h>
static void RTC_Config_Interface(uint32_t addr, uint16_t data,
uint16_t mask, uint16_t shift)
{
uint16_t pmic_reg;
pmic_reg = RTC_Read(addr);
pmic_reg &= ~(mask << shift);
pmic_reg |= (data << shift);
RTC_Write(addr, pmic_reg);
}
static int32_t rtc_disable_2sec_reboot(void)
{
uint16_t reboot;
reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) &
~RTC_BBPU_AUTO_PDN_SEL;
RTC_Write(RTC_AL_SEC, reboot);
return RTC_Write_Trigger();
}
static int32_t rtc_enable_k_eosc(void)
{
uint16_t alm_dow, alm_sec;
int16_t ret;
/* Turning on eosc cali mode clock */
RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0_CLR, 1,
PMIC_RG_RTC_EOSC32_CK_PDN_MASK,
PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT);
alm_sec = RTC_Read(RTC_AL_SEC) & (~RTC_LPD_OPT_MASK);
RTC_Write(RTC_AL_SEC, alm_sec);
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
RTC_Write(RTC_CON, RTC_LPD_EN);
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
RTC_Write(RTC_CON, RTC_LPD_RST);
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
RTC_Write(RTC_CON, RTC_LPD_EN);
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
RTC_Write(RTC_POWERKEY1, RTC_POWERKEY1_KEY);
RTC_Write(RTC_POWERKEY2, RTC_POWERKEY2_KEY);
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
/* set RTC EOSC calibration period = 8sec */
alm_dow = (RTC_Read(RTC_AL_DOW) & (~RTC_RG_EOSC_CALI_TD_MASK)) |
RTC_RG_EOSC_CALI_TD_8SEC;
RTC_Write(RTC_AL_DOW, alm_dow);
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
RTC_Write(RTC_BBPU,
RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
/* Enable K EOSC mode :use solution1 of eosc cali to fix mt6359p 32K*/
RTC_Write(RTC_AL_YEA, (((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0)
& (~RTC_K_EOSC_RSV_1)) | (RTC_K_EOSC_RSV_2)));
ret = RTC_Write_Trigger();
if (ret == 0) {
return 0;
}
INFO("[RTC] RTC_enable_k_eosc\n");
return 1;
}
void rtc_power_off_sequence(void)
{
uint16_t bbpu;
int16_t ret;
ret = rtc_disable_2sec_reboot();
if (ret == 0) {
return;
}
ret = rtc_enable_k_eosc();
if (ret == 0) {
return;
}
bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN;
if (Writeif_unlock() != 0) {
RTC_Write(RTC_BBPU,
bbpu | RTC_BBPU_RESET_ALARM | RTC_BBPU_RESET_SPAR);
RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW);
ret = RTC_Write_Trigger();
if (ret == 0) {
return;
}
mdelay(1);
bbpu = RTC_Read(RTC_BBPU);
if (((bbpu & RTC_BBPU_RESET_ALARM) > 0) ||
((bbpu & RTC_BBPU_RESET_SPAR) > 0)) {
INFO("[RTC] timeout\n");
}
bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
RTC_Write(RTC_BBPU, bbpu);
ret = RTC_Write_Trigger();
if (ret == 0) {
return;
}
}
}