]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/zynq/timer.c
zynq: remove unused statistics fields from Mach structure
[plan9front.git] / sys / src / 9 / zynq / timer.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7
8 enum {
9         TIMERDIV = 1,
10         LTIMERDIV = 1,
11         
12         ARM_PLL_CTRL = 0x100/4,
13         ARM_CLK_CTRL = 0x120/4,
14
15         GTIMERVALL = 0x200/4,
16         GTIMERVALH,
17         GTIMERCTL,
18         LTIMERVAL = 0x604/4,
19         LTIMERCTL,
20         LTIMERISR,
21 };
22
23 uvlong timerhz;
24
25 void
26 microdelay(int n)
27 {
28         ulong now;
29
30         now = µs();
31         while(µs() - now < n);
32 }
33
34 void
35 delay(int n)
36 {
37         while(--n >= 0)
38                 microdelay(1000);
39 }
40
41 uvlong
42 fastticks(uvlong *hz)
43 {
44         ulong lo, hi;
45
46         if(hz != nil)
47                 *hz = timerhz;
48         do{
49                 hi = mpcore[GTIMERVALH];
50                 lo = mpcore[GTIMERVALL];
51         }while(hi != mpcore[GTIMERVALH]);
52         return lo | (uvlong)hi << 32;
53 }
54
55 ulong
56 µs(void)
57 {
58         return fastticks2us(fastticks(nil));
59 }
60
61 void
62 timerset(Tval v)
63 {
64         vlong w;
65
66         w = v - fastticks(nil);
67         if(w < 1)
68                 w = 1;
69         if(w > 0xffffffffLL)
70                 w = 0xffffffff;
71         mpcore[LTIMERCTL] &= ~1;
72         mpcore[LTIMERVAL] = w;
73         mpcore[LTIMERCTL] |= 1;
74 }
75
76 void
77 timerirq(Ureg *u, void *)
78 {
79         if((mpcore[LTIMERISR] & 1) != 0){
80                 mpcore[LTIMERISR] |= 1;
81                 timerintr(u, 0);
82         }
83 }
84
85 void
86 timerinit(void)
87 {
88         m->cpumhz = PS_CLK * (slcr[ARM_PLL_CTRL] >> 12 & 0x7f) / (slcr[ARM_CLK_CTRL] >> 8 & 0x3f);
89         m->cpuhz = m->cpumhz * 1000000;
90         timerhz = m->cpuhz / 2;
91         mpcore[GTIMERCTL] = TIMERDIV - 1 << 8 | 3;
92         mpcore[LTIMERCTL] = LTIMERDIV - 1 << 8 | 4;
93         intrenable(TIMERIRQ, timerirq, nil, EDGE, "clock");
94
95         /* enable and reset cycle counter register */
96         m->cyclefreq = m->cpuhz;
97         setpmcnten((1<<31));
98         coherence();
99         setpmcr(7);
100 }
101
102 /*
103  * synchronize all cpu's cycle counter registers
104  */
105 void
106 synccycles(void)
107 {
108         static Ref r1, r2;
109         int s;
110
111         s = splhi();
112         r2.ref = 0;
113         incref(&r1);
114         while(r1.ref != conf.nmach)
115                 ;
116         setpmcr(7);
117         m->cycleshi = MACHP(0)->cycleshi;
118         incref(&r2);
119         while(r2.ref != conf.nmach)
120                 ;
121         r1.ref = 0;
122         splx(s);
123 }