1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-12-06 GuEe-GUI first version
9 */
10
11 #define DBG_TAG "drv.rk_timer"
12 #define DBG_LVL DBG_INFO
13 #include <rtdbg.h>
14
15 #include <rthw.h>
16 #include <rtthread.h>
17 #include <rtdevice.h>
18
19 #ifdef RT_USING_KTIME
20 #include <ktime.h>
21 #endif
22
23 #define HZ 100
24 #define KHZ 1000
25 #define MHZ 1000000
26 #define OSC_HZ (24 * MHZ)
27
28 #define TIMER_LOAD_COUNT0 0x00
29 #define TIMER_LOAD_COUNT1 0x04
30 #define TIMER_CURRENT_VALUE0 0x08
31 #define TIMER_CURRENT_VALUE1 0x0c
32 #define TIMER_CONTROL_REG3288 0x10
33 #define TIMER_CONTROL_REG3399 0x1c
34 #define TIMER_INT_STATUS 0x18
35
36 #define TIMER_DISABLE 0x0
37 #define TIMER_ENABLE 0x1
38 #define TIMER_MODE_FREE_RUNNING (0 << 1)
39 #define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
40 #define TIMER_INT_UNMASK (1 << 2)
41
42 struct rk_timer
43 {
44 struct rt_hwtimer_device parent;
45
46 void *base;
47 void *ctrl;
48 struct rt_clk *clk;
49 struct rt_clk *pclk;
50
51 int irq;
52 rt_uint32_t freq;
53 rt_uint32_t cycle;
54 rt_bool_t status;
55
56 struct rt_hwtimer_info info;
57 };
58 #ifdef RT_USING_KTIME
59 struct hrt_timer
60 {
61 struct rk_timer *timer;
62 uint64_t cnt;
63 void (*outcb)(void *param);
64 void *param;
65 };
66 static struct hrt_timer _timer0 = {0};
67 static struct rt_spinlock _spinlock;
68 #endif
69 #define raw_to_rk_timer(raw) rt_container_of(raw, struct rk_timer, parent)
70
71 struct rk_timer_data
72 {
73 rt_uint32_t ctrl_reg;
74 };
75
rk_timer_disable(struct rk_timer * timer)76 rt_inline void rk_timer_disable(struct rk_timer *timer)
77 {
78 HWREG32(timer->ctrl) = TIMER_DISABLE;
79 }
80
rk_timer_enable(struct rk_timer * timer,rt_uint32_t flags)81 rt_inline void rk_timer_enable(struct rk_timer *timer, rt_uint32_t flags)
82 {
83 HWREG32(timer->ctrl) = TIMER_ENABLE | flags;
84 }
85
rk_timer_current_value(struct rk_timer * timer)86 rt_inline rt_uint32_t rk_timer_current_value(struct rk_timer *timer)
87 {
88 return HWREG32(timer->base + TIMER_CURRENT_VALUE0);
89 }
90
rk_timer_update_counter(unsigned long cycles,struct rk_timer * timer)91 static void rk_timer_update_counter(unsigned long cycles, struct rk_timer *timer)
92 {
93 HWREG32(timer->base + TIMER_LOAD_COUNT0) = cycles;
94 HWREG32(timer->base + TIMER_LOAD_COUNT1) = 0;
95 }
96
rk_timer_interrupt_clear(struct rk_timer * timer)97 static void rk_timer_interrupt_clear(struct rk_timer *timer)
98 {
99 HWREG32(timer->base + TIMER_INT_STATUS) = 1;
100 }
101
rk_timer_init(struct rt_hwtimer_device * timer,rt_uint32_t state)102 static void rk_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
103 {
104 }
105
rk_timer_start(struct rt_hwtimer_device * timer,rt_uint32_t cnt,rt_hwtimer_mode_t mode)106 static rt_err_t rk_timer_start(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
107 {
108 rt_err_t err = RT_EOK;
109 struct rk_timer *rk_timer = raw_to_rk_timer(timer);
110
111 switch (mode)
112 {
113 case HWTIMER_MODE_ONESHOT:
114 rk_timer_disable(rk_timer);
115 rk_timer_update_counter(cnt, rk_timer);
116 rk_timer_enable(rk_timer, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK);
117 break;
118
119 case HWTIMER_MODE_PERIOD:
120 rk_timer_disable(rk_timer);
121 rk_timer_update_counter(rk_timer->freq / HZ - 1, rk_timer);
122 rk_timer_enable(rk_timer, TIMER_MODE_FREE_RUNNING | TIMER_INT_UNMASK);
123 break;
124
125 default:
126 err = -RT_EINVAL;
127 break;
128 }
129
130 if (!err)
131 {
132 rk_timer->cycle = cnt;
133 rk_timer->status = RT_TRUE;
134 }
135
136 return err;
137 }
138
rk_timer_stop(struct rt_hwtimer_device * timer)139 static void rk_timer_stop(struct rt_hwtimer_device *timer)
140 {
141 struct rk_timer *rk_timer = raw_to_rk_timer(timer);
142
143 rk_timer->status = RT_FALSE;
144 rk_timer_disable(rk_timer);
145 }
146
rk_timer_count_get(struct rt_hwtimer_device * timer)147 static rt_uint32_t rk_timer_count_get(struct rt_hwtimer_device *timer)
148 {
149 struct rk_timer *rk_timer = raw_to_rk_timer(timer);
150
151 return rk_timer_current_value(rk_timer);
152 }
153
rk_timer_ctrl(struct rt_hwtimer_device * timer,rt_uint32_t cmd,void * args)154 static rt_err_t rk_timer_ctrl(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args)
155 {
156 rt_err_t err = RT_EOK;
157 struct rk_timer *rk_timer = raw_to_rk_timer(timer);
158
159 switch (cmd)
160 {
161 case HWTIMER_CTRL_FREQ_SET:
162 err = -RT_ENOSYS;
163 break;
164
165 case HWTIMER_CTRL_STOP:
166 rk_timer_stop(timer);
167 break;
168
169 case HWTIMER_CTRL_INFO_GET:
170 if (args)
171 {
172 rt_memcpy(args, &rk_timer->info, sizeof(rk_timer->info));
173 }
174 else
175 {
176 err = -RT_ERROR;
177 }
178 break;
179
180 case HWTIMER_CTRL_MODE_SET:
181 err = rk_timer_start(timer, rk_timer->cycle, (rt_hwtimer_mode_t)args);
182 break;
183
184 default:
185 err = -RT_EINVAL;
186 break;
187 }
188
189 return err;
190 }
191
192 const static struct rt_hwtimer_ops rk_timer_ops =
193 {
194 .init = rk_timer_init,
195 .start = rk_timer_start,
196 .stop = rk_timer_stop,
197 .count_get = rk_timer_count_get,
198 .control = rk_timer_ctrl,
199 };
200
rk_timer_isr(int irqno,void * param)201 static void rk_timer_isr(int irqno, void *param)
202 {
203 struct hrt_timer *timer = &_timer0;
204 struct rk_timer *time = timer->timer;
205
206 rk_timer_interrupt_clear(time);
207
208 rt_ktime_hrtimer_process();
209 }
210
rt_ktime_hrtimer_bind(rt_bitmap_t * affinity)211 void rt_ktime_hrtimer_bind(rt_bitmap_t *affinity)
212 {
213 struct rk_timer *timer = _timer0.timer;
214
215 if (rt_pic_irq_set_affinity(timer->irq, affinity) == -RT_ENOSYS)
216 {
217 LOG_E("timer irq affinity init fail\n");
218 }
219 else
220 {
221 LOG_D("timer irq(%d) binding done\n", timer->irq);
222 }
223 }
224
rk_timer_probe(struct rt_platform_device * pdev)225 static rt_err_t rk_timer_probe(struct rt_platform_device *pdev)
226 {
227 rt_err_t err = RT_EOK;
228 const char *dev_name;
229 struct rt_device *dev = &pdev->parent;
230 struct rk_timer *timer = rt_calloc(1, sizeof(*timer));
231 const struct rk_timer_data *timer_data = pdev->id->data;
232 if (!timer)
233 {
234 return -RT_ENOMEM;
235 }
236 #ifdef RT_USING_KTIME
237 _timer0.timer = timer;
238 rt_spin_lock_init(&_spinlock);
239 #endif
240 if (!(timer->pclk = rt_clk_get_by_name(dev, "pclk")))
241 {
242 err = -RT_EIO;
243
244 goto _fail;
245 }
246
247 if (!(timer->clk = rt_clk_get_by_name(dev, "timer")))
248 {
249 err = -RT_EIO;
250
251 goto _fail;
252 }
253
254 timer->base = rt_dm_dev_iomap(dev, 0);
255
256 if (!timer->base)
257 {
258 err = -RT_EIO;
259
260 goto _fail;
261 }
262
263 timer->ctrl = timer->base + timer_data->ctrl_reg;
264
265 rt_clk_enable(timer->pclk);
266 rt_clk_enable(timer->clk);
267 timer->freq = rt_clk_get_rate(timer->clk);
268 timer->irq = rt_dm_dev_get_irq(dev, 0);
269
270 rk_timer_interrupt_clear(timer);
271 rk_timer_disable(timer);
272
273 timer->parent.ops = &rk_timer_ops;
274 timer->parent.info = &timer->info;
275
276 timer->info.maxfreq = timer->freq;
277 timer->info.minfreq = timer->freq;
278 timer->info.maxcnt = 0xffffffff;
279 timer->info.cntmode = HWTIMER_CNTMODE_DW;
280
281 rt_dm_dev_set_name_auto(&timer->parent.parent, "timer");
282 dev_name = rt_dm_dev_get_name(&timer->parent.parent);
283
284 rt_device_hwtimer_register(&timer->parent, dev_name, RT_NULL);
285
286 RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = { 0 };
287 rt_bitmap_set_bit(affinity, RT_CPUS_NR - 1);
288 rt_ktime_hrtimer_bind(affinity);
289
290 rt_pic_attach_irq(timer->irq, rk_timer_isr, timer, dev_name, RT_IRQ_F_NONE);
291 rt_pic_irq_unmask(timer->irq);
292
293 #if KTIMER_BIND_CPU
294 RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = {0};
295 rt_bitmap_set_bit(affinity, 1);
296 rt_pic_irq_set_affinity(timer->irq, affinity);
297 #endif
298
299 return err;
300
301 _fail:
302 if (timer->base)
303 {
304 rt_iounmap(timer->base);
305 }
306 if (timer->pclk)
307 {
308 rt_clk_put(timer->pclk);
309 }
310 if (timer->clk)
311 {
312 rt_clk_put(timer->clk);
313 }
314 rt_free(timer);
315
316 return err;
317 }
318
319 static const struct rk_timer_data rk3288_timer_data =
320 {
321 .ctrl_reg = TIMER_CONTROL_REG3288,
322 };
323
324 static const struct rk_timer_data rk3399_timer_data =
325 {
326 .ctrl_reg = TIMER_CONTROL_REG3399,
327 };
328
329 #ifdef RT_USING_KTIME
330
rt_ktime_hrtimer_getfrq(void)331 uint64_t rt_ktime_hrtimer_getfrq(void)
332 {
333 return (24 * 1000 * 1000UL);
334 }
335
rt_ktime_hrtimer_getres(void)336 uint64_t rt_ktime_hrtimer_getres(void)
337 {
338 return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / (24 * 1000 * 1000UL);
339 }
340
rt_ktime_hrtimer_getcnt(void)341 uint64_t rt_ktime_hrtimer_getcnt(void)
342 {
343 return rk_timer_current_value(_timer0.timer);
344 }
345
346 /**
347 * @brief set the timeout function for hrtimer framework
348 *
349 * @warning application should not call this API directly
350 *
351 * @param cnt the count of timer dealy
352 * @return rt_err_t 0 forever
353 */
rt_ktime_hrtimer_settimeout(unsigned long cnt)354 rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt)
355 {
356 struct hrt_timer *timer = &_timer0;
357 struct rk_timer *time = timer->timer;
358
359 timer->cnt = cnt;
360
361 if (cnt)
362 {
363 rk_timer_disable(time);
364 rk_timer_update_counter(cnt, time);
365 rk_timer_enable(time, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK);
366 }
367
368 return 0;
369 }
370 #endif
371
372 static const struct rt_ofw_node_id rk_timer_ofw_ids[] =
373 {
374 { .compatible = "rockchip,rk3288-timer", .data = &rk3288_timer_data },
375 { .compatible = "rockchip,rk3399-timer", .data = &rk3399_timer_data },
376 { /* sentinel */ }
377 };
378
379 static struct rt_platform_driver rk_timer_driver =
380 {
381 .name = "hwtimer-rockchip",
382 .ids = rk_timer_ofw_ids,
383
384 .probe = rk_timer_probe,
385 };
386
rk_timer_drv_register(void)387 static int rk_timer_drv_register(void)
388 {
389 rt_platform_driver_register(&rk_timer_driver);
390
391 return 0;
392 }
393 INIT_PLATFORM_EXPORT(rk_timer_drv_register);
394