1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <common/debug.h> 8*91f16700Schasinglulu #include <drivers/delay_timer.h> 9*91f16700Schasinglulu #include <rtc.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu 12*91f16700Schasinglulu static void RTC_Config_Interface(uint32_t addr, uint16_t data, 13*91f16700Schasinglulu uint16_t mask, uint16_t shift) 14*91f16700Schasinglulu { 15*91f16700Schasinglulu uint16_t pmic_reg; 16*91f16700Schasinglulu 17*91f16700Schasinglulu pmic_reg = RTC_Read(addr); 18*91f16700Schasinglulu 19*91f16700Schasinglulu pmic_reg &= ~(mask << shift); 20*91f16700Schasinglulu pmic_reg |= (data << shift); 21*91f16700Schasinglulu 22*91f16700Schasinglulu RTC_Write(addr, pmic_reg); 23*91f16700Schasinglulu } 24*91f16700Schasinglulu 25*91f16700Schasinglulu static int32_t rtc_disable_2sec_reboot(void) 26*91f16700Schasinglulu { 27*91f16700Schasinglulu uint16_t reboot; 28*91f16700Schasinglulu 29*91f16700Schasinglulu reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) & 30*91f16700Schasinglulu ~RTC_BBPU_AUTO_PDN_SEL; 31*91f16700Schasinglulu RTC_Write(RTC_AL_SEC, reboot); 32*91f16700Schasinglulu 33*91f16700Schasinglulu return RTC_Write_Trigger(); 34*91f16700Schasinglulu } 35*91f16700Schasinglulu 36*91f16700Schasinglulu static int32_t rtc_enable_k_eosc(void) 37*91f16700Schasinglulu { 38*91f16700Schasinglulu uint16_t alm_dow, alm_sec; 39*91f16700Schasinglulu int16_t ret; 40*91f16700Schasinglulu 41*91f16700Schasinglulu /* Turning on eosc cali mode clock */ 42*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0_CLR, 1, 43*91f16700Schasinglulu PMIC_RG_RTC_EOSC32_CK_PDN_MASK, 44*91f16700Schasinglulu PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT); 45*91f16700Schasinglulu 46*91f16700Schasinglulu alm_sec = RTC_Read(RTC_AL_SEC) & (~RTC_LPD_OPT_MASK); 47*91f16700Schasinglulu RTC_Write(RTC_AL_SEC, alm_sec); 48*91f16700Schasinglulu ret = RTC_Write_Trigger(); 49*91f16700Schasinglulu if (ret == 0) { 50*91f16700Schasinglulu return 0; 51*91f16700Schasinglulu } 52*91f16700Schasinglulu 53*91f16700Schasinglulu RTC_Write(RTC_CON, RTC_LPD_EN); 54*91f16700Schasinglulu ret = RTC_Write_Trigger(); 55*91f16700Schasinglulu if (ret == 0) { 56*91f16700Schasinglulu return 0; 57*91f16700Schasinglulu } 58*91f16700Schasinglulu 59*91f16700Schasinglulu RTC_Write(RTC_CON, RTC_LPD_RST); 60*91f16700Schasinglulu ret = RTC_Write_Trigger(); 61*91f16700Schasinglulu if (ret == 0) { 62*91f16700Schasinglulu return 0; 63*91f16700Schasinglulu } 64*91f16700Schasinglulu 65*91f16700Schasinglulu RTC_Write(RTC_CON, RTC_LPD_EN); 66*91f16700Schasinglulu ret = RTC_Write_Trigger(); 67*91f16700Schasinglulu if (ret == 0) { 68*91f16700Schasinglulu return 0; 69*91f16700Schasinglulu } 70*91f16700Schasinglulu 71*91f16700Schasinglulu RTC_Write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); 72*91f16700Schasinglulu RTC_Write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); 73*91f16700Schasinglulu ret = RTC_Write_Trigger(); 74*91f16700Schasinglulu if (ret == 0) { 75*91f16700Schasinglulu return 0; 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu /* set RTC EOSC calibration period = 8sec */ 79*91f16700Schasinglulu alm_dow = (RTC_Read(RTC_AL_DOW) & (~RTC_RG_EOSC_CALI_TD_MASK)) | 80*91f16700Schasinglulu RTC_RG_EOSC_CALI_TD_8SEC; 81*91f16700Schasinglulu RTC_Write(RTC_AL_DOW, alm_dow); 82*91f16700Schasinglulu ret = RTC_Write_Trigger(); 83*91f16700Schasinglulu if (ret == 0) { 84*91f16700Schasinglulu return 0; 85*91f16700Schasinglulu } 86*91f16700Schasinglulu 87*91f16700Schasinglulu RTC_Write(RTC_BBPU, 88*91f16700Schasinglulu RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD); 89*91f16700Schasinglulu ret = RTC_Write_Trigger(); 90*91f16700Schasinglulu if (ret == 0) { 91*91f16700Schasinglulu return 0; 92*91f16700Schasinglulu } 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* Enable K EOSC mode :use solution1 of eosc cali to fix mt6359p 32K*/ 95*91f16700Schasinglulu RTC_Write(RTC_AL_YEA, (((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0) 96*91f16700Schasinglulu & (~RTC_K_EOSC_RSV_1)) | (RTC_K_EOSC_RSV_2))); 97*91f16700Schasinglulu ret = RTC_Write_Trigger(); 98*91f16700Schasinglulu if (ret == 0) { 99*91f16700Schasinglulu return 0; 100*91f16700Schasinglulu } 101*91f16700Schasinglulu 102*91f16700Schasinglulu INFO("[RTC] RTC_enable_k_eosc\n"); 103*91f16700Schasinglulu 104*91f16700Schasinglulu return 1; 105*91f16700Schasinglulu } 106*91f16700Schasinglulu 107*91f16700Schasinglulu void rtc_power_off_sequence(void) 108*91f16700Schasinglulu { 109*91f16700Schasinglulu uint16_t bbpu; 110*91f16700Schasinglulu int16_t ret; 111*91f16700Schasinglulu 112*91f16700Schasinglulu ret = rtc_disable_2sec_reboot(); 113*91f16700Schasinglulu if (ret == 0) { 114*91f16700Schasinglulu return; 115*91f16700Schasinglulu } 116*91f16700Schasinglulu 117*91f16700Schasinglulu ret = rtc_enable_k_eosc(); 118*91f16700Schasinglulu if (ret == 0) { 119*91f16700Schasinglulu return; 120*91f16700Schasinglulu } 121*91f16700Schasinglulu 122*91f16700Schasinglulu bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN; 123*91f16700Schasinglulu 124*91f16700Schasinglulu if (Writeif_unlock() != 0) { 125*91f16700Schasinglulu RTC_Write(RTC_BBPU, 126*91f16700Schasinglulu bbpu | RTC_BBPU_RESET_ALARM | RTC_BBPU_RESET_SPAR); 127*91f16700Schasinglulu RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW); 128*91f16700Schasinglulu ret = RTC_Write_Trigger(); 129*91f16700Schasinglulu if (ret == 0) { 130*91f16700Schasinglulu return; 131*91f16700Schasinglulu } 132*91f16700Schasinglulu mdelay(1); 133*91f16700Schasinglulu 134*91f16700Schasinglulu bbpu = RTC_Read(RTC_BBPU); 135*91f16700Schasinglulu 136*91f16700Schasinglulu if (((bbpu & RTC_BBPU_RESET_ALARM) > 0) || 137*91f16700Schasinglulu ((bbpu & RTC_BBPU_RESET_SPAR) > 0)) { 138*91f16700Schasinglulu INFO("[RTC] timeout\n"); 139*91f16700Schasinglulu } 140*91f16700Schasinglulu 141*91f16700Schasinglulu bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD; 142*91f16700Schasinglulu RTC_Write(RTC_BBPU, bbpu); 143*91f16700Schasinglulu ret = RTC_Write_Trigger(); 144*91f16700Schasinglulu if (ret == 0) { 145*91f16700Schasinglulu return; 146*91f16700Schasinglulu } 147*91f16700Schasinglulu } 148*91f16700Schasinglulu } 149