1 /*
2 * Copyright (c) 2008 Travis Geiselbrecht
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 <platform/timer.h>
13 #include <platform/mt_typedefs.h>
14 #include <platform/mt_reg_base.h>
15 #include <platform/mt_gpt.h>
16 #include <platform/mt_irq.h>
17
18 #include <kernel/thread.h>
19
20 static volatile lk_time_t ticks = 0;
21 static lk_time_t tick_interval;
22
23 static platform_timer_callback time_callback;
24 static void *callback_arg;
25
26 #define AP_PERI_GLOBALCON_PDN0 (PERICFG_BASE+0x10)
27
28 #define TIMER_TICK_RATE 32768
29
timer_irq(void * arg)30 static enum handler_return timer_irq(void *arg) {
31 ticks += tick_interval;
32 return time_callback(callback_arg, ticks);
33 }
34
lk_scheduler(void)35 void lk_scheduler(void) {
36 //static enum handler_return ret;
37
38 /* ack GPT5 irq */
39 DRV_WriteReg32(GPT_IRQACK_REG, 0x10);
40 DRV_WriteReg32(GPT5_CON_REG, GPT_CLEAR);
41 DRV_WriteReg32(GPT5_CON_REG, GPT_DISABLE);
42
43 timer_irq(0);
44
45 /*
46 * CAUTION! The de-assert signal to GIC might delay serveral clocks.
47 * Here must have enough delay to make sure the GPT signal had arrived GIC.
48 */
49 /* ack GIC irq */
50 mt_irq_ack(MT_GPT_IRQ_ID);
51
52 /* enable GPT5 */
53 DRV_WriteReg32(GPT5_CON_REG, GPT_ENABLE|GPT_MODE4_ONE_SHOT);
54
55 }
56
platform_set_periodic_timer(platform_timer_callback callback,void * arg,lk_time_t interval)57 status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval) {
58 time_callback = callback;
59 tick_interval = interval;
60 callback_arg = arg;
61
62 DRV_WriteReg32(GPT_IRQEN_REG, 0);
63 DRV_WriteReg32(GPT_IRQACK_REG, 0x3f);
64
65 mt_irq_set_sens(MT_GPT_IRQ_ID, MT65xx_LEVEL_SENSITIVE);
66 mt_irq_set_polarity(MT_GPT_IRQ_ID, MT65xx_POLARITY_LOW);
67
68 DRV_WriteReg32(GPT5_CON_REG, 0x02);
69 DRV_WriteReg32(GPT_IRQACK_REG, 0x10);
70 DRV_WriteReg32(GPT5_CLK_REG, 0x10);
71
72 DRV_WriteReg32(GPT5_COMPARE_REG, TIMER_TICK_RATE*interval/1000);
73 DRV_WriteReg32(GPT_IRQEN_REG, 0x10);
74
75 mt_irq_unmask(MT_GPT_IRQ_ID);
76
77 DRV_WriteReg32(GPT5_CON_REG, GPT_ENABLE|GPT_MODE4_ONE_SHOT);
78
79 return NO_ERROR;
80 }
81
current_time(void)82 lk_time_t current_time(void) {
83 return ticks;
84 }
85
current_time_hires(void)86 lk_bigtime_t current_time_hires(void) {
87 lk_bigtime_t time;
88
89 time = (lk_bigtime_t)ticks * 1000;
90 return time;
91 }
92
gpt_power_on(bool bPowerOn)93 static void gpt_power_on (bool bPowerOn) {
94 if (!bPowerOn) {
95 DRV_SetReg32(AP_PERI_GLOBALCON_PDN0, 1<<13);
96 } else {
97 DRV_ClrReg32(AP_PERI_GLOBALCON_PDN0, 1<<13);
98 }
99 }
100
platform_early_init_timer(void)101 void platform_early_init_timer(void) {
102 //dprintf(SPEW, "platform_early_init_timer\n");
103
104 gpt_power_on(1);
105 }
106