vrpmu.c revision 1.6 1 /* $NetBSD: vrpmu.c,v 1.6 2000/03/14 08:23:24 sato Exp $ */
2
3 /*
4 * Copyright (c) 1999 M. Warner Losh. All rights reserved.
5 * Copyright (c) 1999 PocketBSD Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/device.h>
32
33 #include <machine/bus.h>
34 #include <machine/config_hook.h>
35
36 #include <hpcmips/vr/vripvar.h>
37 #include <hpcmips/vr/vrpmuvar.h>
38 #include <hpcmips/vr/vrpmureg.h>
39
40 #include "vrbcu.h"
41 #if NVRBCU > 0
42 #include <hpcmips/vr/bcuvar.h>
43 #include <hpcmips/vr/bcureg.h>
44 #endif
45
46 int vrpmu_pwsw = 0;
47
48 #ifdef VRPMUDEBUG
49 #define DEBUG_BOOT 0x1 /* boot time */
50 #define DEBUG_INTR 0x2 /* intr */
51 #define DEBUG_IO 0x4 /* I/O */
52 #ifndef VRPMUDEBUG_CONF
53 #define VRPMUDEBUG_CONF 0
54 #endif /* VRPMUDEBUG_CONF */
55 int vrpmudebug = VRPMUDEBUG_CONF;
56 #define DPRINTF(flag, arg) if (vrpmudebug&flag) printf arg;
57 #define DDUMP_INTR2(flag, arg1, arg2) if (vrpmudebug&flag) vrpmu_dump_intr2(arg1,arg2);
58 #define DDUMP_REGS(flag, arg) if (vrpmudebug&flag) vrpmu_dump_regs(arg);
59 #else /* VRPMUDEBUG */
60 #define DPRINTF(flag, arg)
61 #define DDUMP_INTR2(flag, arg1, arg2)
62 #define DDUMP_REGS(flag, arg)
63 #endif /* VRPMUDEBUG */
64
65 static int vrpmumatch __P((struct device *, struct cfdata *, void *));
66 static void vrpmuattach __P((struct device *, struct device *, void *));
67
68 static void vrpmu_write __P((struct vrpmu_softc *, int, unsigned short));
69 static unsigned short vrpmu_read __P((struct vrpmu_softc *, int));
70
71 int vrpmu_intr __P((void *));
72 void vrpmu_dump_intr __P((void *));
73 void vrpmu_dump_intr2 __P((unsigned int, unsigned int));
74 void vrpmu_dump_regs __P((void *));
75
76 struct cfattach vrpmu_ca = {
77 sizeof(struct vrpmu_softc), vrpmumatch, vrpmuattach
78 };
79
80 static inline void
81 vrpmu_write(sc, port, val)
82 struct vrpmu_softc *sc;
83 int port;
84 unsigned short val;
85 {
86 bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
87 }
88
89 static inline unsigned short
90 vrpmu_read(sc, port)
91 struct vrpmu_softc *sc;
92 int port;
93 {
94 return bus_space_read_2(sc->sc_iot, sc->sc_ioh, port);
95 }
96
97 static int
98 vrpmumatch(parent, cf, aux)
99 struct device *parent;
100 struct cfdata *cf;
101 void *aux;
102 {
103 return 1;
104 }
105
106 static void
107 vrpmuattach(parent, self, aux)
108 struct device *parent;
109 struct device *self;
110 void *aux;
111 {
112 struct vrpmu_softc *sc = (struct vrpmu_softc *)self;
113 struct vrip_attach_args *va = aux;
114
115 bus_space_tag_t iot = va->va_iot;
116 bus_space_handle_t ioh;
117
118 if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
119 printf(": can't map bus space\n");
120 return;
121 }
122
123 sc->sc_iot = iot;
124 sc->sc_ioh = ioh;
125
126 if (!(sc->sc_handler =
127 vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
128 vrpmu_intr, sc))) {
129 printf (": can't map interrupt line.\n");
130 return;
131 }
132
133 printf("\n");
134 /* dump current intrrupt states */
135 vrpmu_dump_intr(sc);
136 DDUMP_REGS(DEBUG_BOOT, sc);
137 /* clear interrupt status */
138 vrpmu_write(sc, PMUINT_REG_W, PMUINT_ALL);
139 vrpmu_write(sc, PMUINT2_REG_W, PMUINT2_ALL);
140 }
141
142 /*
143 * dump PMU intr status regs
144 *
145 */
146 void
147 vrpmu_dump_intr(arg)
148 void *arg;
149 {
150 struct vrpmu_softc *sc = arg;
151 unsigned int intstat1;
152 unsigned int intstat2;
153 intstat1 = vrpmu_read(sc, PMUINT_REG_W);
154 intstat2 = vrpmu_read(sc, PMUINT2_REG_W);
155 vrpmu_dump_intr2(intstat1, intstat2);
156
157 }
158
159 /*
160 * dump PMU intr status regs
161 */
162 void
163 vrpmu_dump_intr2(intstat1, intstat2)
164 unsigned int intstat1, intstat2;
165 {
166 if (intstat1 & PMUINT_GPIO3)
167 printf("vrpmu: GPIO[3] activation\n");
168 if (intstat1 & PMUINT_GPIO2)
169 printf("vrpmu: GPIO[2] activation\n");
170 if (intstat1 & PMUINT_GPIO1)
171 printf("vrpmu: GPIO[1] activation\n");
172 if (intstat1 & PMUINT_GPIO0)
173 printf("vrpmu: GPIO[0] activation\n");
174
175 if (intstat1 & PMUINT_RTC)
176 printf("vrpmu: RTC alarm detected\n");
177 if (intstat1 & PMUINT_BATT)
178 printf("vrpmu: Battery low during activation\n");
179
180 if (intstat1 & PMUINT_TIMOUTRST)
181 printf("vrpmu: HAL timer reset\n");
182 if (intstat1 & PMUINT_RTCRST)
183 printf("vrpmu: RTC reset detected\n");
184 if (intstat1 & PMUINT_RSTSWRST)
185 printf("vrpmu: RESET switch detected\n");
186 if (intstat1 & PMUINT_DMSWRST)
187 printf("vrpmu: Deadman's switch detected\n");
188 if (intstat1 & PMUINT_BATTINTR)
189 printf("vrpmu: Battery low during normal ops\n");
190 if (intstat1 & PMUINT_POWERSW)
191 printf("vrpmu: POWER switch detected\n");
192
193 if (intstat2 & PMUINT_GPIO12)
194 printf("vrpmu: GPIO[12] activation\n");
195 if (intstat2 & PMUINT_GPIO11)
196 printf("vrpmu: GPIO[11] activation\n");
197 if (intstat2 & PMUINT_GPIO10)
198 printf("vrpmu: GPIO[10] activation\n");
199 if (intstat2 & PMUINT_GPIO9)
200 printf("vrpmu: GPIO[9] activation\n");
201 }
202
203 /*
204 * dump PMU registers
205 *
206 */
207 void
208 vrpmu_dump_regs(arg)
209 void *arg;
210 {
211 struct vrpmu_softc *sc = arg;
212 unsigned int intstat1;
213 unsigned int intstat2;
214 unsigned int reg;
215 #if NVRBCU > 0
216 int cpuid;
217 #endif
218 intstat1 = vrpmu_read(sc, PMUINT_REG_W);
219 intstat2 = vrpmu_read(sc, PMUINT2_REG_W);
220
221 /* others? XXXX */
222 reg = vrpmu_read(sc, PMUCNT_REG_W);
223 printf("vrpmu: cnt 0x%x: ", reg);
224 bitdisp16(reg);
225 reg = vrpmu_read(sc, PMUCNT2_REG_W);
226 printf("vrpmu: cnt2 0x%x: ", reg);
227 bitdisp16(reg);
228 #if NVRBCU > 0
229 cpuid = vrbcu_vrip_getcpuid();
230 if (cpuid >= BCUREVID_RID_4111){
231 reg = vrpmu_read(sc, PMUWAIT_REG_W);
232 printf("vrpmu: wait 0x%x", reg);
233 }
234 if (cpuid >= BCUREVID_RID_4121){
235 reg = vrpmu_read(sc, PMUDIV_REG_W);
236 printf(" div 0x%x", reg);
237 }
238 printf("\n");
239 #endif /* NVRBCU > 0 */
240 }
241
242 /*
243 * PMU interrupt handler.
244 * XXX
245 *
246 * In the following interrupt routine we should actually DO something
247 * with the knowledge that we've gained. For now we just report it.
248 */
249 int
250 vrpmu_intr(arg)
251 void *arg;
252 {
253 struct vrpmu_softc *sc = arg;
254 unsigned int intstat1;
255 unsigned int intstat2;
256
257 intstat1 = vrpmu_read(sc, PMUINT_REG_W);
258 /* clear interrupt status */
259 vrpmu_write(sc, PMUINT_REG_W, intstat1);
260
261
262 intstat2 = vrpmu_read(sc, PMUINT2_REG_W);
263 /* clear interrupt status */
264 vrpmu_write(sc, PMUINT2_REG_W, intstat2);
265
266 DDUMP_INTR2(DEBUG_INTR, intstat1, intstat2);
267
268 if (intstat1 & PMUINT_GPIO3)
269 ;
270 if (intstat1 & PMUINT_GPIO2)
271 ;
272 if (intstat1 & PMUINT_GPIO1)
273 ;
274 if (intstat1 & PMUINT_GPIO0)
275 ;
276
277 if (intstat1 & PMUINT_RTC)
278 ;
279 if (intstat1 & PMUINT_BATT)
280 ;
281
282 if (intstat1 & PMUINT_TIMOUTRST)
283 ;
284 if (intstat1 & PMUINT_RTCRST)
285 ;
286 if (intstat1 & PMUINT_RSTSWRST)
287 ;
288 if (intstat1 & PMUINT_DMSWRST)
289 ;
290 if (intstat1 & PMUINT_BATTINTR)
291 ;
292 if (intstat1 & PMUINT_POWERSW) {
293 vrpmu_pwsw = !vrpmu_pwsw;
294 config_hook_call(CONFIG_HOOK_BUTTONEVENT,
295 CONFIG_HOOK_BUTTONEVENT_POWER,
296 (void*)vrpmu_pwsw);
297 }
298
299 if (intstat2 & PMUINT_GPIO12)
300 ;
301 if (intstat2 & PMUINT_GPIO11)
302 ;
303 if (intstat2 & PMUINT_GPIO10)
304 ;
305 if (intstat2 & PMUINT_GPIO9)
306 ;
307
308 return 0;
309 }
310