bcu_vrip.c revision 1.10.2.5 1 1.10.2.5 jdolecek /* $NetBSD: bcu_vrip.c,v 1.10.2.5 2002/10/10 18:33:00 jdolecek Exp $ */
2 1.1 takemura
3 1.1 takemura /*-
4 1.7 sato * Copyright (c) 1999-2001 SATO Kazumi. All rights reserved.
5 1.10.2.4 jdolecek * Copyright (c) 1999, 2002 PocketBSD Project. All rights reserved.
6 1.1 takemura *
7 1.1 takemura * Redistribution and use in source and binary forms, with or without
8 1.1 takemura * modification, are permitted provided that the following conditions
9 1.1 takemura * are met:
10 1.1 takemura * 1. Redistributions of source code must retain the above copyright
11 1.1 takemura * notice, this list of conditions and the following disclaimer.
12 1.1 takemura * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 takemura * notice, this list of conditions and the following disclaimer in the
14 1.1 takemura * documentation and/or other materials provided with the distribution.
15 1.1 takemura * 3. All advertising materials mentioning features or use of this software
16 1.1 takemura * must display the following acknowledgement:
17 1.1 takemura * This product includes software developed by the PocketBSD project
18 1.1 takemura * and its contributors.
19 1.1 takemura * 4. Neither the name of the project nor the names of its contributors
20 1.1 takemura * may be used to endorse or promote products derived from this software
21 1.1 takemura * without specific prior written permission.
22 1.1 takemura *
23 1.1 takemura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 takemura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 takemura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 takemura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 1.1 takemura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 takemura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 takemura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 takemura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 takemura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 takemura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 takemura * SUCH DAMAGE.
34 1.1 takemura *
35 1.1 takemura */
36 1.1 takemura
37 1.1 takemura #include <sys/param.h>
38 1.1 takemura #include <sys/systm.h>
39 1.1 takemura #include <sys/device.h>
40 1.1 takemura #include <sys/reboot.h>
41 1.1 takemura
42 1.1 takemura #include <machine/bus.h>
43 1.10.2.3 jdolecek #include <machine/debug.h>
44 1.10.2.4 jdolecek #include <machine/platid.h>
45 1.10.2.4 jdolecek #include <machine/platid_mask.h>
46 1.1 takemura
47 1.1 takemura #include <mips/cpuregs.h>
48 1.1 takemura
49 1.7 sato #include "opt_vr41xx.h"
50 1.1 takemura #include <hpcmips/vr/vr.h>
51 1.7 sato #include <hpcmips/vr/vrcpudef.h>
52 1.10.2.3 jdolecek #include <hpcmips/vr/vripif.h>
53 1.1 takemura #include <hpcmips/vr/vripvar.h>
54 1.1 takemura #include <hpcmips/vr/vripreg.h>
55 1.1 takemura #include <hpcmips/vr/bcureg.h>
56 1.1 takemura #include <hpcmips/vr/bcuvar.h>
57 1.1 takemura
58 1.10.2.2 thorpej static int vrbcu_match(struct device *, struct cfdata *, void *);
59 1.10.2.2 thorpej static void vrbcu_attach(struct device *, struct device *, void *);
60 1.1 takemura
61 1.10.2.2 thorpej static void vrbcu_write(struct vrbcu_softc *, int, unsigned short);
62 1.10.2.2 thorpej static unsigned short vrbcu_read(struct vrbcu_softc *, int);
63 1.2 sato
64 1.10.2.2 thorpej static void vrbcu_dump_regs(void);
65 1.5 sato
66 1.2 sato char *vr_cpuname=NULL;
67 1.2 sato int vr_major=-1;
68 1.2 sato int vr_minor=-1;
69 1.2 sato int vr_cpuid=-1;
70 1.1 takemura
71 1.10.2.5 jdolecek CFATTACH_DECL(vrbcu, sizeof(struct vrbcu_softc),
72 1.10.2.5 jdolecek vrbcu_match, vrbcu_attach, NULL, NULL);
73 1.1 takemura
74 1.3 sato struct vrbcu_softc *the_bcu_sc = NULL;
75 1.3 sato
76 1.10.2.4 jdolecek #ifdef SINGLE_VRIP_BASE
77 1.10.2.4 jdolecek #define vrbcu_addr() VRIP_BCU_ADDR
78 1.10.2.4 jdolecek #else
79 1.10.2.4 jdolecek static bus_addr_t vrbcu_addr(void);
80 1.10.2.4 jdolecek static bus_addr_t
81 1.10.2.4 jdolecek vrbcu_addr()
82 1.10.2.4 jdolecek {
83 1.10.2.4 jdolecek static bus_addr_t addr = NULL;
84 1.10.2.4 jdolecek static struct platid_data addrs[] = {
85 1.10.2.4 jdolecek { &platid_mask_CPU_MIPS_VR_4102, (void *)VR4102_BCU_ADDR },
86 1.10.2.4 jdolecek { &platid_mask_CPU_MIPS_VR_4111, (void *)VR4102_BCU_ADDR },
87 1.10.2.4 jdolecek { &platid_mask_CPU_MIPS_VR_4121, (void *)VR4102_BCU_ADDR },
88 1.10.2.4 jdolecek { &platid_mask_CPU_MIPS_VR_4122, (void *)VR4122_BCU_ADDR },
89 1.10.2.4 jdolecek { &platid_mask_CPU_MIPS_VR_4131, (void *)VR4122_BCU_ADDR },
90 1.10.2.4 jdolecek { &platid_mask_CPU_MIPS_VR_4181, (void *)VR4181_BCU_ADDR },
91 1.10.2.4 jdolecek { NULL, NULL } /* terminator, don't delete */
92 1.10.2.4 jdolecek };
93 1.10.2.4 jdolecek struct platid_data *p;
94 1.10.2.4 jdolecek
95 1.10.2.4 jdolecek if (addr == NULL) {
96 1.10.2.4 jdolecek if ((p = platid_search_data(&platid, addrs)) == NULL)
97 1.10.2.5 jdolecek panic("%s: can't find VR BCU address", __FUNCTION__);
98 1.10.2.4 jdolecek addr = (bus_addr_t)p->data;
99 1.10.2.4 jdolecek }
100 1.10.2.4 jdolecek
101 1.10.2.4 jdolecek return (addr);
102 1.10.2.4 jdolecek }
103 1.10.2.4 jdolecek #endif /* SINGLE_VRIP_BASE */
104 1.10.2.4 jdolecek
105 1.3 sato static inline void
106 1.10.2.2 thorpej vrbcu_write(struct vrbcu_softc *sc, int port, unsigned short val)
107 1.3 sato {
108 1.10.2.2 thorpej
109 1.3 sato bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
110 1.3 sato }
111 1.3 sato
112 1.3 sato static inline unsigned short
113 1.10.2.2 thorpej vrbcu_read(struct vrbcu_softc *sc, int port)
114 1.3 sato {
115 1.10.2.2 thorpej
116 1.10.2.2 thorpej return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, port));
117 1.3 sato }
118 1.3 sato
119 1.1 takemura static int
120 1.10.2.2 thorpej vrbcu_match(struct device *parent, struct cfdata *cf, void *aux)
121 1.1 takemura {
122 1.10.2.2 thorpej
123 1.10.2.2 thorpej return (2);
124 1.1 takemura }
125 1.1 takemura
126 1.1 takemura static void
127 1.10.2.2 thorpej vrbcu_attach(struct device *parent, struct device *self, void *aux)
128 1.1 takemura {
129 1.1 takemura struct vrip_attach_args *va = aux;
130 1.3 sato struct vrbcu_softc *sc = (struct vrbcu_softc *)self;
131 1.1 takemura
132 1.3 sato sc->sc_iot = va->va_iot;
133 1.3 sato bus_space_map(sc->sc_iot, va->va_addr, va->va_size,
134 1.10.2.2 thorpej 0, /* no flags */
135 1.10.2.2 thorpej &sc->sc_ioh);
136 1.1 takemura
137 1.1 takemura printf("\n");
138 1.3 sato the_bcu_sc = sc;
139 1.5 sato vrbcu_dump_regs();
140 1.5 sato }
141 1.5 sato
142 1.5 sato static void
143 1.5 sato vrbcu_dump_regs()
144 1.5 sato {
145 1.5 sato struct vrbcu_softc *sc = the_bcu_sc;
146 1.7 sato int cpuclock = 0, tclock = 0, vtclock = 0, cpuid;
147 1.8 sato #if !defined(ONLY_VR4102)
148 1.7 sato int spdreg;
149 1.7 sato #endif
150 1.7 sato #ifdef VRBCUDEBUG
151 1.5 sato int reg;
152 1.7 sato #endif /* VRBCUDEBUG */
153 1.5 sato
154 1.7 sato cpuid = vrbcu_vrip_getcpuid();
155 1.8 sato #if !defined(ONLY_VR4181) && !defined(ONLY_VR4102)
156 1.7 sato if (cpuid != BCUREVID_FIXRID_4181
157 1.10.2.2 thorpej && cpuid <= BCUREVID_RID_4131
158 1.10.2.2 thorpej && cpuid >= BCUREVID_RID_4111) {
159 1.7 sato spdreg = vrbcu_read(sc, BCUCLKSPEED_REG_W);
160 1.5 sato #ifdef VRBCUDEBUG
161 1.7 sato printf("vrbcu: CLKSPEED %x: \n", spdreg);
162 1.7 sato #endif /* VRBCUDEBUG */
163 1.7 sato }
164 1.7 sato #endif
165 1.8 sato #if defined VR4181
166 1.8 sato if (cpuid == BCUREVID_FIXRID_4181){
167 1.8 sato spdreg = vrbcu_read(sc, BCU81CLKSPEED_REG_W);
168 1.8 sato #ifdef VRBCUDEBUG
169 1.8 sato printf("vrbcu: CLKSPEED %x: \n", spdreg);
170 1.8 sato #endif /* VRBCUDEBUG */
171 1.8 sato }
172 1.8 sato #endif
173 1.7 sato
174 1.5 sato cpuclock = vrbcu_vrip_getcpuclock();
175 1.5 sato
176 1.5 sato switch (cpuid) {
177 1.8 sato #if defined VR4181
178 1.7 sato case BCUREVID_FIXRID_4181:
179 1.10.2.2 thorpej switch ((spdreg & BCU81CLKSPEED_DIVTMASK) >>
180 1.10.2.2 thorpej BCU81CLKSPEED_DIVTSHFT){
181 1.8 sato case BCU81CLKSPEED_DIVT1:
182 1.8 sato vtclock = tclock = cpuclock;
183 1.8 sato break;
184 1.8 sato case BCU81CLKSPEED_DIVT2:
185 1.8 sato vtclock = tclock = cpuclock/2;
186 1.8 sato break;
187 1.8 sato case BCU81CLKSPEED_DIVT3:
188 1.8 sato vtclock = tclock = cpuclock/3;
189 1.8 sato break;
190 1.8 sato case BCU81CLKSPEED_DIVT4:
191 1.8 sato vtclock = tclock = cpuclock/4;
192 1.8 sato break;
193 1.8 sato default:
194 1.8 sato vtclock = tclock = 0;
195 1.8 sato }
196 1.8 sato break;
197 1.8 sato #endif /* VR4181 */
198 1.5 sato case BCUREVID_RID_4101:
199 1.5 sato case BCUREVID_RID_4102:
200 1.5 sato vtclock = tclock = cpuclock/2;
201 1.5 sato break;
202 1.7 sato #if defined VR4111
203 1.5 sato case BCUREVID_RID_4111:
204 1.7 sato if ((spdreg&BCUCLKSPEED_DIVT2B) == 0)
205 1.5 sato vtclock = tclock = cpuclock/2;
206 1.7 sato else if ((spdreg&BCUCLKSPEED_DIVT3B) == 0)
207 1.5 sato vtclock = tclock = cpuclock/3;
208 1.7 sato else if ((spdreg&BCUCLKSPEED_DIVT4B) == 0)
209 1.5 sato vtclock = tclock = cpuclock/4;
210 1.5 sato else
211 1.5 sato vtclock = tclock = 0; /* XXX */
212 1.5 sato break;
213 1.7 sato #endif /* VR4111 */
214 1.7 sato #if defined VR4121
215 1.5 sato case BCUREVID_RID_4121:
216 1.10.2.2 thorpej {
217 1.10.2.2 thorpej int vt;
218 1.10.2.2 thorpej tclock = cpuclock / ((spdreg & BCUCLKSPEED_DIVTMASK) >>
219 1.10.2.2 thorpej BCUCLKSPEED_DIVTSHFT);
220 1.10.2.2 thorpej vt = ((spdreg & BCUCLKSPEED_DIVVTMASK) >>
221 1.10.2.2 thorpej BCUCLKSPEED_DIVVTSHFT);
222 1.10.2.2 thorpej if (vt == 0)
223 1.10.2.2 thorpej vtclock = 0; /* XXX */
224 1.10.2.2 thorpej else if (vt < 0x9)
225 1.10.2.2 thorpej vtclock = cpuclock / vt;
226 1.10.2.2 thorpej else
227 1.10.2.2 thorpej vtclock = cpuclock / ((vt - 8)*2+1) * 2;
228 1.10.2.2 thorpej }
229 1.10.2.2 thorpej break;
230 1.7 sato #endif /* VR4121 */
231 1.10.2.1 thorpej #if defined VR4122 || defined VR4131
232 1.9 enami case BCUREVID_RID_4122:
233 1.10.2.1 thorpej case BCUREVID_RID_4131:
234 1.10.2.2 thorpej {
235 1.10.2.2 thorpej int vtdiv;
236 1.9 enami
237 1.10.2.2 thorpej vtdiv = ((spdreg & BCUCLKSPEED_VTDIVMODE) >>
238 1.10.2.2 thorpej BCUCLKSPEED_VTDIVSHFT);
239 1.10.2.2 thorpej if (vtdiv == 0 || vtdiv > BCUCLKSPEED_VTDIV6)
240 1.10.2.2 thorpej vtclock = 0; /* XXX */
241 1.10.2.2 thorpej else
242 1.10.2.2 thorpej vtclock = cpuclock / vtdiv;
243 1.10.2.2 thorpej tclock = vtclock /
244 1.10.2.2 thorpej (((spdreg & BCUCLKSPEED_TDIVMODE) >>
245 1.10.2.2 thorpej BCUCLKSPEED_TDIVSHFT) ? 4 : 2);
246 1.10.2.2 thorpej }
247 1.10.2.2 thorpej break;
248 1.10.2.1 thorpej #endif /* VR4122 || VR4131 */
249 1.5 sato default:
250 1.5 sato break;
251 1.5 sato }
252 1.7 sato if (tclock)
253 1.7 sato printf("%s: cpu %d.%03dMHz, bus %d.%03dMHz, ram %d.%03dMHz\n",
254 1.10.2.2 thorpej sc->sc_dev.dv_xname,
255 1.10.2.2 thorpej cpuclock/1000000, (cpuclock%1000000)/1000,
256 1.10.2.2 thorpej tclock/1000000, (tclock%1000000)/1000,
257 1.10.2.2 thorpej vtclock/1000000, (vtclock%1000000)/1000);
258 1.7 sato else {
259 1.7 sato printf("%s: cpu %d.%03dMHz\n",
260 1.10.2.2 thorpej sc->sc_dev.dv_xname,
261 1.10.2.2 thorpej cpuclock/1000000, (cpuclock%1000000)/1000);
262 1.10.2.2 thorpej printf("%s: UNKNOWN BUS CLOCK SPEED:"
263 1.10.2.2 thorpej " CPU is UNKNOWN or NOT CONFIGURED\n",
264 1.10.2.2 thorpej sc->sc_dev.dv_xname);
265 1.7 sato }
266 1.5 sato #ifdef VRBCUDEBUG
267 1.7 sato reg = vrbcu_read(sc, BCUCNT1_REG_W);
268 1.7 sato printf("vrbcu: CNT1 %x: ", reg);
269 1.10.2.3 jdolecek dbg_bit_print(reg);
270 1.7 sato #if !defined(ONLY_VR4181)
271 1.7 sato if (cpuid != BCUREVID_FIXRID_4181
272 1.10.2.2 thorpej && cpuid <= BCUREVID_RID_4121
273 1.10.2.2 thorpej && cpuid >= BCUREVID_RID_4102) {
274 1.7 sato reg = vrbcu_read(sc, BCUCNT2_REG_W);
275 1.7 sato printf("vrbcu: CNT2 %x: ", reg);
276 1.10.2.3 jdolecek dbg_bit_print(reg);
277 1.7 sato }
278 1.7 sato #endif /* !defined ONLY_VR4181 */
279 1.10.2.1 thorpej #if !defined(ONLY_VR4181) || !defined(ONLY_VR4122_4131)
280 1.7 sato if (cpuid != BCUREVID_FIXRID_4181
281 1.10.2.2 thorpej && cpuid <= BCUREVID_RID_4121
282 1.10.2.2 thorpej && cpuid >= BCUREVID_RID_4102) {
283 1.7 sato reg = vrbcu_read(sc, BCUSPEED_REG_W);
284 1.7 sato printf("vrbcu: SPEED %x: ", reg);
285 1.10.2.3 jdolecek dbg_bit_print(reg);
286 1.7 sato reg = vrbcu_read(sc, BCUERRST_REG_W);
287 1.7 sato printf("vrbcu: ERRST %x: ", reg);
288 1.10.2.3 jdolecek dbg_bit_print(reg);
289 1.7 sato reg = vrbcu_read(sc, BCURFCNT_REG_W);
290 1.7 sato printf("vrbcu: RFCNT %x\n", reg);
291 1.7 sato reg = vrbcu_read(sc, BCUREFCOUNT_REG_W);
292 1.7 sato printf("vrbcu: RFCOUNT %x\n", reg);
293 1.7 sato }
294 1.10.2.1 thorpej #endif /* !defined(ONLY_VR4181) || !defined(ONLY_VR4122_4131) */
295 1.7 sato #if !defined(ONLY_VR4181)
296 1.7 sato if (cpuid != BCUREVID_FIXRID_4181
297 1.10.2.2 thorpej && cpuid <= BCUREVID_RID_4131
298 1.10.2.2 thorpej && cpuid >= BCUREVID_RID_4111)
299 1.7 sato {
300 1.5 sato reg = vrbcu_read(sc, BCUCNT3_REG_W);
301 1.5 sato printf("vrbcu: CNT3 %x: ", reg);
302 1.10.2.3 jdolecek dbg_bit_print(reg);
303 1.5 sato }
304 1.7 sato #endif /* !defined ONLY_VR4181 */
305 1.5 sato #endif /* VRBCUDEBUG */
306 1.5 sato
307 1.1 takemura }
308 1.1 takemura
309 1.1 takemura static char *cpuname[] = {
310 1.7 sato "VR4101", /* 0 */
311 1.7 sato "VR4102", /* 1 */
312 1.7 sato "VR4111", /* 2 */
313 1.7 sato "VR4121", /* 3 */
314 1.7 sato "VR4122", /* 4 */
315 1.10.2.1 thorpej "VR4131", /* 5 */
316 1.7 sato "UNKNOWN",
317 1.7 sato "UNKNOWN",
318 1.1 takemura "UNKNOWN",
319 1.1 takemura "UNKNOWN",
320 1.1 takemura "UNKNOWN",
321 1.7 sato "UNKNOWN",
322 1.7 sato "UNKNOWN",
323 1.7 sato "UNKNOWN",
324 1.7 sato "UNKNOWN",
325 1.7 sato "UNKNOWN",
326 1.7 sato "VR4181", /* 0x10 + 0 */
327 1.7 sato };
328 1.1 takemura
329 1.2 sato int
330 1.2 sato vrbcu_vrip_getcpuid(void)
331 1.2 sato {
332 1.2 sato volatile u_int16_t *revreg;
333 1.2 sato
334 1.2 sato if (vr_cpuid != -1)
335 1.10.2.2 thorpej return (vr_cpuid);
336 1.2 sato
337 1.2 sato if (vr_cpuid == -1) {
338 1.10.2.4 jdolecek if (vrbcu_addr() == VR4181_BCU_ADDR)
339 1.10.2.2 thorpej revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
340 1.10.2.4 jdolecek ((vrbcu_addr() + BCU81REVID_REG_W));
341 1.8 sato else
342 1.10.2.2 thorpej revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
343 1.10.2.4 jdolecek ((vrbcu_addr() + BCUREVID_REG_W));
344 1.2 sato
345 1.2 sato vr_cpuid = *revreg;
346 1.2 sato vr_cpuid = (vr_cpuid&BCUREVID_RIDMASK)>>BCUREVID_RIDSHFT;
347 1.10.2.4 jdolecek if (vrbcu_addr() == VR4181_BCU_ADDR
348 1.8 sato && vr_cpuid == BCUREVID_RID_4181) /* conflict vr4101 */
349 1.7 sato vr_cpuid = BCUREVID_FIXRID_4181;
350 1.2 sato }
351 1.10.2.2 thorpej return (vr_cpuid);
352 1.2 sato }
353 1.2 sato
354 1.1 takemura char *
355 1.1 takemura vrbcu_vrip_getcpuname(void)
356 1.1 takemura {
357 1.2 sato int cpuid;
358 1.1 takemura
359 1.2 sato if (vr_cpuname != NULL)
360 1.10.2.2 thorpej return (vr_cpuname);
361 1.1 takemura
362 1.2 sato cpuid = vrbcu_vrip_getcpuid();
363 1.2 sato vr_cpuname = cpuname[cpuid];
364 1.10.2.2 thorpej
365 1.10.2.2 thorpej return (vr_cpuname);
366 1.1 takemura }
367 1.1 takemura
368 1.2 sato
369 1.1 takemura int
370 1.1 takemura vrbcu_vrip_getcpumajor(void)
371 1.1 takemura {
372 1.1 takemura volatile u_int16_t *revreg;
373 1.2 sato
374 1.2 sato if (vr_major != -1)
375 1.10.2.2 thorpej return (vr_major);
376 1.1 takemura
377 1.10.2.2 thorpej revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
378 1.10.2.4 jdolecek ((vrbcu_addr() + BCUREVID_REG_W));
379 1.1 takemura
380 1.2 sato vr_major = *revreg;
381 1.2 sato vr_major = (vr_major&BCUREVID_MJREVMASK)>>BCUREVID_MJREVSHFT;
382 1.10.2.2 thorpej
383 1.10.2.2 thorpej return (vr_major);
384 1.1 takemura }
385 1.1 takemura
386 1.1 takemura int
387 1.1 takemura vrbcu_vrip_getcpuminor(void)
388 1.1 takemura {
389 1.1 takemura volatile u_int16_t *revreg;
390 1.2 sato
391 1.2 sato if (vr_minor != -1)
392 1.10.2.2 thorpej return (vr_minor);
393 1.1 takemura
394 1.10.2.2 thorpej revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
395 1.10.2.4 jdolecek ((vrbcu_addr() + BCUREVID_REG_W));
396 1.1 takemura
397 1.2 sato vr_minor = *revreg;
398 1.2 sato vr_minor = (vr_minor&BCUREVID_MNREVMASK)>>BCUREVID_MNREVSHFT;
399 1.10.2.2 thorpej
400 1.10.2.2 thorpej return (vr_minor);
401 1.1 takemura }
402 1.4 shin
403 1.4 shin #define CLKX 18432000 /* CLKX1,CLKX2: 18.432MHz */
404 1.4 shin #define MHZ 1000000
405 1.4 shin
406 1.4 shin int
407 1.4 shin vrbcu_vrip_getcpuclock(void)
408 1.4 shin {
409 1.4 shin u_int16_t clksp;
410 1.4 shin int cpuid, cpuclock;
411 1.4 shin
412 1.4 shin cpuid = vrbcu_vrip_getcpuid();
413 1.7 sato if (cpuid != BCUREVID_FIXRID_4181 && cpuid >= BCUREVID_RID_4111) {
414 1.10.2.2 thorpej clksp = *(u_int16_t *)MIPS_PHYS_TO_KSEG1
415 1.10.2.4 jdolecek ((vrbcu_addr() + BCUCLKSPEED_REG_W)) &
416 1.10.2.2 thorpej BCUCLKSPEED_CLKSPMASK;
417 1.8 sato } else if (cpuid == BCUREVID_FIXRID_4181) {
418 1.10.2.2 thorpej clksp = *(u_int16_t *)MIPS_PHYS_TO_KSEG1
419 1.10.2.4 jdolecek ((vrbcu_addr() + BCU81CLKSPEED_REG_W)) &
420 1.10.2.2 thorpej BCUCLKSPEED_CLKSPMASK;
421 1.7 sato }
422 1.4 shin
423 1.4 shin switch (cpuid) {
424 1.7 sato case BCUREVID_FIXRID_4181:
425 1.8 sato cpuclock = CLKX / clksp * 64;
426 1.7 sato /* branch delay is 1 clock; 2 clock/loop */
427 1.7 sato cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
428 1.7 sato break;
429 1.4 shin case BCUREVID_RID_4101:
430 1.4 shin /* assume 33MHz */
431 1.4 shin cpuclock = 33000000;
432 1.4 shin /* branch delay is 1 clock; 2 clock/loop */
433 1.4 shin cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
434 1.4 shin break;
435 1.4 shin case BCUREVID_RID_4102:
436 1.4 shin cpuclock = CLKX / clksp * 32;
437 1.4 shin /* branch delay is 1 clock; 2 clock/loop */
438 1.4 shin cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
439 1.4 shin break;
440 1.4 shin case BCUREVID_RID_4111:
441 1.4 shin cpuclock = CLKX / clksp * 64;
442 1.4 shin /* branch delay is 1 clock; 2 clock/loop */
443 1.4 shin cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
444 1.4 shin break;
445 1.4 shin case BCUREVID_RID_4121:
446 1.4 shin cpuclock = CLKX / clksp * 64;
447 1.9 enami /* branch delay is 2 clock; 3 clock/loop */
448 1.9 enami cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
449 1.9 enami break;
450 1.9 enami case BCUREVID_RID_4122:
451 1.10.2.1 thorpej cpuclock = CLKX / clksp * 98;
452 1.10.2.1 thorpej /* branch delay is 2 clock; 3 clock/loop */
453 1.10.2.1 thorpej cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
454 1.10.2.1 thorpej break;
455 1.10.2.1 thorpej case BCUREVID_RID_4131:
456 1.9 enami cpuclock = CLKX / clksp * 98;
457 1.4 shin /* branch delay is 2 clock; 3 clock/loop */
458 1.4 shin cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
459 1.4 shin break;
460 1.4 shin default:
461 1.10.2.5 jdolecek panic("unknown CPU type %d", cpuid);
462 1.4 shin break;
463 1.4 shin }
464 1.10.2.2 thorpej
465 1.10.2.2 thorpej return (cpuclock);
466 1.4 shin }
467