]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/omap4/clock.c
kernel: add portable uncached memory allocator (ucalloc) (from sources)
[plan9front.git] / sys / src / 9 / omap4 / clock.c
1 #include "u.h"
2 #include "ureg.h"
3 #include "../port/lib.h"
4 #include "mem.h"
5 #include "dat.h"
6 #include "fns.h"
7 #include "io.h"
8
9 extern uchar *periph;
10 ulong *global, *local;
11 enum {
12         PERIPHCLK = 506965000,
13         MaxPeriod = PERIPHCLK / (256 * 100),
14         MinPeriod = MaxPeriod / 100,
15 } ;
16
17 void
18 globalclockinit(void)
19 {
20         global = (ulong*) (periph + 0x200);
21         local = (ulong*) (periph + 0x600);
22         global[2] &= 0xFFFF00F0;
23         global[0] = 0;
24         global[1] = 0;
25         global[2] |= 1;
26 }
27
28 void
29 cycles(uvlong *x)
30 {
31         ulong hi, newhi, lo, *y;
32         
33         newhi = global[1];
34         do{
35                 hi = newhi;
36                 lo = global[0];
37         }while((newhi = global[1]) != hi);
38         y = (ulong *) x;
39         y[0] = lo;
40         y[1] = hi;
41 }
42
43 uvlong
44 fastticks(uvlong *hz)
45 {
46         uvlong ret;
47
48         if(hz != nil)
49                 *hz = PERIPHCLK;
50         cycles(&ret);
51         return ret;
52 }
53
54 ulong
55 µs(void)
56 {
57         return fastticks2us(fastticks(nil));
58 }
59
60
61 ulong
62 perfticks(void)
63 {
64         return global[0];
65 }
66
67 void
68 clocktick(Ureg* ureg, void *)
69 {
70         timerintr(ureg, 0);
71 }
72
73 void
74 localclockinit(void)
75 {
76         local[2] = 0xFF06;
77         intenable(29, clocktick, nil);
78         timerset(0);
79 }
80
81 void
82 timerset(uvlong val)
83 {
84         uvlong now, ticks;
85
86         if(val == 0)
87                 ticks = MaxPeriod;
88         else{
89                 cycles(&now);
90                 ticks = (val - now) / 256;
91                 if(ticks < MinPeriod)
92                         ticks = MinPeriod;
93                 if(ticks > MaxPeriod)
94                         ticks = MaxPeriod;
95         }
96         local[2] &= ~1;
97         local[0] = local[1] = ticks;
98         local[2] |= 1;
99 }
100
101 static void
102 waituntil(uvlong n)
103 {
104         uvlong now, then;
105         
106         cycles(&now);
107         then = now + n;
108         while(now < then)
109                 cycles(&now);
110 }
111
112 void
113 microdelay(int n)
114 {
115         waituntil(((uvlong)n) * PERIPHCLK / 1000000);
116 }
117
118 void
119 delay(int n)
120 {
121         waituntil(((uvlong)n) * PERIPHCLK / 1000);
122 }
123