1 /*
2 * Copyright (c) 2015 MediaTek Inc.
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <sys/types.h>
9 #include <lk/debug.h>
10 #include <lk/err.h>
11 #include <lk/reg.h>
12 #include <kernel/thread.h>
13 #include <mt_gic.h>
14 #include <platform/timer.h>
15 #include <platform/mt_typedefs.h>
16 #include <platform/mt_reg_base.h>
17 #include <platform/mt_gpt.h>
18 #include <platform/mt_irq.h>
19
20 #define TIMER_TICK_RATE 32768
21
22 static volatile lk_time_t ticks = 0;
23 static lk_time_t tick_interval;
24 static platform_timer_callback time_callback;
25 static void *callback_arg;
26
timer_irq(void * arg)27 static enum handler_return timer_irq(void *arg) {
28 ticks += tick_interval;
29 return time_callback(callback_arg, ticks);
30 }
31
lk_scheduler(void)32 enum handler_return lk_scheduler(void) {
33 static enum handler_return ret;
34
35 /* ack GPT5 irq */
36 DRV_WriteReg32(GPT_IRQACK_REG, 0x10);
37 DRV_WriteReg32(GPT5_CON_REG, GPT_CLEAR);
38 DRV_WriteReg32(GPT5_CON_REG, GPT_DISABLE);
39
40 ret = timer_irq(0);
41
42 /* ack GIC irq */
43 mt_irq_ack(MT_GPT_IRQ_ID);
44
45 /* enable GPT5 */
46 DRV_WriteReg32(GPT5_CON_REG, GPT_ENABLE|GPT_MODE4_ONE_SHOT);
47
48 return ret;
49 }
50
platform_set_periodic_timer(platform_timer_callback callback,void * arg,lk_time_t interval)51 status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval) {
52 time_callback = callback;
53 tick_interval = interval;
54 callback_arg = arg;
55
56 DRV_WriteReg32(GPT_IRQEN_REG, 0);
57 DRV_WriteReg32(GPT_IRQACK_REG, 0x3f);
58
59 mt_irq_set_sens(MT_GPT_IRQ_ID, MT65xx_LEVEL_SENSITIVE);
60 mt_irq_set_polarity(MT_GPT_IRQ_ID, MT65xx_POLARITY_LOW);
61
62 DRV_WriteReg32(GPT5_CON_REG, 0x02);
63 DRV_WriteReg32(GPT_IRQACK_REG, 0x10);
64 DRV_WriteReg32(GPT5_CLK_REG, 0x10);
65
66 DRV_WriteReg32(GPT5_COMPARE_REG, TIMER_TICK_RATE*interval/1000);
67 DRV_WriteReg32(GPT_IRQEN_REG, 0x10);
68
69 mt_irq_unmask(MT_GPT_IRQ_ID);
70
71 DRV_WriteReg32(GPT5_CON_REG, GPT_ENABLE|GPT_MODE4_ONE_SHOT);
72
73 return NO_ERROR;
74 }
75
current_time(void)76 lk_time_t current_time(void) {
77 return ticks;
78 }
79
current_time_hires(void)80 lk_bigtime_t current_time_hires(void) {
81 lk_bigtime_t time;
82
83 time = (lk_bigtime_t)ticks * 1000;
84 return time;
85 }
86
87