1*1c9d674cSDavid du Colombier /* ppc440 clock */
2*1c9d674cSDavid du Colombier #include "u.h"
3*1c9d674cSDavid du Colombier #include "../port/lib.h"
4*1c9d674cSDavid du Colombier #include "mem.h"
5*1c9d674cSDavid du Colombier #include "dat.h"
6*1c9d674cSDavid du Colombier #include "fns.h"
7*1c9d674cSDavid du Colombier
8*1c9d674cSDavid du Colombier void
delay(int l)9*1c9d674cSDavid du Colombier delay(int l)
10*1c9d674cSDavid du Colombier {
11*1c9d674cSDavid du Colombier ulong i, j;
12*1c9d674cSDavid du Colombier
13*1c9d674cSDavid du Colombier j = m->delayloop;
14*1c9d674cSDavid du Colombier while(l-- > 0)
15*1c9d674cSDavid du Colombier for(i=0; i < j; i++)
16*1c9d674cSDavid du Colombier ;
17*1c9d674cSDavid du Colombier }
18*1c9d674cSDavid du Colombier
19*1c9d674cSDavid du Colombier void
microdelay(int l)20*1c9d674cSDavid du Colombier microdelay(int l)
21*1c9d674cSDavid du Colombier {
22*1c9d674cSDavid du Colombier ulong i;
23*1c9d674cSDavid du Colombier
24*1c9d674cSDavid du Colombier l *= m->delayloop;
25*1c9d674cSDavid du Colombier l /= 1000;
26*1c9d674cSDavid du Colombier if(l <= 0)
27*1c9d674cSDavid du Colombier l = 1;
28*1c9d674cSDavid du Colombier for(i = 0; i < l; i++)
29*1c9d674cSDavid du Colombier ;
30*1c9d674cSDavid du Colombier }
31*1c9d674cSDavid du Colombier
32*1c9d674cSDavid du Colombier enum {
33*1c9d674cSDavid du Colombier Timebase = 1, /* system clock cycles per time base cycle */
34*1c9d674cSDavid du Colombier
35*1c9d674cSDavid du Colombier Wp21= 0<<30, /* watchdog period (2^x clocks) */
36*1c9d674cSDavid du Colombier Wp25= 1<<30,
37*1c9d674cSDavid du Colombier Wp29= 2<<30,
38*1c9d674cSDavid du Colombier Wp33= 3<<30,
39*1c9d674cSDavid du Colombier Wrnone= 0<<28, /* no watchdog reset */
40*1c9d674cSDavid du Colombier Wrcore= 1<<28, /* core reset */
41*1c9d674cSDavid du Colombier Wrchip= 2<<28, /* chip reset */
42*1c9d674cSDavid du Colombier Wrsys= 3<<28, /* system reset */
43*1c9d674cSDavid du Colombier Wie= 1<<27, /* watchdog interrupt enable */
44*1c9d674cSDavid du Colombier Pie= 1<<26, /* enable PIT interrupt */
45*1c9d674cSDavid du Colombier Fit13= 0<<24, /* fit period (2^x clocks) */
46*1c9d674cSDavid du Colombier Fit17= 1<<24,
47*1c9d674cSDavid du Colombier Fit21= 2<<24,
48*1c9d674cSDavid du Colombier Fit25= 3<<24,
49*1c9d674cSDavid du Colombier Fie= 1<<23, /* fit interrupt enable */
50*1c9d674cSDavid du Colombier Are= 1<<22, /* auto reload enable */
51*1c9d674cSDavid du Colombier
52*1c9d674cSDavid du Colombier /* dcr */
53*1c9d674cSDavid du Colombier Boot= 0x0F1,
54*1c9d674cSDavid du Colombier Epctl= 0x0F3,
55*1c9d674cSDavid du Colombier Pllmr0= 0x0F0,
56*1c9d674cSDavid du Colombier Pllmr1= 0x0F4,
57*1c9d674cSDavid du Colombier Ucr= 0x0F5,
58*1c9d674cSDavid du Colombier };
59*1c9d674cSDavid du Colombier
60*1c9d674cSDavid du Colombier void (*archclocktick)(void); /* set by arch*.c if used */
61*1c9d674cSDavid du Colombier
62*1c9d674cSDavid du Colombier void
clockinit(void)63*1c9d674cSDavid du Colombier clockinit(void)
64*1c9d674cSDavid du Colombier {
65*1c9d674cSDavid du Colombier long x;
66*1c9d674cSDavid du Colombier
67*1c9d674cSDavid du Colombier m->delayloop = m->cpuhz/1000; /* initial estimate */
68*1c9d674cSDavid du Colombier do {
69*1c9d674cSDavid du Colombier x = gettbl();
70*1c9d674cSDavid du Colombier delay(10);
71*1c9d674cSDavid du Colombier x = gettbl() - x;
72*1c9d674cSDavid du Colombier } while(x < 0);
73*1c9d674cSDavid du Colombier
74*1c9d674cSDavid du Colombier /*
75*1c9d674cSDavid du Colombier * fix count
76*1c9d674cSDavid du Colombier */
77*1c9d674cSDavid du Colombier m->delayloop = ((vlong)m->delayloop * (10*(vlong)m->clockgen/1000)) /
78*1c9d674cSDavid du Colombier (x*Timebase);
79*1c9d674cSDavid du Colombier if((int)m->delayloop <= 0)
80*1c9d674cSDavid du Colombier m->delayloop = 20000;
81*1c9d674cSDavid du Colombier
82*1c9d674cSDavid du Colombier x = (m->clockgen/Timebase)/HZ;
83*1c9d674cSDavid du Colombier putpit(x);
84*1c9d674cSDavid du Colombier puttsr(~0);
85*1c9d674cSDavid du Colombier /* not sure if we want Wrnone or Wrcore */
86*1c9d674cSDavid du Colombier // puttcr(Pie|Are|Wie|Wrcore|Wp29);
87*1c9d674cSDavid du Colombier puttcr(Pie|Are|Wrnone);
88*1c9d674cSDavid du Colombier }
89*1c9d674cSDavid du Colombier
90*1c9d674cSDavid du Colombier void
clockintr(Ureg * ureg)91*1c9d674cSDavid du Colombier clockintr(Ureg *ureg)
92*1c9d674cSDavid du Colombier {
93*1c9d674cSDavid du Colombier /* PIT was set to reload automatically */
94*1c9d674cSDavid du Colombier puttsr(~0);
95*1c9d674cSDavid du Colombier m->fastclock++;
96*1c9d674cSDavid du Colombier timerintr(ureg, 0);
97*1c9d674cSDavid du Colombier if(archclocktick != nil)
98*1c9d674cSDavid du Colombier archclocktick();
99*1c9d674cSDavid du Colombier }
100*1c9d674cSDavid du Colombier
101*1c9d674cSDavid du Colombier uvlong
fastticks(uvlong * hz)102*1c9d674cSDavid du Colombier fastticks(uvlong *hz)
103*1c9d674cSDavid du Colombier {
104*1c9d674cSDavid du Colombier if(hz)
105*1c9d674cSDavid du Colombier *hz = HZ;
106*1c9d674cSDavid du Colombier return m->fastclock;
107*1c9d674cSDavid du Colombier }
108*1c9d674cSDavid du Colombier
109*1c9d674cSDavid du Colombier ulong
s(void)110*1c9d674cSDavid du Colombier µs(void)
111*1c9d674cSDavid du Colombier {
112*1c9d674cSDavid du Colombier return fastticks2us(m->fastclock);
113*1c9d674cSDavid du Colombier }
114*1c9d674cSDavid du Colombier
115*1c9d674cSDavid du Colombier void
timerset(uvlong)116*1c9d674cSDavid du Colombier timerset(uvlong)
117*1c9d674cSDavid du Colombier {
118*1c9d674cSDavid du Colombier }
119*1c9d674cSDavid du Colombier
120*1c9d674cSDavid du Colombier ulong
perfticks(void)121*1c9d674cSDavid du Colombier perfticks(void)
122*1c9d674cSDavid du Colombier {
123*1c9d674cSDavid du Colombier return (ulong)fastticks(nil);
124*1c9d674cSDavid du Colombier }
125*1c9d674cSDavid du Colombier
126*1c9d674cSDavid du Colombier long
lcycles(void)127*1c9d674cSDavid du Colombier lcycles(void)
128*1c9d674cSDavid du Colombier {
129*1c9d674cSDavid du Colombier return perfticks();
130*1c9d674cSDavid du Colombier }
131