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