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