xref: /plan9-contrib/sys/src/9/vt5/clock.c (revision 1c9d674cbfa2c1924558af05e99c43e5c5cd4845)
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