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