xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/common/rtc.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <soc/rtc_common.h>
4 #include <soc/rtc.h>
5 #include <timer.h>
6 
7 /* ensure rtc write success */
rtc_busy_wait(void)8 static bool rtc_busy_wait(void)
9 {
10 	struct stopwatch sw;
11 	u16 bbpu;
12 
13 	stopwatch_init_usecs_expire(&sw, RTC_CBUSY_TIMEOUT_US);
14 
15 	do {
16 		rtc_read(RTC_BBPU, &bbpu);
17 		/* Time > 1sec, time out and set recovery mode enable.*/
18 		if (stopwatch_expired(&sw)) {
19 			rtc_info("BBPU CBUSY time out !!\n");
20 			return false;
21 		}
22 	} while (bbpu & RTC_BBPU_CBUSY);
23 
24 	return true;
25 }
26 
rtc_write_trigger(void)27 bool rtc_write_trigger(void)
28 {
29 	rtc_write(RTC_WRTGR, 1);
30 	return rtc_busy_wait();
31 }
32 
33 /* unlock rtc write interface */
rtc_writeif_unlock(void)34 bool rtc_writeif_unlock(void)
35 {
36 	rtc_write(RTC_PROT, RTC_PROT_UNLOCK1);
37 	if (!rtc_write_trigger())
38 		return false;
39 	rtc_write(RTC_PROT, RTC_PROT_UNLOCK2);
40 	if (!rtc_write_trigger())
41 		return false;
42 
43 	return true;
44 }
45 
46 /* set rtc time */
rtc_set(const struct rtc_time * time)47 int rtc_set(const struct rtc_time *time)
48 {
49 	return -1;
50 }
51 
52 /* get rtc time */
rtc_get(struct rtc_time * time)53 int rtc_get(struct rtc_time *time)
54 {
55 	u16 value;
56 
57 	rtc_read(RTC_TC_SEC, &value);
58 	time->sec = value;
59 	rtc_read(RTC_TC_MIN, &value);
60 	time->min = value;
61 	rtc_read(RTC_TC_HOU, &value);
62 	time->hour = value;
63 	rtc_read(RTC_TC_DOM, &value);
64 	time->mday = value;
65 	rtc_read(RTC_TC_MTH, &value);
66 	time->mon = value;
67 	rtc_read(RTC_TC_YEA, &value);
68 	time->year = (value + RTC_MIN_YEAR_OFFSET) % 100;
69 
70 	return 0;
71 }
72 
73 /* set rtc xosc setting */
rtc_xosc_write(u16 val)74 bool rtc_xosc_write(u16 val)
75 {
76 	u16 bbpu;
77 
78 	rtc_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1);
79 	if (!rtc_busy_wait())
80 		return false;
81 	rtc_write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2);
82 	if (!rtc_busy_wait())
83 		return false;
84 
85 	rtc_write(RTC_OSC32CON, val);
86 	if (!rtc_busy_wait())
87 		return false;
88 
89 	rtc_read(RTC_BBPU, &bbpu);
90 	bbpu |= RTC_BBPU_KEY | RTC_BBPU_RELOAD;
91 	rtc_write(RTC_BBPU, bbpu);
92 
93 	return rtc_write_trigger();
94 }
95 
96 /* enable lpd subroutine */
rtc_lpen(u16 con)97 bool rtc_lpen(u16 con)
98 {
99 	con &= ~RTC_CON_LPRST;
100 	rtc_write(RTC_CON, con);
101 
102 	if (!rtc_write_trigger())
103 		return false;
104 
105 	con |= RTC_CON_LPRST;
106 	rtc_write(RTC_CON, con);
107 
108 	if (!rtc_write_trigger())
109 		return false;
110 
111 	con &= ~RTC_CON_LPRST;
112 	rtc_write(RTC_CON, con);
113 
114 	if (!rtc_write_trigger())
115 		return false;
116 
117 	return true;
118 }
119 
120 /* initialize rtc related registers */
rtc_reg_init(void)121 bool rtc_reg_init(void)
122 {
123 	u16 irqsta;
124 
125 	rtc_write(RTC_IRQ_EN, 0);
126 	rtc_write(RTC_CII_EN, 0);
127 	rtc_write(RTC_AL_MASK, 0);
128 	rtc_write(RTC_AL_YEA, 1970 - RTC_MIN_YEAR);
129 	rtc_write(RTC_AL_MTH, 1);
130 	rtc_write(RTC_AL_DOM, 1);
131 	rtc_write(RTC_AL_DOW, 4);
132 	rtc_write(RTC_AL_HOU, 0);
133 	rtc_write(RTC_AL_MIN, 0);
134 	rtc_write(RTC_AL_SEC, 0);
135 
136 	rtc_write(RTC_DIFF, 0);
137 	rtc_write(RTC_CALI, 0);
138 	if (!rtc_write_trigger())
139 		return false;
140 
141 	rtc_read(RTC_IRQ_STA, &irqsta);  /* read clear */
142 
143 	/* init time counters after resetting RTC_DIFF and RTC_CALI */
144 	rtc_write(RTC_TC_YEA, RTC_DEFAULT_YEA - RTC_MIN_YEAR);
145 	rtc_write(RTC_TC_MTH, RTC_DEFAULT_MTH);
146 	rtc_write(RTC_TC_DOM, RTC_DEFAULT_DOM);
147 	rtc_write(RTC_TC_DOW, RTC_DEFAULT_DOW);
148 	rtc_write(RTC_TC_HOU, 0);
149 	rtc_write(RTC_TC_MIN, 0);
150 	rtc_write(RTC_TC_SEC, 0);
151 
152 	return rtc_write_trigger();
153 }
154 
155 /* write powerkeys to enable rtc functions */
rtc_powerkey_init(void)156 bool rtc_powerkey_init(void)
157 {
158 	rtc_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY);
159 	rtc_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY);
160 	return rtc_write_trigger();
161 }
162 
rtc_check_state(void)163 static u8 rtc_check_state(void)
164 {
165 	u16 con;
166 	u16 pwrky1;
167 	u16 pwrky2;
168 
169 	rtc_read(RTC_CON, &con);
170 	rtc_read(RTC_POWERKEY1, &pwrky1);
171 	rtc_read(RTC_POWERKEY2, &pwrky2);
172 
173 	rtc_info("con=%x, pwrkey1=%x, pwrkey2=%x\n", con, pwrky1, pwrky2);
174 
175 	if (con & RTC_CON_LPSTA_RAW)
176 		return RTC_STATE_INIT;
177 
178 	if (!rtc_busy_wait())
179 		return RTC_STATE_RECOVER;
180 
181 	if (!rtc_writeif_unlock())
182 		return RTC_STATE_RECOVER;
183 
184 	if (pwrky1 != RTC_POWERKEY1_KEY || pwrky2 != RTC_POWERKEY2_KEY)
185 		return RTC_STATE_INIT;
186 	else
187 		return RTC_STATE_REBOOT;
188 }
189 
rtc_boot_common(void)190 void rtc_boot_common(void)
191 {
192 	u16 bbpu;
193 	u16 con;
194 	u16 irqsta;
195 
196 	switch (rtc_check_state()) {
197 	case RTC_STATE_REBOOT:
198 		rtc_read(RTC_BBPU, &bbpu);
199 		rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
200 		rtc_write_trigger();
201 		rtc_osc_init();
202 		rtc_info("RTC_STATE_REBOOT\n");
203 		break;
204 	case RTC_STATE_RECOVER:
205 		rtc_init(1);
206 		rtc_info("RTC_STATE_RECOVER\n");
207 		break;
208 	case RTC_STATE_INIT:
209 	default:
210 		if (rtc_init(0))
211 			rtc_init(1);
212 		rtc_info("RTC_STATE_INIT\n");
213 		break;
214 	}
215 
216 	rtc_read(RTC_IRQ_STA, &irqsta);  /* Read clear */
217 	rtc_read(RTC_BBPU, &bbpu);
218 	rtc_read(RTC_CON, &con);
219 
220 	rtc_info("irqsta=%x, bbpu=%x, con=%x\n", irqsta, bbpu, con);
221 }
222