Annotation of sys/arch/hppa/dev/lasi.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: lasi.c,v 1.22 2004/09/15 20:11:28 mickey Exp $ */
2:
3: /*
4: * Copyright (c) 1998-2003 Michael Shalayeff
5: * 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 ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26: * THE POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: #undef LASIDEBUG
30:
31: #include <sys/param.h>
32: #include <sys/systm.h>
33: #include <sys/device.h>
34: #include <sys/reboot.h>
35:
36: #include <machine/bus.h>
37: #include <machine/iomod.h>
38: #include <machine/reg.h>
39: #include <machine/autoconf.h>
40:
41: #include <hppa/dev/cpudevs.h>
42:
43: #include <hppa/gsc/gscbusvar.h>
44:
45: #define LASI_IOMASK 0xfff00000
46:
47: struct lasi_hwr {
48: u_int32_t lasi_power;
49: #define LASI_BLINK 0x01
50: #define LASI_OFF 0x02
51: u_int32_t lasi_error;
52: u_int32_t lasi_version;
53: u_int32_t lasi_reset;
54: u_int32_t lasi_arbmask;
55: };
56:
57: struct lasi_trs {
58: u_int32_t lasi_irr; /* int requset register */
59: u_int32_t lasi_imr; /* int mask register */
60: u_int32_t lasi_ipr; /* int pending register */
61: u_int32_t lasi_icr; /* int command? register */
62: u_int32_t lasi_iar; /* int acquire? register */
63: };
64:
65: struct lasi_softc {
66: struct device sc_dev;
67: struct gscbus_ic sc_ic;
68:
69: struct lasi_hwr volatile *sc_hw;
70: struct lasi_trs volatile *sc_trs;
71: struct gsc_attach_args ga; /* for deferred attach */
72: };
73:
74: int lasimatch(struct device *, void *, void *);
75: void lasiattach(struct device *, struct device *, void *);
76:
77: struct cfattach lasi_ca = {
78: sizeof(struct lasi_softc), lasimatch, lasiattach
79: };
80:
81: struct cfdriver lasi_cd = {
82: NULL, "lasi", DV_DULL
83: };
84:
85: void lasi_cold_hook(int on);
86: void lasi_gsc_attach(struct device *self);
87:
88: int
89: lasimatch(parent, cfdata, aux)
90: struct device *parent;
91: void *cfdata;
92: void *aux;
93: {
94: register struct confargs *ca = aux;
95: /* register struct cfdata *cf = cfdata; */
96:
97: if (ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
98: ca->ca_type.iodc_sv_model != HPPA_BHA_LASI)
99: return 0;
100:
101: return 1;
102: }
103:
104: void
105: lasiattach(parent, self, aux)
106: struct device *parent;
107: struct device *self;
108: void *aux;
109: {
110: struct lasi_softc *sc = (struct lasi_softc *)self;
111: struct confargs *ca = aux;
112: bus_space_handle_t ioh, ioh2;
113: int s, in;
114:
115: if (bus_space_map(ca->ca_iot, ca->ca_hpa,
116: IOMOD_HPASIZE, 0, &ioh)) {
117: printf(": can't map TRS space\n");
118: return;
119: }
120:
121: if (bus_space_map(ca->ca_iot, ca->ca_hpa + 0xc000,
122: IOMOD_HPASIZE, 0, &ioh2)) {
123: bus_space_unmap(ca->ca_iot, ioh, IOMOD_HPASIZE);
124: printf(": can't map IO space\n");
125: return;
126: }
127:
128: sc->sc_trs = (struct lasi_trs *)ca->ca_hpa;
129: sc->sc_hw = (struct lasi_hwr *)(ca->ca_hpa + 0xc000);
130:
131: /* XXX should we reset the chip here? */
132:
133: printf(": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4,
134: sc->sc_hw->lasi_version & 0xf);
135:
136: /* interrupts guts */
137: s = splhigh();
138: sc->sc_trs->lasi_iar = cpu_gethpa(0) | (31 - ca->ca_irq);
139: sc->sc_trs->lasi_icr = 0;
140: sc->sc_trs->lasi_imr = ~0U;
141: in = sc->sc_trs->lasi_irr;
142: sc->sc_trs->lasi_imr = 0;
143: splx(s);
144:
145: sc->sc_ic.gsc_type = gsc_lasi;
146: sc->sc_ic.gsc_dv = sc;
147: sc->sc_ic.gsc_base = sc->sc_trs;
148:
149: #ifdef USELEDS
150: /* figure out the leds address */
151: switch (cpu_hvers) {
152: case HPPA_BOARD_HP712_60:
153: case HPPA_BOARD_HP712_80:
154: case HPPA_BOARD_HP712_100:
155: case HPPA_BOARD_HP743I_64:
156: case HPPA_BOARD_HP743I_100:
157: case HPPA_BOARD_HP712_120:
158: break; /* only has one led. works different */
159:
160: case HPPA_BOARD_HP715_64:
161: case HPPA_BOARD_HP715_80:
162: case HPPA_BOARD_HP715_100:
163: case HPPA_BOARD_HP715_100XC:
164: case HPPA_BOARD_HP725_100:
165: case HPPA_BOARD_HP725_120:
166: if (bus_space_map(ca->ca_iot, ca->ca_hpa - 0x20000,
167: 4, 0, (bus_space_handle_t *)&machine_ledaddr))
168: machine_ledaddr = NULL;
169: machine_ledword = 1;
170: break;
171:
172: case HPPA_BOARD_HP800_A180C:
173: case HPPA_BOARD_HP778_B132L:
174: case HPPA_BOARD_HP778_B132LP:
175: case HPPA_BOARD_HP778_B160L:
176: case HPPA_BOARD_HP778_B180L:
177: case HPPA_BOARD_HP780_C100:
178: case HPPA_BOARD_HP780_C110:
179: case HPPA_BOARD_HP779_C132L:
180: case HPPA_BOARD_HP779_C160L:
181: case HPPA_BOARD_HP779_C180L:
182: case HPPA_BOARD_HP779_C160L1:
183: if (bus_space_map(ca->ca_iot, 0xf0190000,
184: 4, 0, (bus_space_handle_t *)&machine_ledaddr))
185: machine_ledaddr = NULL;
186: machine_ledword = 1;
187: break;
188:
189: default:
190: machine_ledaddr = (u_int8_t *)sc->sc_hw;
191: machine_ledword = 1;
192: break;
193: }
194: #endif
195:
196: sc->ga.ga_ca = *ca; /* clone from us */
197: if (!strcmp(parent->dv_xname, "mainbus0")) {
198: sc->ga.ga_dp.dp_bc[0] = sc->ga.ga_dp.dp_bc[1];
199: sc->ga.ga_dp.dp_bc[1] = sc->ga.ga_dp.dp_bc[2];
200: sc->ga.ga_dp.dp_bc[2] = sc->ga.ga_dp.dp_bc[3];
201: sc->ga.ga_dp.dp_bc[3] = sc->ga.ga_dp.dp_bc[4];
202: sc->ga.ga_dp.dp_bc[4] = sc->ga.ga_dp.dp_bc[5];
203: sc->ga.ga_dp.dp_bc[5] = sc->ga.ga_dp.dp_mod;
204: sc->ga.ga_dp.dp_mod = 0;
205: }
206: if (sc->sc_dev.dv_unit)
207: config_defer(self, lasi_gsc_attach);
208: else {
209: extern void (*cold_hook)(int);
210:
211: lasi_gsc_attach(self);
212: /* could be already set by power(4) */
213: if (!cold_hook)
214: cold_hook = lasi_cold_hook;
215: }
216: }
217:
218: void
219: lasi_gsc_attach(self)
220: struct device *self;
221: {
222: struct lasi_softc *sc = (struct lasi_softc *)self;
223:
224: sc->ga.ga_name = "gsc";
225: sc->ga.ga_hpamask = LASI_IOMASK;
226: sc->ga.ga_ic = &sc->sc_ic;
227: config_found(self, &sc->ga, gscprint);
228: }
229:
230: void
231: lasi_cold_hook(on)
232: int on;
233: {
234: register struct lasi_softc *sc = lasi_cd.cd_devs[0];
235:
236: if (!sc)
237: return;
238:
239: switch (on) {
240: case HPPA_COLD_COLD:
241: sc->sc_hw->lasi_power = LASI_BLINK;
242: break;
243: case HPPA_COLD_HOT:
244: sc->sc_hw->lasi_power = 0;
245: break;
246: case HPPA_COLD_OFF:
247: sc->sc_hw->lasi_power = LASI_OFF;
248: break;
249: }
250: }
CVSweb