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