1 /*
2  * Copyright (c) 2020, 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 
RTC_Config_Interface(uint32_t addr,uint16_t data,uint16_t mask,uint16_t shift)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 
rtc_disable_2sec_reboot(void)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 
rtc_enable_k_eosc(void)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 
rtc_power_off_sequence(void)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