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