xref: /rk3399_ARM-atf/plat/mediatek/drivers/rtc/rtc_mt6359p.c (revision 04f28f895f1dc8683838a1382c8f92881f4cf21d)
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 
RTC_Config_Interface(uint32_t addr,uint16_t data,uint16_t mask,uint16_t shift)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 
rtc_disable_2sec_reboot(void)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 
rtc_enable_k_eosc(void)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 
rtc_power_off_sequence(void)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