coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
timer.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
5  */
6 
7 #include <delay.h>
8 #include <device/mmio.h>
9 #include <arch/lib_helpers.h>
10 #include <console/console.h>
11 #include <soc/clock.h>
12 #include <soc/timer.h>
13 #include <stdint.h>
14 #include <timer.h>
15 #include <soc/addressmap.h>
16 #include <assert.h>
17 
18 /* Global System Timers Unit (GTI) registers */
19 struct cn81xx_timer {
23  u8 rsvd[0x10];
26  u8 rsvd2[0x98];
37  u8 skip[0x1fef8];
41  u8 rsvd3[0x34];
43  u8 skip2[0x1ffb8];
44  u64 cwd_wdog[48]; /* Offset 0x40000 */
45  u8 skip3[0xfe80];
46  u64 cwd_poke[48]; /* Offset 0x50000 */
47 };
48 
49 check_member(cn81xx_timer, cc_imp_ctl, 0x100);
50 check_member(cn81xx_timer, ctl_cntacr0, 0x20040);
51 check_member(cn81xx_timer, cwd_wdog[0], 0x40000);
52 check_member(cn81xx_timer, cwd_poke[0], 0x50000);
53 
54 #define GTI_CC_CNTCR_EN (1 << 0)
55 #define GTI_CC_CNTCR_HDBG (1 << 1)
56 #define GTI_CC_CNTCR_FCREQ (1 << 8)
57 
58 #define GTI_CC_CNTSR_DBGH (1 << 1)
59 #define GTI_CC_CNTSR_FCACK (1 << 8)
60 
61 #define GTI_CWD_WDOG_MODE_SHIFT 0
62 #define GTI_CWD_WDOG_MODE_MASK 0x3
63 #define GTI_CWD_WDOG_STATE_SHIFT 2
64 #define GTI_CWD_WDOG_STATE_MASK 0x3
65 #define GTI_CWD_WDOG_LEN_SHIFT 4
66 #define GTI_CWD_WDOG_LEN_MASK 0xffff
67 #define GTI_CWD_WDOG_CNT_SHIFT 20
68 #define GTI_CWD_WDOG_CNT_MASK 0xffffff
69 #define GTI_CWD_WDOC_DSTOP (1 << 44)
70 #define GTI_CWD_WDOC_GSTOP (1 << 45)
71 
73 {
74  struct cn81xx_timer *timer = (void *)GTI_PF_BAR0;
75 
76  return read64(&timer->cc_cntcv);
77 }
78 
79 /**
80  * Get GTI counter value.
81  * @param mt Structure to fill
82  */
84 {
86 }
87 
88 /* Setup counter to operate at 1MHz */
89 static const size_t tickrate = 1000000;
90 
91 /**
92  * Init Global System Timers Unit (GTI).
93  * Configure timer to run at 1MHz tick-rate.
94  */
95 void init_timer(void)
96 {
97  struct cn81xx_timer *gti = (struct cn81xx_timer *)GTI_PF_BAR0;
98 
99  /* Check if the counter was already setup */
100  if (gti->cc_cntcr & GTI_CC_CNTCR_EN)
101  return;
102 
103  u64 sclk = thunderx_get_io_clock();
104 
105  /* Use coprocessor clock source */
106  write32(&gti->cc_imp_ctl, 0);
107 
108  write32(&gti->cc_cntfid0, tickrate);
109  write32(&gti->ctl_cntfrq, tickrate);
110  write32(&gti->cc_cntrate, ((1ULL << 32) * tickrate) / sclk);
111 
112  /* Enable the counter */
114 
115  //u32 u = (CNTPS_CTL_EL1_IMASK | CNTPS_CTL_EL1_EN);
116  //BDK_MSR(CNTPS_CTL_EL1, u);
117 }
118 
119 void soc_timer_init(void)
120 {
121  raw_write_cntfrq_el0(tickrate);
122 }
123 
124 /**
125  * Setup the watchdog to expire in timeout_ms milliseconds. When the watchdog
126  * expires, the chip three things happen:
127  * 1) Expire 1: interrupt that is ignored by the BDK
128  * 2) Expire 2: DEL3T interrupt, which is disabled and ignored
129  * 3) Expire 3: Soft reset of the chip
130  *
131  * Since we want a soft reset, we actually program the watchdog to expire at
132  * the timeout / 3.
133  *
134  * @param index Index of watchdog to configure
135  * @param timeout_ms Timeout in milliseconds.
136  */
137 void watchdog_set(const size_t index, unsigned int timeout_ms)
138 {
140  uint64_t timeout_sclk = sclk * timeout_ms / 1000;
141  struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
142 
143  assert(index < ARRAY_SIZE(timer->cwd_wdog));
144  if (index >= ARRAY_SIZE(timer->cwd_wdog))
145  return;
146 
147  /*
148  * Per comment above, we want the watchdog to expire at 3x the rate
149  * specified
150  */
151  timeout_sclk /= 3;
152  /* Watchdog counts in 1024 cycle steps */
153  uint64_t timeout_wdog = timeout_sclk >> 10;
154  /* We can only specify the upper 16 bits of a 24 bit value. Round up */
155  timeout_wdog = (timeout_wdog + 0xff) >> 8;
156  /* If the timeout overflows the hardware limit, set max */
157  if (timeout_wdog >= 0x10000)
158  timeout_wdog = 0xffff;
159 
160  printk(BIOS_DEBUG, "Watchdog: Set to expire %llu SCLK cycles\n",
161  timeout_wdog << 18);
162  clrsetbits64(&timer->cwd_wdog[index],
165  (timeout_wdog << GTI_CWD_WDOG_LEN_SHIFT) |
166  (3 << GTI_CWD_WDOG_MODE_SHIFT));
167 }
168 
169 /**
170  * Signal the watchdog that we are still running.
171  *
172  * @param index Index of watchdog to configure.
173  */
174 void watchdog_poke(const size_t index)
175 {
176  struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
177 
178  assert(index < ARRAY_SIZE(timer->cwd_poke));
179  if (index >= ARRAY_SIZE(timer->cwd_poke))
180  return;
181 
182  write64(&timer->cwd_poke[0], 0);
183 }
184 
185 /**
186  * Disable the hardware watchdog
187  *
188  * @param index Index of watchdog to configure.
189  */
190 void watchdog_disable(const size_t index)
191 {
192  struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
193 
194  assert(index < ARRAY_SIZE(timer->cwd_wdog));
195  if (index >= ARRAY_SIZE(timer->cwd_wdog))
196  return;
197 
198  write64(&timer->cwd_wdog[index], 0);
199  printk(BIOS_DEBUG, "Watchdog: Disabled\n");
200 }
201 
202 /**
203  * Return true if the watchdog is configured and running
204  *
205  * @param index Index of watchdog to configure.
206  *
207  * @return Non-zero if watchdog is running.
208  */
209 int watchdog_is_running(const size_t index)
210 {
211  struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
212 
213  assert(index < ARRAY_SIZE(timer->cwd_wdog));
214  if (index >= ARRAY_SIZE(timer->cwd_wdog))
215  return 0;
216 
217  uint64_t val = read64(&timer->cwd_wdog[index]);
218 
220 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
void write64(void *addr, uint64_t val)
uint64_t read64(const void *addr)
#define assert(statement)
Definition: assert.h:74
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
#define setbits32(addr, set)
Definition: mmio.h:21
#define clrsetbits64(addr, clear, set)
Definition: mmio.h:17
static void mono_time_set_usecs(struct mono_time *mt, long us)
Definition: timer.h:53
__weak void init_timer(void)
Definition: timer.c:7
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
void timer_monotonic_get(struct mono_time *mt)
Definition: timer.c:7
u64 thunderx_get_io_clock(void)
Returns the I/O clock speed in Hz.
Definition: clock.c:45
#define GTI_PF_BAR0
Definition: addressmap.h:68
#define GTI_CWD_WDOG_LEN_MASK
Definition: timer.c:66
void watchdog_disable(const size_t index)
Disable the hardware watchdog.
Definition: timer.c:190
check_member(cn81xx_timer, cc_imp_ctl, 0x100)
#define GTI_CWD_WDOG_MODE_MASK
Definition: timer.c:62
void watchdog_poke(const size_t index)
Signal the watchdog that we are still running.
Definition: timer.c:174
void watchdog_set(const size_t index, unsigned int timeout_ms)
Setup the watchdog to expire in timeout_ms milliseconds.
Definition: timer.c:137
static const size_t tickrate
Definition: timer.c:89
static uint64_t timer_raw_value(void)
Definition: timer.c:72
#define GTI_CC_CNTCR_EN
Definition: timer.c:54
#define GTI_CWD_WDOG_MODE_SHIFT
Definition: timer.c:61
#define GTI_CWD_WDOG_LEN_SHIFT
Definition: timer.c:65
int watchdog_is_running(const size_t index)
Return true if the watchdog is configured and running.
Definition: timer.c:209
void soc_timer_init(void)
Definition: timer.c:119
uint64_t u64
Definition: stdint.h:54
uint32_t u32
Definition: stdint.h:51
unsigned long long uint64_t
Definition: stdint.h:17
uint8_t u8
Definition: stdint.h:45
u32 cc_cntrate
Definition: timer.c:27
u8 skip[0x1fef8]
Definition: timer.c:37
u8 skip2[0x1ffb8]
Definition: timer.c:43
u64 cc_cntmb_int_set
Definition: timer.c:33
u8 rsvd3[0x34]
Definition: timer.c:41
u64 cc_cntmb_int_ena_clr
Definition: timer.c:34
u32 cc_cntsr
Definition: timer.c:21
u32 ctl_cntacr0
Definition: timer.c:42
u64 cc_cntmb_int
Definition: timer.c:32
u32 cc_cntfid1
Definition: timer.c:25
u64 cwd_wdog[48]
Definition: timer.c:44
u64 cwd_poke[48]
Definition: timer.c:46
u64 cc_cntadd
Definition: timer.c:29
u32 ctl_cnttidr
Definition: timer.c:40
u64 cc_cntmbts
Definition: timer.c:31
u32 cc_cntcr
Definition: timer.c:20
u32 ctl_cntfrq
Definition: timer.c:38
u32 ctl_cntnsar
Definition: timer.c:39
u64 cc_imp_ctl
Definition: timer.c:36
u32 cc_cntracc
Definition: timer.c:28
u64 cc_cntcv
Definition: timer.c:22
u8 rsvd2[0x98]
Definition: timer.c:26
u64 cc_cntmb_int_ena_set
Definition: timer.c:35
u8 skip3[0xfe80]
Definition: timer.c:45
u64 cc_cntmb
Definition: timer.c:30
u32 cc_cntfid0
Definition: timer.c:24
u8 rsvd[0x10]
Definition: timer.c:23
u8 val
Definition: sys.c:300