coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
rtc_mt6359p.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/clkbuf.h>
6 #include <soc/mt6359p.h>
7 #include <soc/pmif.h>
8 #include <soc/rtc.h>
9 #include <soc/rtc_common.h>
10 #include <timer.h>
11 
12 static struct pmif *pmif_arb = NULL;
13 
14 void rtc_read(u16 addr, u16 *rdata)
15 {
16  u32 data;
17 
18  if (pmif_arb == NULL)
20  pmif_arb->read(pmif_arb, 0, (u32)addr, &data);
21 
22  *rdata = (u16)data;
23 }
24 
25 void rtc_write(u16 addr, u16 wdata)
26 {
27  if (pmif_arb == NULL)
29  pmif_arb->write(pmif_arb, 0, (unsigned int)addr, (unsigned int)wdata);
30 }
31 
32 static void rtc_write_field(u16 reg, u16 val, u16 mask, u16 shift)
33 {
34  u16 old, new;
35 
36  rtc_read(reg, &old);
37  new = old & ~(mask << shift);
38  new |= (val << shift);
39  rtc_write(reg, new);
40 }
41 
42 /* initialize rtc setting of using dcxo clock */
43 static bool rtc_enable_dcxo(void)
44 {
45  if (!rtc_writeif_unlock()) {
46  rtc_info("rtc_writeif_unlock() failed\n");
47  return false;
48  }
49 
50  u16 bbpu, con, osc32con, sec;
51  rtc_read(RTC_BBPU, &bbpu);
54  rtc_read(RTC_OSC32CON, &osc32con);
57 
58  if (!rtc_xosc_write(osc32con)) {
59  rtc_info("rtc_xosc_write() failed\n");
60  return false;
61  }
62 
63  rtc_read(RTC_CON, &con);
64  rtc_read(RTC_OSC32CON, &osc32con);
65  rtc_read(RTC_AL_SEC, &sec);
66  rtc_info("con=%#x, osc32con=%#x, sec=%#x\n", con, osc32con, sec);
67  return true;
68 }
69 
70 /* initialize rtc related gpio */
71 bool rtc_gpio_init(void)
72 {
73  u16 con;
74 
75  /* GPI mode and pull down */
76  rtc_read(RTC_CON, &con);
79  con |= (RTC_CON_GPEN | RTC_CON_GOE);
80  con &= ~(RTC_CON_F32KOB);
81  con &= ~RTC_CON_GPU;
82  rtc_write(RTC_CON, con);
83 
84  return rtc_write_trigger();
85 }
86 
87 u16 rtc_get_frequency_meter(u16 val, u16 measure_src, u16 window_size)
88 {
89  u16 bbpu, osc32con;
90  u16 fqmtr_busy, fqmtr_data, fqmtr_tcksel;
91  struct stopwatch sw;
92 
93  if (val) {
94  rtc_read(RTC_BBPU, &bbpu);
97  rtc_read(RTC_OSC32CON, &osc32con);
98  rtc_xosc_write((osc32con & ~RTC_XOSCCALI_MASK) |
100  }
101 
102  /* RG_BANK_FQMTR_RST=1, reset FQMTR*/
105  udelay(20);
106  /* RG_BANK_FQMTR_RST=0, release FQMTR*/
109 
110  /* enable FQMTR clock */
115 
116 
119 
120  /* set frequency meter window value (0=1X32K(fixed clock)) */
121  rtc_write(PMIC_RG_FQMTR_WINSET, window_size);
122  /* enable 26M and set test clock source */
124  /* enable 26M -> delay 100us -> enable FQMTR */
125  mdelay(1);
126  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
127  /* enable FQMTR */
129  mdelay(1);
131  /* FQMTR read until ready */
132  do {
133  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_busy);
134  if (stopwatch_expired(&sw)) {
135  rtc_info("get frequency time out!\n");
136  return false;
137  }
138  } while (fqmtr_busy & PMIC_FQMTR_CON0_BUSY);
139 
140  /* read data should be closed to 26M/32k = 794 */
141  rtc_read(PMIC_RG_FQMTR_DATA, &fqmtr_data);
142 
143  /* disable FQMTR */
144  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
146  /* disable FQMTR -> delay 100us -> disable 26M */
147  mdelay(1);
148  /* disable 26M */
149  rtc_read(PMIC_RG_FQMTR_CON0, &fqmtr_tcksel);
151  fqmtr_tcksel & ~PMIC_FQMTR_CON0_DCXO26M_EN);
152  rtc_info("input=%d, output=%d\n", val, fqmtr_data);
153 
154  /* disable FQMTR clock */
159 
160  return fqmtr_data;
161 }
162 
163 /* low power detect setting */
164 static bool rtc_lpd_init(void)
165 {
166  u16 con, sec;
167 
168  /* enable both XOSC & EOSC LPD */
169  rtc_read(RTC_AL_SEC, &sec);
171  rtc_write(RTC_AL_SEC, sec);
172 
173  if (!rtc_write_trigger())
174  return false;
175 
176  /* init XOSC32 to detect 32k clock stop */
177  rtc_read(RTC_CON, &con);
178  con |= RTC_CON_XOSC32_LPEN;
179 
180  if (!rtc_lpen(con))
181  return false;
182 
183  /* init EOSC32 to detect rtc low power */
184  rtc_read(RTC_CON, &con);
185  con |= RTC_CON_EOSC32_LPEN;
186 
187  if (!rtc_lpen(con))
188  return false;
189 
190  rtc_read(RTC_CON, &con);
191  rtc_info("check RTC_CON_LPSTA_RAW after LP init: %#x\n", con);
192 
193  return true;
194 }
195 
196 static bool rtc_hw_init(void)
197 {
198  u16 bbpu;
199 
200  rtc_read(RTC_BBPU, &bbpu);
202  rtc_write(RTC_BBPU, bbpu & (~RTC_BBPU_SPAR_SW));
204  udelay(500);
205 
206  rtc_read(RTC_BBPU, &bbpu);
209  rtc_read(RTC_BBPU, &bbpu);
210 
211  if (bbpu & RTC_BBPU_RESET_ALARM || bbpu & RTC_BBPU_RESET_SPAR) {
212  rtc_info("timeout\n");
213  return false;
214  }
215  return true;
216 }
217 
218 /* rtc init check */
219 int rtc_init(int recover)
220 {
221  int ret;
222  u16 year;
223 
224  rtc_info("recovery: %d\n", recover);
225 
226  /* write powerkeys to enable rtc functions */
227  if (!rtc_powerkey_init()) {
229  goto err;
230  }
231 
232  /* write interface unlock need to be set after powerkey match */
233  if (!rtc_writeif_unlock()) {
235  goto err;
236  }
237 
238  rtc_osc_init();
239 
240  /* In recovery mode, we need 20ms delay for register setting. */
241  if (recover)
242  mdelay(20);
243 
244  if (!rtc_gpio_init()) {
246  goto err;
247  }
248 
249  if (!rtc_hw_init()) {
251  goto err;
252  }
253 
254  if (!rtc_reg_init()) {
256  goto err;
257  }
258 
259  /* solution1 for EOSC cali*/
262  & (~RTC_K_EOSC_RSV_2));
264 
265  if (!rtc_lpd_init()) {
267  goto err;
268  }
269 
270  /*
271  * After lpd init, powerkeys need to be written again to enable
272  * low power detect function.
273  */
274  if (!rtc_powerkey_init()) {
276  goto err;
277  }
278  return RTC_STATUS_OK;
279 
280 err:
281  rtc_info("init failed: ret=%d\n", ret);
282  return ret;
283 }
284 
285 /* enable rtc bbpu */
287 {
288  u16 bbpu;
289  int ret;
290 
291  /* pull powerhold high, control by pmic */
292  rtc_write_field(PMIC_PWRHOLD, 1, 0x1, 0);
294  rtc_write(RTC_BBPU, bbpu);
295  ret = rtc_write_trigger();
296  rtc_info("rtc_write_trigger=%d\n", ret);
297  rtc_read(RTC_BBPU, &bbpu);
298  rtc_info("done BBPU=%#x\n", bbpu);
299 }
300 
301 void poweroff(void)
302 {
303  u16 bbpu;
304 
305  if (!rtc_writeif_unlock())
306  rtc_info("rtc_writeif_unlock() failed\n");
307  /* pull PWRBB low */
309  rtc_write(RTC_BBPU, bbpu);
310  rtc_write_field(PMIC_PWRHOLD, 0, 0x1, 0);
311  halt();
312 }
313 
314 /* the rtc boot flow entry */
315 void rtc_boot(void)
316 {
317  u16 tmp;
318 
319  /* dcxo 32k init settings */
320  rtc_write_field(PMIC_RG_DCXO_CW02, 0xF, 0xF, 0);
322  rtc_info("PMIC_RG_SCK_TOP_CON0,%#x:%#x\n", PMIC_RG_SCK_TOP_CON0, tmp);
325  rtc_info("PMIC_RG_SCK_TOP_CON0,%#x:%#x\n", PMIC_RG_SCK_TOP_CON0, tmp);
326  /* use dcxo 32K clock */
327  if (!rtc_enable_dcxo())
328  rtc_info("rtc_enable_dcxo() failed\n");
329  rtc_boot_common();
331 }
static u32 addr
Definition: cirrus.c:14
@ PMIC_RG_DCXO_CW02
Definition: clkbuf.h:10
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
unsigned int year
Definition: edid.c:53
@ PMIC_PWRHOLD
Definition: mt6359p.h:20
@ PMIC_RG_FQMTR_CON0
Definition: mt6391.h:64
@ PMIF_SPI
Definition: pmif_common.h:39
struct pmif * get_pmif_controller(int inf, int mstid)
Definition: pmif.c:168
bool rtc_write_trigger(void)
Definition: rtc.c:27
@ 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
bool rtc_lpen(u16 con)
Definition: rtc.c:97
#define rtc_info(fmt, arg ...)
Definition: rtc_common.h:12
void rtc_osc_init(void)
Definition: rtc_osc_init.c:54
@ RTC_BBPU_KEY
Definition: rtc_common.h:45
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
void rtc_boot(void)
Definition: rtc_mt6359p.c:315
void rtc_bbpu_power_on(void)
Definition: rtc_mt6359p.c:286
static bool rtc_hw_init(void)
Definition: rtc_mt6359p.c:196
static bool rtc_enable_dcxo(void)
Definition: rtc_mt6359p.c:43
static bool rtc_lpd_init(void)
Definition: rtc_mt6359p.c:164
void poweroff(void)
Definition: rtc_mt6359p.c:301
void rtc_read(u16 addr, u16 *rdata)
Definition: rtc_mt6359p.c:14
static void rtc_write_field(u16 reg, u16 val, u16 mask, u16 shift)
Definition: rtc_mt6359p.c:32
int rtc_init(int recover)
Definition: rtc_mt6359p.c:219
static struct pmif * pmif_arb
Definition: rtc_mt6359p.c:12
u16 rtc_get_frequency_meter(u16 val, u16 measure_src, u16 window_size)
Definition: rtc_mt6359p.c:87
bool rtc_gpio_init(void)
Definition: rtc_mt6359p.c:71
void rtc_write(u16 addr, u16 wdata)
Definition: rtc_mt6359p.c:25
static const int mask[4]
Definition: gpio.c:308
@ RTC_CON
Definition: rtc.h:43
@ RTC_OSC32CON
Definition: rtc.h:42
@ RTC_BBPU
Definition: rtc.h:14
@ RTC_BBPU_RELOAD
Definition: rtc.h:67
@ RTC_CON_GPU
Definition: rtc.h:88
@ 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_YEA
Definition: rtc.h:37
@ RTC_AL_SEC
Definition: rtc.h:31
@ PMIC_RG_TOP_CKPDN_CON0_CLR
Definition: rtc.h:122
@ PMIC_RG_TOP_CKPDN_CON0_SET
Definition: rtc.h:121
@ PMIC_RG_SCK_TOP_CON0
Definition: rtc.h:115
@ RTC_EMBCK_SRC_SEL
Definition: rtc.h:99
@ RTC_REG_XOSC32_ENB
Definition: rtc.h:102
@ RTC_XOSCCALI_MASK
Definition: rtc.h:92
@ RTC_EMBCK_SEL_MODE_MASK
Definition: rtc.h:98
@ PMIC_RG_FQMTR_DATA
Definition: rtc.h:162
@ 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_F32K_CK_ALIVE
Definition: rtc.h:109
@ OSC32CON_ANALOG_SETTING
Definition: rtc.h:107
@ RTC_BBPU_SPAR_SW
Definition: rtc.h:61
@ RTC_BBPU_RESET_SPAR
Definition: rtc.h:62
@ RTC_BBPU_ENABLE_ALARM
Definition: rtc.h:60
@ RTC_BBPU_RESET_ALARM
Definition: rtc.h:63
@ PMIC_RG_FQMTR_DCXO26M_EN_SHIFT
Definition: rtc.h:148
@ PMIC_RG_BANK_FQMTR_RST_SHIFT
Definition: rtc.h:149
@ PMIC_RG_BANK_FQMTR_RST
Definition: rtc.h:144
@ RTC_K_EOSC_RSV_0
Definition: rtc.h:206
@ RTC_K_EOSC_RSV_1
Definition: rtc.h:207
@ RTC_K_EOSC_RSV_2
Definition: rtc.h:208
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
void(* write)(struct pmif *arb, u32 slvid, u32 reg, u32 data)
Definition: pmif_common.h:32
void(* read)(struct pmif *arb, u32 slvid, u32 reg, u32 *data)
Definition: pmif_common.h:31
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15