xref: /rk3399_ARM-atf/plat/mediatek/mt8183/drivers/rtc/rtc.c (revision 76eac18647f3bb81e029309ea61f8c4c5336ca27)
1*e977b4dbSkenny liang /*
2*e977b4dbSkenny liang  * Copyright (c) 2019, MediaTek Inc. All rights reserved.
3*e977b4dbSkenny liang  *
4*e977b4dbSkenny liang  * SPDX-License-Identifier: BSD-3-Clause
5*e977b4dbSkenny liang  */
6*e977b4dbSkenny liang 
7*e977b4dbSkenny liang #include <common/debug.h>
8*e977b4dbSkenny liang #include <drivers/delay_timer.h>
9*e977b4dbSkenny liang #include <rtc.h>
10*e977b4dbSkenny liang 
RTC_Config_Interface(uint32_t addr,uint16_t data,uint16_t MASK,uint16_t SHIFT)11*e977b4dbSkenny liang static void RTC_Config_Interface(uint32_t addr, uint16_t data,
12*e977b4dbSkenny liang 			    uint16_t MASK, uint16_t SHIFT)
13*e977b4dbSkenny liang {
14*e977b4dbSkenny liang 	uint16_t pmic_reg = 0;
15*e977b4dbSkenny liang 
16*e977b4dbSkenny liang 	pmic_reg = RTC_Read(addr);
17*e977b4dbSkenny liang 
18*e977b4dbSkenny liang 	pmic_reg &= ~(MASK << SHIFT);
19*e977b4dbSkenny liang 	pmic_reg |= (data << SHIFT);
20*e977b4dbSkenny liang 
21*e977b4dbSkenny liang 	RTC_Write(addr, pmic_reg);
22*e977b4dbSkenny liang }
23*e977b4dbSkenny liang 
rtc_disable_2sec_reboot(void)24*e977b4dbSkenny liang static void rtc_disable_2sec_reboot(void)
25*e977b4dbSkenny liang {
26*e977b4dbSkenny liang 	uint16_t reboot;
27*e977b4dbSkenny liang 
28*e977b4dbSkenny liang 	reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) &
29*e977b4dbSkenny liang 		 ~RTC_BBPU_AUTO_PDN_SEL;
30*e977b4dbSkenny liang 	RTC_Write(RTC_AL_SEC, reboot);
31*e977b4dbSkenny liang 	RTC_Write_Trigger();
32*e977b4dbSkenny liang }
33*e977b4dbSkenny liang 
rtc_xosc_write(uint16_t val,bool reload)34*e977b4dbSkenny liang static void rtc_xosc_write(uint16_t val, bool reload)
35*e977b4dbSkenny liang {
36*e977b4dbSkenny liang 	uint16_t bbpu;
37*e977b4dbSkenny liang 
38*e977b4dbSkenny liang 	RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1);
39*e977b4dbSkenny liang 	rtc_busy_wait();
40*e977b4dbSkenny liang 	RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2);
41*e977b4dbSkenny liang 	rtc_busy_wait();
42*e977b4dbSkenny liang 
43*e977b4dbSkenny liang 	RTC_Write(RTC_OSC32CON, val);
44*e977b4dbSkenny liang 	rtc_busy_wait();
45*e977b4dbSkenny liang 
46*e977b4dbSkenny liang 	if (reload) {
47*e977b4dbSkenny liang 		bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
48*e977b4dbSkenny liang 		RTC_Write(RTC_BBPU, bbpu);
49*e977b4dbSkenny liang 		RTC_Write_Trigger();
50*e977b4dbSkenny liang 	}
51*e977b4dbSkenny liang }
52*e977b4dbSkenny liang 
rtc_enable_k_eosc(void)53*e977b4dbSkenny liang static void rtc_enable_k_eosc(void)
54*e977b4dbSkenny liang {
55*e977b4dbSkenny liang 	uint16_t osc32;
56*e977b4dbSkenny liang 	uint16_t rtc_eosc_cali_td = 8; /* eosc cali period time */
57*e977b4dbSkenny liang 
58*e977b4dbSkenny liang 	/* Truning on eosc cali mode clock */
59*e977b4dbSkenny liang 	RTC_Config_Interface(PMIC_RG_TOP_CON, 1,
60*e977b4dbSkenny liang 			PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK,
61*e977b4dbSkenny liang 			PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT);
62*e977b4dbSkenny liang 	RTC_Config_Interface(PMIC_RG_TOP_CON, 1,
63*e977b4dbSkenny liang 			PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK,
64*e977b4dbSkenny liang 			PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT);
65*e977b4dbSkenny liang 	RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0, 0,
66*e977b4dbSkenny liang 			PMIC_RG_RTC_EOSC32_CK_PDN_MASK,
67*e977b4dbSkenny liang 			PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT);
68*e977b4dbSkenny liang 
69*e977b4dbSkenny liang 	switch (rtc_eosc_cali_td) {
70*e977b4dbSkenny liang 	case 1:
71*e977b4dbSkenny liang 		RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x3,
72*e977b4dbSkenny liang 			PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
73*e977b4dbSkenny liang 		break;
74*e977b4dbSkenny liang 	case 2:
75*e977b4dbSkenny liang 		RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x4,
76*e977b4dbSkenny liang 			PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
77*e977b4dbSkenny liang 		break;
78*e977b4dbSkenny liang 	case 4:
79*e977b4dbSkenny liang 		RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x5,
80*e977b4dbSkenny liang 			PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
81*e977b4dbSkenny liang 		break;
82*e977b4dbSkenny liang 	case 16:
83*e977b4dbSkenny liang 		RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x7,
84*e977b4dbSkenny liang 			PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
85*e977b4dbSkenny liang 		break;
86*e977b4dbSkenny liang 	default:
87*e977b4dbSkenny liang 		RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x6,
88*e977b4dbSkenny liang 			PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
89*e977b4dbSkenny liang 		break;
90*e977b4dbSkenny liang 	}
91*e977b4dbSkenny liang 	/* Switch the DCXO from 32k-less mode to RTC mode,
92*e977b4dbSkenny liang 	 * otherwise, EOSC cali will fail
93*e977b4dbSkenny liang 	 */
94*e977b4dbSkenny liang 	/* RTC mode will have only OFF mode and FPM */
95*e977b4dbSkenny liang 	RTC_Config_Interface(PMIC_RG_DCXO_CW02, 0, PMIC_RG_XO_EN32K_MAN_MASK,
96*e977b4dbSkenny liang 		PMIC_RG_XO_EN32K_MAN_SHIFT);
97*e977b4dbSkenny liang 	RTC_Write(RTC_BBPU,
98*e977b4dbSkenny liang 		  RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
99*e977b4dbSkenny liang 	RTC_Write_Trigger();
100*e977b4dbSkenny liang 	/* Enable K EOSC mode for normal power off and then plug out battery */
101*e977b4dbSkenny liang 	RTC_Write(RTC_AL_YEA, ((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0)
102*e977b4dbSkenny liang 				& (~RTC_K_EOSC_RSV_1)) | RTC_K_EOSC_RSV_2);
103*e977b4dbSkenny liang 	RTC_Write_Trigger();
104*e977b4dbSkenny liang 
105*e977b4dbSkenny liang 	osc32 = RTC_Read(RTC_OSC32CON);
106*e977b4dbSkenny liang 	rtc_xosc_write(osc32 | RTC_EMBCK_SRC_SEL, true);
107*e977b4dbSkenny liang 	INFO("[RTC] RTC_enable_k_eosc\n");
108*e977b4dbSkenny liang }
109*e977b4dbSkenny liang 
rtc_power_off_sequence(void)110*e977b4dbSkenny liang void rtc_power_off_sequence(void)
111*e977b4dbSkenny liang {
112*e977b4dbSkenny liang 	uint16_t bbpu;
113*e977b4dbSkenny liang 
114*e977b4dbSkenny liang 	rtc_disable_2sec_reboot();
115*e977b4dbSkenny liang 	rtc_enable_k_eosc();
116*e977b4dbSkenny liang 
117*e977b4dbSkenny liang 	/* clear alarm */
118*e977b4dbSkenny liang 	bbpu = RTC_BBPU_KEY | RTC_BBPU_CLR | RTC_BBPU_PWREN;
119*e977b4dbSkenny liang 	if (Writeif_unlock()) {
120*e977b4dbSkenny liang 		RTC_Write(RTC_BBPU, bbpu);
121*e977b4dbSkenny liang 
122*e977b4dbSkenny liang 		RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW);
123*e977b4dbSkenny liang 		RTC_Write_Trigger();
124*e977b4dbSkenny liang 		mdelay(1);
125*e977b4dbSkenny liang 
126*e977b4dbSkenny liang 		bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
127*e977b4dbSkenny liang 		RTC_Write(RTC_BBPU, bbpu);
128*e977b4dbSkenny liang 		RTC_Write_Trigger();
129*e977b4dbSkenny liang 		INFO("[RTC] BBPU=0x%x, IRQ_EN=0x%x, AL_MSK=0x%x, AL_SEC=0x%x\n",
130*e977b4dbSkenny liang 		     RTC_Read(RTC_BBPU), RTC_Read(RTC_IRQ_EN),
131*e977b4dbSkenny liang 		     RTC_Read(RTC_AL_MASK), RTC_Read(RTC_AL_SEC));
132*e977b4dbSkenny liang 	}
133*e977b4dbSkenny liang }
134