xref: /plan9-contrib/sys/src/boot/vt4/clock.c (revision da917039c7f233c1a27d212bf012c6afa758af39)
1 /* virtex[45] ppc4xx clock */
2 #include "include.h"
3 
4 uvlong clockintrs;
5 
6 void
delay(int l)7 delay(int l)
8 {
9 	ulong i, j;
10 
11 	j = m->delayloop;
12 	while(l-- > 0)
13 		for(i=0; i < j; i++)
14 			;
15 }
16 
17 void
microdelay(int l)18 microdelay(int l)
19 {
20 	ulong i;
21 
22 	l *= m->delayloop;
23 	l /= 1000;
24 	if(l <= 0)
25 		l = 1;
26 	for(i = 0; i < l; i++)
27 		;
28 }
29 
30 enum {
31 	Timebase = 1,	/* system clock cycles per time base cycle */
32 
33 	Wp17=	0<<30,	/* watchdog period (2^x clocks) */
34 	Wp21=	1<<30,
35 	Wp25=	2<<30,
36 	Wp29=	3<<30,
37 	Wrnone=	0<<28,	/* no watchdog reset */
38 	Wrcore=	1<<28,	/* core reset */
39 	Wrchip=	2<<28,	/* chip reset */
40 	Wrsys=	3<<28,	/* system reset */
41 	Wie=		1<<27,	/* watchdog interrupt enable */
42 	Pie=		1<<26,	/* enable PIT interrupt */
43 	Fit9=		0<<24,	/* fit period (2^x clocks) */
44 	Fit13=	1<<24,
45 	Fit17=	2<<24,
46 	Fit21=	3<<24,
47 	Fie=		1<<23,	/* fit interrupt enable */
48 	Are=		1<<22,	/* auto reload enable */
49 };
50 
51 void
prcpuid(void)52 prcpuid(void)
53 {
54 	ulong pvr;
55 	static char xilinx[] = "Xilinx ";
56 	static char ppc[] = "PowerPC";
57 
58 	pvr = getpvr();
59 	m->cputype = pvr >> 16;
60 	print("cpu%d: %ldMHz %#lux (", m->machno, m->cpuhz/1000000, pvr);
61 	switch (m->cputype) {
62 	case 0x1291: case 0x4011: case 0x41f1: case 0x5091: case 0x5121:
63 		print("%s 405", ppc);
64 		break;
65 	case 0x2001:			/* 200 is Xilinx, 1 is ppc405 */
66 		print(xilinx);
67 		switch (pvr & ~0xfff) {
68 		case 0x20010000:
69 			print("Virtex-II Pro %s 405", ppc);
70 			break;
71 		case 0x20011000:
72 			print("Virtex 4 FX %s 405D5X2", ppc);
73 			break;
74 		default:
75 			print("%s 405", ppc);
76 			break;
77 		}
78 		break;
79 	case 0x7ff2:
80 		print(xilinx);
81 		if ((pvr & ~0xf) == 0x7ff21910)
82 			print("Virtex 5 FXT %s 440X5", ppc);
83 		else
84 			print("%s 440", ppc);
85 		break;
86 	default:
87 		print(ppc);
88 		break;
89 	}
90 	print(")\n");
91 }
92 
93 void
clockinit(void)94 clockinit(void)
95 {
96 	int s;
97 	long x;
98 	vlong now;
99 
100 	s = splhi();
101 	m->clockgen = m->cpuhz = myhz;
102 	m->delayloop = m->cpuhz/1000;		/* initial estimate */
103 	do {
104 		x = gettbl();
105 		delay(10);
106 		x = gettbl() - x;
107 	} while(x < 0);
108 
109 	/*
110 	 *  fix count
111 	 */
112 	assert(x != 0);
113 	m->delayloop = ((vlong)m->delayloop * (10*(vlong)m->clockgen/1000)) /
114 		(x*Timebase);
115 	if((int)m->delayloop <= 0)
116 		m->delayloop = 20000;
117 
118 	x = (m->clockgen/Timebase)/HZ;
119 // print("initial PIT %ld\n", x);
120 	putpit(x);
121 	puttsr(~0);
122 	puttcr(Pie|Are);
123 	coherence();
124 	splx(s);
125 
126 	now = m->fastclock;
127 	x = 50000000UL;
128 	while (now == m->fastclock && x-- > 0)
129 		;
130 	if (now == m->fastclock)
131 		print("clock is NOT ticking\n");
132 }
133 
134 void
clockintr(Ureg * ureg)135 clockintr(Ureg *ureg)
136 {
137 	/* PIT was set to reload automatically */
138 	puttsr(~0);
139 	m->fastclock++;
140 	dcflush(PTR2UINT(&m->fastclock), sizeof m->fastclock); /* seems needed */
141 	clockintrs++;
142 	dcflush(PTR2UINT(&clockintrs), sizeof clockintrs);  /* seems needed */
143 	timerintr(ureg);
144 }
145