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