drivers/mipi: Add support for KD_KD110N11_51IE panel
[coreboot2.git] / src / soc / cavium / cn81xx / timer.c
blobd9879baec6ab04211bd9b7de2cda416e88c16380
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /*
4 * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
5 */
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>
18 /* Global System Timers Unit (GTI) registers */
19 struct cn81xx_timer {
20 u32 cc_cntcr;
21 u32 cc_cntsr;
22 u64 cc_cntcv;
23 u8 rsvd[0x10];
24 u32 cc_cntfid0;
25 u32 cc_cntfid1;
26 u8 rsvd2[0x98];
27 u32 cc_cntrate;
28 u32 cc_cntracc;
29 u64 cc_cntadd;
30 u64 cc_cntmb;
31 u64 cc_cntmbts;
32 u64 cc_cntmb_int;
33 u64 cc_cntmb_int_set;
34 u64 cc_cntmb_int_ena_clr;
35 u64 cc_cntmb_int_ena_set;
36 u64 cc_imp_ctl;
37 u8 skip[0x1fef8];
38 u32 ctl_cntfrq;
39 u32 ctl_cntnsar;
40 u32 ctl_cnttidr;
41 u8 rsvd3[0x34];
42 u32 ctl_cntacr0;
43 u8 skip2[0x1ffb8];
44 u64 cwd_wdog[48]; /* Offset 0x40000 */
45 u8 skip3[0xfe80];
46 u64 cwd_poke[48]; /* Offset 0x50000 */
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);
54 #define GTI_CC_CNTCR_EN (1 << 0)
55 #define GTI_CC_CNTCR_HDBG (1 << 1)
56 #define GTI_CC_CNTCR_FCREQ (1 << 8)
58 #define GTI_CC_CNTSR_DBGH (1 << 1)
59 #define GTI_CC_CNTSR_FCACK (1 << 8)
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)
72 static uint64_t timer_raw_value(void)
74 struct cn81xx_timer *timer = (void *)GTI_PF_BAR0;
76 return read64(&timer->cc_cntcv);
79 /**
80 * Get GTI counter value.
81 * @param mt Structure to fill
83 void timer_monotonic_get(struct mono_time *mt)
85 mono_time_set_usecs(mt, timer_raw_value());
88 /* Setup counter to operate at 1MHz */
89 static const size_t tickrate = 1000000;
91 /**
92 * Init Global System Timers Unit (GTI).
93 * Configure timer to run at 1MHz tick-rate.
95 void init_timer(void)
97 struct cn81xx_timer *gti = (struct cn81xx_timer *)GTI_PF_BAR0;
99 /* Check if the counter was already setup */
100 if (gti->cc_cntcr & GTI_CC_CNTCR_EN)
101 return;
103 u64 sclk = thunderx_get_io_clock();
105 /* Use coprocessor clock source */
106 write32(&gti->cc_imp_ctl, 0);
108 write32(&gti->cc_cntfid0, tickrate);
109 write32(&gti->ctl_cntfrq, tickrate);
110 write32(&gti->cc_cntrate, ((1ULL << 32) * tickrate) / sclk);
112 /* Enable the counter */
113 setbits32(&gti->cc_cntcr, GTI_CC_CNTCR_EN);
115 //u32 u = (CNTPS_CTL_EL1_IMASK | CNTPS_CTL_EL1_EN);
116 //BDK_MSR(CNTPS_CTL_EL1, u);
119 void soc_timer_init(void)
121 raw_write_cntfrq_el0(tickrate);
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
131 * Since we want a soft reset, we actually program the watchdog to expire at
132 * the timeout / 3.
134 * @param index Index of watchdog to configure
135 * @param timeout_ms Timeout in milliseconds.
137 void watchdog_set(const size_t index, unsigned int timeout_ms)
139 uint64_t sclk = thunderx_get_io_clock();
140 uint64_t timeout_sclk = sclk * timeout_ms / 1000;
141 struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
143 assert(index < ARRAY_SIZE(timer->cwd_wdog));
144 if (index >= ARRAY_SIZE(timer->cwd_wdog))
145 return;
148 * Per comment above, we want the watchdog to expire at 3x the rate
149 * specified
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;
160 printk(BIOS_DEBUG, "Watchdog: Set to expire %llu SCLK cycles\n",
161 timeout_wdog << 18);
162 clrsetbits64(&timer->cwd_wdog[index],
163 (GTI_CWD_WDOG_LEN_MASK << GTI_CWD_WDOG_LEN_SHIFT) |
164 (GTI_CWD_WDOG_MODE_MASK << GTI_CWD_WDOG_MODE_SHIFT),
165 (timeout_wdog << GTI_CWD_WDOG_LEN_SHIFT) |
166 (3 << GTI_CWD_WDOG_MODE_SHIFT));
170 * Signal the watchdog that we are still running.
172 * @param index Index of watchdog to configure.
174 void watchdog_poke(const size_t index)
176 struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
178 assert(index < ARRAY_SIZE(timer->cwd_poke));
179 if (index >= ARRAY_SIZE(timer->cwd_poke))
180 return;
182 write64(&timer->cwd_poke[0], 0);
186 * Disable the hardware watchdog
188 * @param index Index of watchdog to configure.
190 void watchdog_disable(const size_t index)
192 struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
194 assert(index < ARRAY_SIZE(timer->cwd_wdog));
195 if (index >= ARRAY_SIZE(timer->cwd_wdog))
196 return;
198 write64(&timer->cwd_wdog[index], 0);
199 printk(BIOS_DEBUG, "Watchdog: Disabled\n");
203 * Return true if the watchdog is configured and running
205 * @param index Index of watchdog to configure.
207 * @return Non-zero if watchdog is running.
209 int watchdog_is_running(const size_t index)
211 struct cn81xx_timer *timer = (struct cn81xx_timer *)GTI_PF_BAR0;
213 assert(index < ARRAY_SIZE(timer->cwd_wdog));
214 if (index >= ARRAY_SIZE(timer->cwd_wdog))
215 return 0;
217 uint64_t val = read64(&timer->cwd_wdog[index]);
219 return !!(val & (GTI_CWD_WDOG_MODE_MASK << GTI_CWD_WDOG_MODE_SHIFT));