1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker * Copyright (c) 2008-2012 Travis Geiselbrecht
3*344aa361SAndroid Build Coastguard Worker *
4*344aa361SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker *
12*344aa361SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker *
15*344aa361SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker */
23*344aa361SAndroid Build Coastguard Worker #include <debug.h>
24*344aa361SAndroid Build Coastguard Worker #include <err.h>
25*344aa361SAndroid Build Coastguard Worker #include <kernel/thread.h>
26*344aa361SAndroid Build Coastguard Worker #include <platform.h>
27*344aa361SAndroid Build Coastguard Worker #include <platform/interrupts.h>
28*344aa361SAndroid Build Coastguard Worker #include <platform/timer.h>
29*344aa361SAndroid Build Coastguard Worker #include <platform/vexpress-a15.h>
30*344aa361SAndroid Build Coastguard Worker #include <sys/types.h>
31*344aa361SAndroid Build Coastguard Worker #include "platform_p.h"
32*344aa361SAndroid Build Coastguard Worker
33*344aa361SAndroid Build Coastguard Worker #define TIMREG(reg) (*REG32(TIMER0 + (reg)))
34*344aa361SAndroid Build Coastguard Worker
35*344aa361SAndroid Build Coastguard Worker #define LOADVAL (0x00)
36*344aa361SAndroid Build Coastguard Worker #define VAL (0x04)
37*344aa361SAndroid Build Coastguard Worker #define CONTROL (0x08)
38*344aa361SAndroid Build Coastguard Worker #define INTCLEAR (0x0c)
39*344aa361SAndroid Build Coastguard Worker #define RAWINTSTAT (0x10)
40*344aa361SAndroid Build Coastguard Worker #define MASKEDINTSTAT (0x14)
41*344aa361SAndroid Build Coastguard Worker
42*344aa361SAndroid Build Coastguard Worker static platform_timer_callback t_callback;
43*344aa361SAndroid Build Coastguard Worker
44*344aa361SAndroid Build Coastguard Worker static volatile uint ticks = 0;
45*344aa361SAndroid Build Coastguard Worker static lk_time_t periodic_interval;
46*344aa361SAndroid Build Coastguard Worker
platform_set_periodic_timer(platform_timer_callback callback,void * arg,lk_time_t interval)47*344aa361SAndroid Build Coastguard Worker status_t platform_set_periodic_timer(platform_timer_callback callback,
48*344aa361SAndroid Build Coastguard Worker void* arg,
49*344aa361SAndroid Build Coastguard Worker lk_time_t interval) {
50*344aa361SAndroid Build Coastguard Worker enter_critical_section();
51*344aa361SAndroid Build Coastguard Worker
52*344aa361SAndroid Build Coastguard Worker t_callback = callback;
53*344aa361SAndroid Build Coastguard Worker
54*344aa361SAndroid Build Coastguard Worker periodic_interval = interval;
55*344aa361SAndroid Build Coastguard Worker TIMREG(LOADVAL) = periodic_interval * 1000; /* timer is running at 1Mhz */
56*344aa361SAndroid Build Coastguard Worker
57*344aa361SAndroid Build Coastguard Worker TIMREG(CONTROL) |= (1 << 7); // enable
58*344aa361SAndroid Build Coastguard Worker
59*344aa361SAndroid Build Coastguard Worker unmask_interrupt(TIMER01_INT);
60*344aa361SAndroid Build Coastguard Worker
61*344aa361SAndroid Build Coastguard Worker exit_critical_section();
62*344aa361SAndroid Build Coastguard Worker
63*344aa361SAndroid Build Coastguard Worker return NO_ERROR;
64*344aa361SAndroid Build Coastguard Worker }
65*344aa361SAndroid Build Coastguard Worker
current_time_hires(void)66*344aa361SAndroid Build Coastguard Worker lk_bigtime_t current_time_hires(void) {
67*344aa361SAndroid Build Coastguard Worker lk_bigtime_t time;
68*344aa361SAndroid Build Coastguard Worker
69*344aa361SAndroid Build Coastguard Worker time = ticks * periodic_interval * 1000ULL;
70*344aa361SAndroid Build Coastguard Worker
71*344aa361SAndroid Build Coastguard Worker return time;
72*344aa361SAndroid Build Coastguard Worker }
73*344aa361SAndroid Build Coastguard Worker
current_time(void)74*344aa361SAndroid Build Coastguard Worker lk_time_t current_time(void) {
75*344aa361SAndroid Build Coastguard Worker lk_time_t time;
76*344aa361SAndroid Build Coastguard Worker
77*344aa361SAndroid Build Coastguard Worker time = ticks * periodic_interval;
78*344aa361SAndroid Build Coastguard Worker
79*344aa361SAndroid Build Coastguard Worker return time;
80*344aa361SAndroid Build Coastguard Worker }
81*344aa361SAndroid Build Coastguard Worker
platform_tick(void * arg)82*344aa361SAndroid Build Coastguard Worker static enum handler_return platform_tick(void* arg) {
83*344aa361SAndroid Build Coastguard Worker ticks++;
84*344aa361SAndroid Build Coastguard Worker TIMREG(INTCLEAR) = 1;
85*344aa361SAndroid Build Coastguard Worker if (t_callback) {
86*344aa361SAndroid Build Coastguard Worker return t_callback(arg, current_time());
87*344aa361SAndroid Build Coastguard Worker } else {
88*344aa361SAndroid Build Coastguard Worker return INT_NO_RESCHEDULE;
89*344aa361SAndroid Build Coastguard Worker }
90*344aa361SAndroid Build Coastguard Worker }
91*344aa361SAndroid Build Coastguard Worker
platform_init_timer(void)92*344aa361SAndroid Build Coastguard Worker void platform_init_timer(void) {
93*344aa361SAndroid Build Coastguard Worker /* disable timer */
94*344aa361SAndroid Build Coastguard Worker TIMREG(CONTROL) = 0;
95*344aa361SAndroid Build Coastguard Worker
96*344aa361SAndroid Build Coastguard Worker /* periodic mode, ints enabled, 32bit, wrapping */
97*344aa361SAndroid Build Coastguard Worker TIMREG(CONTROL) = (1 << 6) | (1 << 5) | (1 << 1);
98*344aa361SAndroid Build Coastguard Worker
99*344aa361SAndroid Build Coastguard Worker register_int_handler(TIMER01_INT, &platform_tick, NULL);
100*344aa361SAndroid Build Coastguard Worker }
101