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