bcu_vrip.c revision 1.1.1.1.8.1 1 1.1.1.1.8.1 wrstuden /* $NetBSD: bcu_vrip.c,v 1.1.1.1.8.1 1999/12/27 18:32:14 wrstuden Exp $ */
2 1.1 takemura
3 1.1 takemura /*-
4 1.1 takemura * Copyright (c) 1999 SATO Kazumi. All rights reserved.
5 1.1 takemura * Copyright (c) 1999 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.1 takemura
44 1.1 takemura #include <mips/cpuregs.h>
45 1.1 takemura
46 1.1 takemura #include <hpcmips/vr/vr.h>
47 1.1 takemura #include <hpcmips/vr/vripvar.h>
48 1.1 takemura #include <hpcmips/vr/vripreg.h>
49 1.1 takemura #include <hpcmips/vr/bcureg.h>
50 1.1 takemura #include <hpcmips/vr/bcuvar.h>
51 1.1 takemura
52 1.1.1.1.8.1 wrstuden static int vrbcu_match __P((struct device *, struct cfdata *, void *));
53 1.1.1.1.8.1 wrstuden static void vrbcu_attach __P((struct device *, struct device *, void *));
54 1.1.1.1.8.1 wrstuden
55 1.1.1.1.8.1 wrstuden static void vrbcu_write __P((struct vrbcu_softc *, int, unsigned short));
56 1.1.1.1.8.1 wrstuden static unsigned short vrbcu_read __P((struct vrbcu_softc *, int));
57 1.1 takemura
58 1.1.1.1.8.1 wrstuden char *vr_cpuname=NULL;
59 1.1.1.1.8.1 wrstuden int vr_major=-1;
60 1.1.1.1.8.1 wrstuden int vr_minor=-1;
61 1.1.1.1.8.1 wrstuden int vr_cpuid=-1;
62 1.1 takemura
63 1.1 takemura struct cfattach vrbcu_ca = {
64 1.1.1.1.8.1 wrstuden sizeof(struct vrbcu_softc), vrbcu_match, vrbcu_attach
65 1.1 takemura };
66 1.1 takemura
67 1.1.1.1.8.1 wrstuden struct vrbcu_softc *the_bcu_sc = NULL;
68 1.1.1.1.8.1 wrstuden
69 1.1.1.1.8.1 wrstuden static inline void
70 1.1.1.1.8.1 wrstuden vrbcu_write(sc, port, val)
71 1.1.1.1.8.1 wrstuden struct vrbcu_softc *sc;
72 1.1.1.1.8.1 wrstuden int port;
73 1.1.1.1.8.1 wrstuden unsigned short val;
74 1.1.1.1.8.1 wrstuden {
75 1.1.1.1.8.1 wrstuden bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
76 1.1.1.1.8.1 wrstuden }
77 1.1.1.1.8.1 wrstuden
78 1.1.1.1.8.1 wrstuden static inline unsigned short
79 1.1.1.1.8.1 wrstuden vrbcu_read(sc, port)
80 1.1.1.1.8.1 wrstuden struct vrbcu_softc *sc;
81 1.1.1.1.8.1 wrstuden int port;
82 1.1.1.1.8.1 wrstuden {
83 1.1.1.1.8.1 wrstuden return bus_space_read_2(sc->sc_iot, sc->sc_ioh, port);
84 1.1.1.1.8.1 wrstuden }
85 1.1.1.1.8.1 wrstuden
86 1.1 takemura static int
87 1.1.1.1.8.1 wrstuden vrbcu_match(parent, cf, aux)
88 1.1 takemura struct device *parent;
89 1.1 takemura struct cfdata *cf;
90 1.1 takemura void *aux;
91 1.1 takemura {
92 1.1.1.1.8.1 wrstuden return 2;
93 1.1 takemura }
94 1.1 takemura
95 1.1 takemura static void
96 1.1.1.1.8.1 wrstuden vrbcu_attach(parent, self, aux)
97 1.1 takemura struct device *parent;
98 1.1 takemura struct device *self;
99 1.1 takemura void *aux;
100 1.1 takemura {
101 1.1 takemura struct vrip_attach_args *va = aux;
102 1.1.1.1.8.1 wrstuden struct vrbcu_softc *sc = (struct vrbcu_softc *)self;
103 1.1 takemura
104 1.1.1.1.8.1 wrstuden sc->sc_iot = va->va_iot;
105 1.1.1.1.8.1 wrstuden bus_space_map(sc->sc_iot, va->va_addr, va->va_size,
106 1.1 takemura 0, /* no flags */
107 1.1.1.1.8.1 wrstuden &sc->sc_ioh);
108 1.1 takemura
109 1.1 takemura printf("\n");
110 1.1.1.1.8.1 wrstuden the_bcu_sc = sc;
111 1.1 takemura }
112 1.1 takemura
113 1.1 takemura static char *cpuname[] = {
114 1.1 takemura "VR4101",
115 1.1 takemura "VR4102",
116 1.1 takemura "VR4111",
117 1.1 takemura "VR4121",
118 1.1 takemura "UNKNOWN",
119 1.1 takemura "UNKNOWN",
120 1.1 takemura "UNKNOWN",
121 1.1 takemura "UNKNOWN" };
122 1.1 takemura
123 1.1.1.1.8.1 wrstuden int
124 1.1.1.1.8.1 wrstuden vrbcu_vrip_getcpuid(void)
125 1.1.1.1.8.1 wrstuden {
126 1.1.1.1.8.1 wrstuden volatile u_int16_t *revreg;
127 1.1.1.1.8.1 wrstuden
128 1.1.1.1.8.1 wrstuden if (vr_cpuid != -1)
129 1.1.1.1.8.1 wrstuden return vr_cpuid;
130 1.1.1.1.8.1 wrstuden
131 1.1.1.1.8.1 wrstuden if (vr_cpuid == -1) {
132 1.1.1.1.8.1 wrstuden revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1((VRIP_BCU_ADDR+BCUREVID_REG_W));
133 1.1.1.1.8.1 wrstuden
134 1.1.1.1.8.1 wrstuden vr_cpuid = *revreg;
135 1.1.1.1.8.1 wrstuden vr_cpuid = (vr_cpuid&BCUREVID_RIDMASK)>>BCUREVID_RIDSHFT;
136 1.1.1.1.8.1 wrstuden }
137 1.1.1.1.8.1 wrstuden return vr_cpuid;
138 1.1.1.1.8.1 wrstuden }
139 1.1.1.1.8.1 wrstuden
140 1.1 takemura char *
141 1.1 takemura vrbcu_vrip_getcpuname(void)
142 1.1 takemura {
143 1.1.1.1.8.1 wrstuden int cpuid;
144 1.1 takemura
145 1.1.1.1.8.1 wrstuden if (vr_cpuname != NULL)
146 1.1.1.1.8.1 wrstuden return vr_cpuname;
147 1.1 takemura
148 1.1.1.1.8.1 wrstuden cpuid = vrbcu_vrip_getcpuid();
149 1.1.1.1.8.1 wrstuden vr_cpuname = cpuname[cpuid];
150 1.1.1.1.8.1 wrstuden return vr_cpuname;
151 1.1 takemura }
152 1.1 takemura
153 1.1.1.1.8.1 wrstuden
154 1.1 takemura int
155 1.1 takemura vrbcu_vrip_getcpumajor(void)
156 1.1 takemura {
157 1.1 takemura volatile u_int16_t *revreg;
158 1.1.1.1.8.1 wrstuden
159 1.1.1.1.8.1 wrstuden if (vr_major != -1)
160 1.1.1.1.8.1 wrstuden return vr_major;
161 1.1 takemura
162 1.1 takemura revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1((VRIP_BCU_ADDR+BCUREVID_REG_W));
163 1.1 takemura
164 1.1.1.1.8.1 wrstuden vr_major = *revreg;
165 1.1.1.1.8.1 wrstuden vr_major = (vr_major&BCUREVID_MJREVMASK)>>BCUREVID_MJREVSHFT;
166 1.1.1.1.8.1 wrstuden return vr_major;
167 1.1 takemura }
168 1.1 takemura
169 1.1 takemura int
170 1.1 takemura vrbcu_vrip_getcpuminor(void)
171 1.1 takemura {
172 1.1 takemura volatile u_int16_t *revreg;
173 1.1.1.1.8.1 wrstuden
174 1.1.1.1.8.1 wrstuden if (vr_minor != -1)
175 1.1.1.1.8.1 wrstuden return vr_minor;
176 1.1 takemura
177 1.1 takemura revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1((VRIP_BCU_ADDR+BCUREVID_REG_W));
178 1.1 takemura
179 1.1.1.1.8.1 wrstuden vr_minor = *revreg;
180 1.1.1.1.8.1 wrstuden vr_minor = (vr_minor&BCUREVID_MNREVMASK)>>BCUREVID_MNREVSHFT;
181 1.1.1.1.8.1 wrstuden return vr_minor;
182 1.1 takemura }
183 1.1.1.1.8.1 wrstuden
184 1.1.1.1.8.1 wrstuden #define CLKX 18432000 /* CLKX1,CLKX2: 18.432MHz */
185 1.1.1.1.8.1 wrstuden #define MHZ 1000000
186 1.1.1.1.8.1 wrstuden
187 1.1.1.1.8.1 wrstuden int
188 1.1.1.1.8.1 wrstuden vrbcu_vrip_getcpuclock(void)
189 1.1.1.1.8.1 wrstuden {
190 1.1.1.1.8.1 wrstuden u_int16_t clksp;
191 1.1.1.1.8.1 wrstuden int cpuid, cpuclock;
192 1.1.1.1.8.1 wrstuden
193 1.1.1.1.8.1 wrstuden clksp = *(u_int16_t *)MIPS_PHYS_TO_KSEG1((VRIP_BCU_ADDR+BCUCLKSPEED_REG_W)) & BCUCLKSPEED_CLKSPMASK;
194 1.1.1.1.8.1 wrstuden cpuid = vrbcu_vrip_getcpuid();
195 1.1.1.1.8.1 wrstuden
196 1.1.1.1.8.1 wrstuden switch (cpuid) {
197 1.1.1.1.8.1 wrstuden case BCUREVID_RID_4101:
198 1.1.1.1.8.1 wrstuden /* assume 33MHz */
199 1.1.1.1.8.1 wrstuden cpuclock = 33000000;
200 1.1.1.1.8.1 wrstuden /* branch delay is 1 clock; 2 clock/loop */
201 1.1.1.1.8.1 wrstuden cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
202 1.1.1.1.8.1 wrstuden break;
203 1.1.1.1.8.1 wrstuden case BCUREVID_RID_4102:
204 1.1.1.1.8.1 wrstuden cpuclock = CLKX / clksp * 32;
205 1.1.1.1.8.1 wrstuden /* branch delay is 1 clock; 2 clock/loop */
206 1.1.1.1.8.1 wrstuden cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
207 1.1.1.1.8.1 wrstuden break;
208 1.1.1.1.8.1 wrstuden case BCUREVID_RID_4111:
209 1.1.1.1.8.1 wrstuden cpuclock = CLKX / clksp * 64;
210 1.1.1.1.8.1 wrstuden /* branch delay is 1 clock; 2 clock/loop */
211 1.1.1.1.8.1 wrstuden cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
212 1.1.1.1.8.1 wrstuden break;
213 1.1.1.1.8.1 wrstuden case BCUREVID_RID_4121:
214 1.1.1.1.8.1 wrstuden cpuclock = CLKX / clksp * 64;
215 1.1.1.1.8.1 wrstuden /* branch delay is 2 clock; 3 clock/loop */
216 1.1.1.1.8.1 wrstuden cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
217 1.1.1.1.8.1 wrstuden break;
218 1.1.1.1.8.1 wrstuden default:
219 1.1.1.1.8.1 wrstuden panic("unknown CPU type %d\n", cpuid);
220 1.1.1.1.8.1 wrstuden break;
221 1.1.1.1.8.1 wrstuden }
222 1.1.1.1.8.1 wrstuden return cpuclock;
223 1.1.1.1.8.1 wrstuden }
224