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