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 /*
4  * This file is created based on MT8186 Functional Specification
5  * Chapter number: 5.13
6  */
7 
8 #include <delay.h>
9 #include <halt.h>
10 #include <soc/rtc.h>
11 #include <soc/rtc_common.h>
12 #include <soc/mt6366.h>
13 #include <soc/pmic_wrap.h>
14 #include <timer.h>
15 
16 #define MT8186_RTC_DXCO_CAPID 0xE0
17 
18 /* Initialize RTC setting of using DCXO clock */
19 static bool rtc_enable_dcxo(void)
20 {
21  u16 bbpu, con, osc32con, sec;
22 
23  rtc_read(RTC_BBPU, &bbpu);
25 
26  if (!rtc_write_trigger()) {
27  rtc_info("rtc_write_trigger() failed\n");
28  return false;
29  }
30 
31  mdelay(1);
32  if (!rtc_writeif_unlock()) {
33  rtc_info("rtc_writeif_unlock() failed\n");
34  return false;
35  }
36 
37  rtc_read(RTC_OSC32CON, &osc32con);
42  if (!rtc_xosc_write(osc32con)) {
43  rtc_info("rtc_xosc_write() failed\n");
44  return false;
45  }
46 
47  rtc_read(RTC_CON, &con);
48  rtc_read(RTC_OSC32CON, &osc32con);
49  rtc_read(RTC_AL_SEC, &sec);
50  rtc_info("con = %#x, osc32con = %#x, sec = %#x\n", con, osc32con, sec);
51 
52  return true;
53 }
54 
55 /* Initialize RTC related gpio */
56 bool rtc_gpio_init(void)
57 {
58  u16 con;
59 
60  /* RTC_32K1V8 clock change from 128k div 4 source to RTC 32k source */
62 
63  /* Export 32K clock RTC_32K1V8_1 */
65 
66  /* Export 32K clock RTC_32K2V8 */
67  rtc_read(RTC_CON, &con);
70  con |= (RTC_CON_GPEN | RTC_CON_GOE);
71  con &= ~RTC_CON_F32KOB;
72  rtc_write(RTC_CON, con);
73 
74  return rtc_write_trigger();
75 }
76 
77 u16 rtc_get_frequency_meter(u16 val, u16 measure_src, u16 window_size)
78 {
79  u16 bbpu, osc32con;
80  u16 fqmtr_busy, fqmtr_data, fqmtr_rst, fqmtr_tcksel;
81  struct stopwatch sw;
82 
83  rtc_read(RTC_BBPU, &bbpu);
85  if (!rtc_write_trigger()) {
86  rtc_info("rtc_write_trigger() failed\n");
87  return false;
88  }
89 
90  rtc_read(RTC_OSC32CON, &osc32con);
91  if (!rtc_xosc_write((osc32con & ~RTC_XOSCCALI_MASK) |
92  (val & RTC_XOSCCALI_MASK))) {
93  rtc_info("rtc_xosc_write() failed\n");
94  return false;
95  }
96 
97  /* Enable FQMTR clock */
102 
103  /* FQMTR reset */
105  do {
106  rtc_read(PMIC_RG_FQMTR_DATA, &fqmtr_data);
107  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_busy);
108  } while (fqmtr_data && (fqmtr_busy & PMIC_FQMTR_CON0_BUSY));
109  rtc_read(PMIC_RG_FQMTR_RST, &fqmtr_rst);
110  /* FQMTR normal */
112 
113  /* Set frequency meter window value (0=1X32K(fixed clock)) */
114  rtc_write(PMIC_RG_FQMTR_WINSET, window_size);
115  /* Enable 26M and set test clock source */
117  /* Enable 26M -> delay 100us -> enable FQMTR */
118  udelay(100);
119  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
120  /* Enable FQMTR */
122  udelay(100);
123 
125  /* FQMTR read until ready */
127  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_busy) == 0 &&
128  !(fqmtr_busy & PMIC_FQMTR_CON0_BUSY))) {
129  rtc_info("get frequency time out: %#x\n", fqmtr_busy);
130  return false;
131  }
132 
133  /* Read data should be closed to 26M/32k = 794 */
134  rtc_read(PMIC_RG_FQMTR_DATA, &fqmtr_data);
135 
136  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
137  /* Disable FQMTR */
139  /* Disable FQMTR -> delay 100us -> disable 26M */
140  udelay(100);
141  /* Disable 26M */
142  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
144  fqmtr_tcksel & ~PMIC_FQMTR_CON0_DCXO26M_EN);
145  rtc_info("input = %#x, output = %#x\n", val, fqmtr_data);
146 
147  /* Disable FQMTR clock */
152 
153  return fqmtr_data;
154 }
155 
156 /* Low power detect setting */
157 static bool rtc_lpd_init(void)
158 {
159  u16 con, sec;
160 
161  /* Set RTC_LPD_OPT */
162  rtc_read(RTC_AL_SEC, &sec);
164  rtc_write(RTC_AL_SEC, sec);
165  if (!rtc_write_trigger()) {
166  rtc_info("rtc_write_trigger() failed\n");
167  return false;
168  }
169 
170  /* Initialize XOSC32 to detect 32k clock stop */
171  rtc_read(RTC_CON, &con);
172  con |= RTC_CON_XOSC32_LPEN;
173  if (!rtc_lpen(con))
174  return false;
175 
176  /* Initialize EOSC32 to detect RTC low power */
177  rtc_read(RTC_CON, &con);
178  con |= RTC_CON_EOSC32_LPEN;
179  if (!rtc_lpen(con))
180  return false;
181 
182  rtc_read(RTC_CON, &con);
183  con &= ~RTC_CON_XOSC32_LPEN;
184  rtc_write(RTC_CON, con);
185 
186  /* Set RTC_LPD_OPT */
187  rtc_read(RTC_AL_SEC, &sec);
188  sec &= ~RTC_LPD_OPT_MASK;
189  sec |= RTC_LPD_OPT_EOSC_LPD;
190  rtc_write(RTC_AL_SEC, sec);
191  if (!rtc_write_trigger()) {
192  rtc_info("rtc_write_trigger() failed\n");
193  return false;
194  }
195 
196  return true;
197 }
198 
199 static bool rtc_hw_init(void)
200 {
201  u16 bbpu;
202 
203  rtc_read(RTC_BBPU, &bbpu);
205  if (!rtc_write_trigger()) {
206  rtc_info("rtc_write_trigger() failed\n");
207  return false;
208  }
209 
210  udelay(500);
211 
212  rtc_read(RTC_BBPU, &bbpu);
214  if (!rtc_write_trigger()) {
215  rtc_info("rtc_write_trigger() failed\n");
216  return false;
217  }
218 
219  rtc_read(RTC_BBPU, &bbpu);
220  if (bbpu & RTC_BBPU_INIT) {
221  rtc_info("timeout\n");
222  return false;
223  }
224 
225  return true;
226 }
227 
228 static void mt6366_dcxo_disable_unused(void)
229 {
230  /* Disable clock buffer XO_CEL */
232  /* Mask bblpm request and switch off bblpm mode */
233  rtc_write(PMIC_RG_DCXO_CW23, 0x0052);
234 }
235 
236 static void rtc_set_capid(u16 capid)
237 {
238  u16 read_capid;
239 
240  rtc_write(PMIC_RG_DCXO_CW03, 0xFF00 | capid);
241 
242  rtc_read(PMIC_RG_DCXO_CW03, &read_capid);
243  rtc_info("read back capid: %#x\n", read_capid & 0xFF);
244 }
245 
246 /* Check RTC Initialization */
247 int rtc_init(int recover)
248 {
249  int ret;
250 
251  rtc_info("recovery: %d\n", recover);
252 
253  /* Write powerkeys to enable RTC functions */
254  if (!rtc_powerkey_init()) {
256  goto err;
257  }
258 
259  /* Write interface unlock need to be set after powerkey match */
260  if (!rtc_writeif_unlock()) {
262  goto err;
263  }
264 
265  rtc_osc_init();
266 
267  /* In recovery mode, we need 20ms delay for register setting. */
268  if (recover)
269  mdelay(20);
270 
271  if (!rtc_gpio_init()) {
273  goto err;
274  }
275 
276  if (!rtc_hw_init()) {
278  goto err;
279  }
280 
281  if (!rtc_reg_init()) {
283  goto err;
284  }
285 
286  if (!rtc_lpd_init()) {
288  goto err;
289  }
290 
291  /*
292  * After lpd init, powerkeys need to be written again to enable
293  * low power detect function.
294  */
295  if (!rtc_powerkey_init()) {
297  goto err;
298  }
299 
300  return RTC_STATUS_OK;
301 err:
302  rtc_info("init failed: ret = %d\n", ret);
303  return ret;
304 }
305 
306 /* Enable RTC bbpu */
308 {
309  u16 bbpu;
310  int ret;
311 
312  /* Pull powerhold high, control by pmic */
313  mt6366_set_power_hold(true);
314 
315  /* Pull PWRBB high */
317  rtc_write(RTC_BBPU, bbpu);
318  ret = rtc_write_trigger();
319  rtc_info("rtc_write_trigger = %d\n", ret);
320 
321  rtc_read(RTC_BBPU, &bbpu);
322  rtc_info("done BBPU = %#x\n", bbpu);
323 }
324 
325 static void dcxo_init(void)
326 {
327  /* Buffer setting */
328  rtc_write(PMIC_RG_DCXO_CW15, 0xA2AA);
329  rtc_write(PMIC_RG_DCXO_CW13, 0x98E9);
330  rtc_write(PMIC_RG_DCXO_CW16, 0x9855);
331 
332  /* 26M enable control */
333  /* Enable clock buffer XO_SOC, XO_CEL */
334  rtc_write(PMIC_RG_DCXO_CW00, 0x4805);
335  rtc_write(PMIC_RG_DCXO_CW11, 0x8000);
336 
337  /* Load thermal coefficient */
339  rtc_write(PMIC_RG_DCXO_CW21, 0x12A7);
340  rtc_write(PMIC_RG_DCXO_ELR0, 0xD004);
342 
343  /* Adjust OSC FPM setting */
344  rtc_write(PMIC_RG_DCXO_CW07, 0x8FFE);
345 
346  /* Re-calibrate OSC current */
347  rtc_write(PMIC_RG_DCXO_CW09, 0x008F);
348  udelay(100);
349  rtc_write(PMIC_RG_DCXO_CW09, 0x408F);
350  mdelay(5);
351 
353 
355 }
356 
357 /* Initialize rtc boot flow */
358 void rtc_boot(void)
359 {
360  /* DCXO clock initialized settings */
361  dcxo_init();
362 
363  /* DCXO 32k initialized settings */
364  pwrap_write_field(PMIC_RG_DCXO_CW02, 0xF, 0xF, 0);
366 
367  /* Use DCXO 32K clock */
368  if (!rtc_enable_dcxo())
369  rtc_info("rtc_enable_dcxo() failed\n");
370 
371  rtc_boot_common();
373 }
@ 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
void mdelay(unsigned int msecs)
Definition: delay.c:2
#define wait_us(timeout_us, condition)
Definition: timer.h:198
static void stopwatch_init_usecs_expire(struct stopwatch *sw, long us)
Definition: timer.h:127
void mt6366_set_power_hold(bool enable)
Definition: mt6366.c:829
@ 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
void rtc_bbpu_power_on(void)
Definition: rtc.c:266
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
@ PMIC_RG_DCXO_CW03
Definition: rtc.h:146
static void mt6366_dcxo_disable_unused(void)
Definition: rtc.c:228
static void rtc_set_capid(u16 capid)
Definition: rtc.c:236
static void dcxo_init(void)
Definition: rtc.c:325
#define MT8186_RTC_DXCO_CAPID
Definition: rtc.c:16
static bool rtc_hw_init(void)
Definition: rtc.c:199
static bool rtc_enable_dcxo(void)
Definition: rtc.c:19
static bool rtc_lpd_init(void)
Definition: rtc.c:157
uint16_t u16
Definition: stdint.h:48
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15