coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
rtc.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <delay.h>
4 #include <halt.h>
5 #include <soc/rtc.h>
6 #include <soc/rtc_common.h>
7 #include <soc/mt6358.h>
8 #include <soc/pmic_wrap.h>
9 #include <timer.h>
10 
11 /* initialize rtc setting of using dcxo clock */
12 static bool rtc_enable_dcxo(void)
13 {
14  u16 bbpu, con, osc32con, sec;
15 
16  rtc_read(RTC_BBPU, &bbpu);
19 
20  mdelay(1);
21  if (!rtc_writeif_unlock()) {
22  rtc_info("rtc_writeif_unlock() failed\n");
23  return false;
24  }
25 
26  rtc_read(RTC_OSC32CON, &osc32con);
31  if (!rtc_xosc_write(osc32con)) {
32  rtc_info("rtc_xosc_write() failed\n");
33  return false;
34  }
35 
36  rtc_read(RTC_CON, &con);
37  rtc_read(RTC_OSC32CON, &osc32con);
38  rtc_read(RTC_AL_SEC, &sec);
39  rtc_info("con=0x%x, osc32con=0x%x, sec=0x%x\n", con, osc32con, sec);
40 
41  return true;
42 }
43 
44 /* initialize rtc related gpio */
45 bool rtc_gpio_init(void)
46 {
47  u16 con;
48 
49  /* RTC_32K1V8 clock change from 128k div 4 source
50  * to RTC 32k source
51  */
53 
54  /* Export 32K clock RTC_32K1V8_1 */
56 
57  /* Export 32K clock RTC_32K2V8 */
58  rtc_read(RTC_CON, &con);
61  con |= (RTC_CON_GPEN | RTC_CON_GOE);
62  con &= ~(RTC_CON_F32KOB);
63  rtc_write(RTC_CON, con);
64 
65  return rtc_write_trigger();
66 }
67 
68 u16 rtc_get_frequency_meter(u16 val, u16 measure_src, u16 window_size)
69 {
70  u16 bbpu, osc32con;
71  u16 fqmtr_busy, fqmtr_data, fqmtr_rst, fqmtr_tcksel;
72  struct stopwatch sw;
73 
74  if (val) {
75  rtc_read(RTC_BBPU, &bbpu);
78  rtc_read(RTC_OSC32CON, &osc32con);
79  rtc_xosc_write((osc32con & ~RTC_XOSCCALI_MASK) |
81  }
82 
83  /* enable FQMTR clock */
88 
89  /* FQMTR reset */
91  do {
92  rtc_read(PMIC_RG_FQMTR_DATA, &fqmtr_data);
93  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_busy);
94  } while (fqmtr_data && (fqmtr_busy & PMIC_FQMTR_CON0_BUSY));
95  rtc_read(PMIC_RG_FQMTR_RST, &fqmtr_rst);
96  /* FQMTR normal */
98 
99  /* set frequency meter window value (0=1X32K(fixed clock)) */
100  rtc_write(PMIC_RG_FQMTR_WINSET, window_size);
101  /* enable 26M and set test clock source */
103  /* enable 26M -> delay 100us -> enable FQMTR */
104  udelay(100);
105  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
106  /* enable FQMTR */
108  udelay(100);
109 
111  /* FQMTR read until ready */
112  do {
113  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_busy);
114  if (stopwatch_expired(&sw)) {
115  rtc_info("get frequency time out !!\n");
116  return false;
117  }
118  } while (fqmtr_busy & PMIC_FQMTR_CON0_BUSY);
119 
120  /* read data should be closed to 26M/32k = 794 */
121  rtc_read(PMIC_RG_FQMTR_DATA, &fqmtr_data);
122 
123  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
124  /* disable FQMTR */
126  /* disable FQMTR -> delay 100us -> disable 26M */
127  udelay(100);
128  /* disable 26M */
129  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
131  fqmtr_tcksel & ~PMIC_FQMTR_CON0_DCXO26M_EN);
132  rtc_info("input=0x%x, output=%d\n", val, fqmtr_data);
133 
134  /* disable FQMTR clock */
139 
140  return fqmtr_data;
141 }
142 
143 /* low power detect setting */
144 static bool rtc_lpd_init(void)
145 {
146  u16 con, sec;
147 
148  /* set RTC_LPD_OPT */
149  rtc_read(RTC_AL_SEC, &sec);
151  rtc_write(RTC_AL_SEC, sec);
152  if (!rtc_write_trigger())
153  return false;
154 
155  /* init XOSC32 to detect 32k clock stop */
156  rtc_read(RTC_CON, &con);
157  con |= RTC_CON_XOSC32_LPEN;
158  if (!rtc_lpen(con))
159  return false;
160 
161  /* init EOSC32 to detect rtc low power */
162  rtc_read(RTC_CON, &con);
163  con |= RTC_CON_EOSC32_LPEN;
164  if (!rtc_lpen(con))
165  return false;
166 
167  rtc_read(RTC_CON, &con);
168  con &= ~RTC_CON_XOSC32_LPEN;
169  rtc_write(RTC_CON, con);
170 
171  /* set RTC_LPD_OPT */
172  rtc_read(RTC_AL_SEC, &sec);
173  sec &= ~RTC_LPD_OPT_MASK;
174  sec |= RTC_LPD_OPT_EOSC_LPD;
175  rtc_write(RTC_AL_SEC, sec);
176  if (!rtc_write_trigger())
177  return false;
178 
179  return true;
180 }
181 
182 static bool rtc_hw_init(void)
183 {
184  u16 bbpu;
185 
186  rtc_read(RTC_BBPU, &bbpu);
189 
190  udelay(500);
191 
192  rtc_read(RTC_BBPU, &bbpu);
195 
196  rtc_read(RTC_BBPU, &bbpu);
197  if (bbpu & RTC_BBPU_INIT) {
198  rtc_info("timeout\n");
199  return false;
200  }
201 
202  return true;
203 }
204 
205 /* rtc init check */
206 int rtc_init(int recover)
207 {
208  int ret;
209 
210  rtc_info("recovery: %d\n", recover);
211 
212  /* write powerkeys to enable rtc functions */
213  if (!rtc_powerkey_init()) {
215  goto err;
216  }
217 
218  /* write interface unlock need to be set after powerkey match */
219  if (!rtc_writeif_unlock()) {
221  goto err;
222  }
223 
224  rtc_osc_init();
225 
226  /* In recovery mode, we need 20ms delay for register setting. */
227  if (recover)
228  mdelay(20);
229 
230  if (!rtc_gpio_init()) {
232  goto err;
233  }
234 
235  if (!rtc_hw_init()) {
237  goto err;
238  }
239 
240  if (!rtc_reg_init()) {
242  goto err;
243  }
244 
245  if (!rtc_lpd_init()) {
247  goto err;
248  }
249 
250  /*
251  * After lpd init, powerkeys need to be written again to enable
252  * low power detect function.
253  */
254  if (!rtc_powerkey_init()) {
256  goto err;
257  }
258 
259  return RTC_STATUS_OK;
260 err:
261  rtc_info("init fail: ret=%d\n", ret);
262  return ret;
263 }
264 
265 /* enable rtc bbpu */
267 {
268  u16 bbpu;
269  int ret;
270 
271  /* pull powerhold high, control by pmic */
272  pmic_set_power_hold(true);
273 
274  /* pull PWRBB high */
276  rtc_write(RTC_BBPU, bbpu);
277  ret = rtc_write_trigger();
278  rtc_info("rtc_write_trigger=%d\n", ret);
279 
280  rtc_read(RTC_BBPU, &bbpu);
281  rtc_info("done BBPU=%#x\n", bbpu);
282 }
283 
284 void poweroff(void)
285 {
286  u16 bbpu;
287 
288  if (!rtc_writeif_unlock())
289  rtc_info("rtc_writeif_unlock() failed\n");
290  /* pull PWRBB low */
292  rtc_write(RTC_BBPU, bbpu);
293 
294  pmic_set_power_hold(false);
295  halt();
296 }
297 
298 static void dcxo_init(void)
299 {
300  /* Buffer setting */
301  rtc_write(PMIC_RG_DCXO_CW15, 0xA2AA);
302  rtc_write(PMIC_RG_DCXO_CW13, 0x98E9);
303  rtc_write(PMIC_RG_DCXO_CW16, 0x9855);
304 
305  /* 26M enable control */
306  /* Enable clock buffer XO_SOC, XO_CEL */
307  rtc_write(PMIC_RG_DCXO_CW00, 0x4805);
308  rtc_write(PMIC_RG_DCXO_CW11, 0x8000);
309 
310  /* Load thermal coefficient */
312  rtc_write(PMIC_RG_DCXO_CW21, 0x12A7);
313  rtc_write(PMIC_RG_DCXO_ELR0, 0xD004);
315 
316  /* Adjust OSC FPM setting */
317  rtc_write(PMIC_RG_DCXO_CW07, 0x8FFE);
318 
319  /* Re-Calibrate OSC current */
320  rtc_write(PMIC_RG_DCXO_CW09, 0x008F);
321  udelay(100);
322  rtc_write(PMIC_RG_DCXO_CW09, 0x408F);
323  mdelay(5);
324 }
325 
327 {
328  /* Disable clock buffer XO_CEL */
330  /* Mask bblpm request and switch off bblpm mode */
331  rtc_write(PMIC_RG_DCXO_CW23, 0x0052);
332 }
333 
334 /* the rtc boot flow entry */
335 void rtc_boot(void)
336 {
337  /* dcxo clock init settings */
338  dcxo_init();
339 
340  /* dcxo 32k init settings */
341  pwrap_write_field(PMIC_RG_DCXO_CW02, 0xF, 0xF, 0);
343 
344  /* use dcxo 32K clock */
345  if (!rtc_enable_dcxo())
346  rtc_info("rtc_enable_dcxo() failed\n");
347 
348  rtc_boot_common();
350 }
@ PMIC_RG_DCXO_CW00
Definition: clkbuf.h:9
@ PMIC_RG_DCXO_CW13
Definition: clkbuf.h:16
@ PMIC_RG_DCXO_CW09
Definition: clkbuf.h:12
@ PMIC_RG_DCXO_CW15
Definition: clkbuf.h:17
@ PMIC_RG_DCXO_CW02
Definition: clkbuf.h:10
static void pmic_set_power_hold(void)
Definition: mt6359p.c:63
void mdelay(unsigned int msecs)
Definition: delay.c:2
void __noreturn halt(void)
halt the system reliably
Definition: halt.c:6
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_usecs_expire(struct stopwatch *sw, long us)
Definition: timer.h:127
@ PMIC_RG_FQMTR_CON0
Definition: mt6391.h:64
static void pwrap_write_field(u16 reg, u16 val, u16 mask, u16 shift)
@ RTC_STATUS_HW_INIT_FAIL
Definition: rtc_common.h:92
@ RTC_STATUS_OK
Definition: rtc_common.h:87
@ RTC_STATUS_LPD_INIT_FAIL
Definition: rtc_common.h:94
@ RTC_STATUS_REG_INIT_FAIL
Definition: rtc_common.h:93
@ RTC_STATUS_GPIO_INIT_FAIL
Definition: rtc_common.h:91
@ RTC_STATUS_WRITEIF_UNLOCK_FAIL
Definition: rtc_common.h:89
@ RTC_STATUS_POWERKEY_INIT_FAIL
Definition: rtc_common.h:88
#define rtc_info(fmt, arg ...)
Definition: rtc_common.h:12
@ RTC_BBPU_KEY
Definition: rtc_common.h:45
void rtc_read(u16 addr, u16 *rdata)
Definition: rtc_mt6359p.c:14
void rtc_write(u16 addr, u16 wdata)
Definition: rtc_mt6359p.c:25
void rtc_init(void)
Definition: rtc.c:29
bool rtc_write_trigger(void)
Definition: rtc.c:27
bool rtc_lpen(u16 con)
Definition: rtc.c:97
bool rtc_writeif_unlock(void)
Definition: rtc.c:34
bool rtc_reg_init(void)
Definition: rtc.c:121
void rtc_boot_common(void)
Definition: rtc.c:190
bool rtc_xosc_write(u16 val)
Definition: rtc.c:74
bool rtc_powerkey_init(void)
Definition: rtc.c:156
@ RTC_CON
Definition: rtc.h:43
@ RTC_OSC32CON
Definition: rtc.h:42
@ RTC_BBPU
Definition: rtc.h:14
@ RTC_BBPU_AUTO
Definition: rtc.h:65
@ RTC_BBPU_PWREN
Definition: rtc.h:63
@ RTC_BBPU_RELOAD
Definition: rtc.h:67
@ RTC_CON_F32KOB
Definition: rtc.h:82
@ RTC_CON_LPSTA_RAW
Definition: rtc.h:92
@ RTC_CON_GOE
Definition: rtc.h:84
@ RTC_CON_LPRST
Definition: rtc.h:80
@ RTC_CON_GPEN
Definition: rtc.h:87
@ RTC_AL_SEC
Definition: rtc.h:31
void rtc_boot(void)
Definition: rtc.c:149
void rtc_osc_init(void)
Definition: rtc.c:28
@ PMIC_RG_TOP_TMA_KEY
Definition: rtc.h:153
@ PMIC_RG_TOP_CKSEL_CON0_SET
Definition: rtc.h:127
@ PMIC_RG_TOP_CKPDN_CON0_CLR
Definition: rtc.h:122
@ PMIC_RG_TOP_CKPDN_CON0_SET
Definition: rtc.h:121
@ PMIC_RG_TOP_CKPDN_CON1_CLR
Definition: rtc.h:125
@ PMIC_RG_SCK_TOP_CON0
Definition: rtc.h:115
@ RTC_BBPU_INIT
Definition: rtc.h:63
@ RTC_EMBCK_SRC_SEL
Definition: rtc.h:99
@ RTC_REG_XOSC32_ENB
Definition: rtc.h:102
@ RTC_GPS_CKOUT_EN
Definition: rtc.h:101
@ RTC_XOSCCALI_MASK
Definition: rtc.h:92
@ RTC_EMB_K_EOSC32_MODE
Definition: rtc.h:95
@ RTC_EMBCK_SEL_OPTION
Definition: rtc.h:100
@ RTC_XOSC32_ENB
Definition: rtc.h:93
@ RTC_EMBCK_SEL_MODE_MASK
Definition: rtc.h:98
@ PMIC_RG_DCXO_CW21
Definition: rtc.h:147
@ PMIC_RG_DCXO_CW23
Definition: rtc.h:148
@ PMIC_RG_DCXO_CW16
Definition: rtc.h:146
@ PMIC_RG_DCXO_ELR0
Definition: rtc.h:149
@ PMIC_RG_DCXO_CW00_CLR
Definition: rtc.h:139
@ PMIC_RG_DCXO_CW11
Definition: rtc.h:143
@ PMIC_RG_DCXO_CW07
Definition: rtc.h:141
@ PMIC_RG_FQMTR_DATA
Definition: rtc.h:162
@ PMIC_RG_FQMTR_RST
Definition: rtc.h:159
@ FQMTR_TIMEOUT_US
Definition: rtc.h:164
@ PMIC_RG_FQMTR_WINSET
Definition: rtc.h:161
@ RTC_CON_EOSC32_LPEN
Definition: rtc.h:74
@ RTC_CON_XOSC32_LPEN
Definition: rtc.h:75
@ PMIC_FQMTR_CON0_BUSY
Definition: rtc.h:191
@ PMIC_FQMTR_CON0_DCXO26M_EN
Definition: rtc.h:192
@ PMIC_FQMTR_CON0_FQMTR_EN
Definition: rtc.h:193
@ PMIC_RG_FQMTR_32K_CK_PDN_SHIFT
Definition: rtc.h:132
@ PMIC_RG_FQMTR_CK_PDN_SHIFT
Definition: rtc.h:133
@ RTC_LPD_OPT_EOSC_LPD
Definition: rtc.h:107
@ RTC_LPD_OPT_F32K_CK_ALIVE
Definition: rtc.h:109
@ RTC_LPD_OPT_MASK
Definition: rtc.h:110
@ PMIC_FQMTR_RST_SHIFT
Definition: rtc.h:179
static void dcxo_init(void)
Definition: rtc.c:298
void rtc_bbpu_power_on(void)
Definition: rtc.c:266
static bool rtc_hw_init(void)
Definition: rtc.c:182
static bool rtc_enable_dcxo(void)
Definition: rtc.c:12
void mt6358_dcxo_disable_unused(void)
Definition: rtc.c:326
static bool rtc_lpd_init(void)
Definition: rtc.c:144
void poweroff(void)
Definition: rtc.c:284
u16 rtc_get_frequency_meter(u16 val, u16 measure_src, u16 window_size)
Definition: rtc.c:68
bool rtc_gpio_init(void)
Definition: rtc.c:45
uint16_t u16
Definition: stdint.h:48
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15