xref: /openbsd-src/sys/arch/hppa/dev/lasi.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: lasi.c,v 1.4 2001/06/09 03:57:19 mickey Exp $	*/
2 
3 /*
4  * Copyright (c) 1998,1999 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  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Michael Shalayeff.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #undef LASIDEBUG
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/reboot.h>
39 
40 #include <machine/bus.h>
41 #include <machine/iomod.h>
42 #include <machine/autoconf.h>
43 
44 #include <hppa/dev/cpudevs.h>
45 
46 #include <hppa/gsc/gscbusvar.h>
47 
48 struct lasi_hwr {
49 	u_int32_t lasi_power;
50 	u_int32_t lasi_error;
51 	u_int32_t lasi_version;
52 	u_int32_t lasi_reset;
53 	u_int32_t lasi_arbmask;
54 };
55 
56 struct lasi_trs {
57 	u_int32_t lasi_irr;	/* int requset register */
58 	u_int32_t lasi_imr;	/* int mask register */
59 	u_int32_t lasi_ipr;	/* int pending register */
60 	u_int32_t lasi_icr;	/* int command? register */
61 	u_int32_t lasi_iar;	/* int acquire? register */
62 };
63 
64 struct lasi_softc {
65 	struct device sc_dev;
66 	struct gscbus_ic sc_ic;
67 
68 	struct lasi_hwr volatile *sc_hw;
69 	struct lasi_trs volatile *sc_trs;
70 };
71 
72 int	lasimatch __P((struct device *, void *, void *));
73 void	lasiattach __P((struct device *, struct device *, void *));
74 
75 struct cfattach lasi_ca = {
76 	sizeof(struct lasi_softc), lasimatch, lasiattach
77 };
78 
79 struct cfdriver lasi_cd = {
80 	NULL, "lasi", DV_DULL
81 };
82 
83 void lasi_intr_establish __P((void *v, u_int32_t mask));
84 void lasi_intr_disestablish __P((void *v, u_int32_t mask));
85 u_int32_t lasi_intr_check __P((void *v));
86 void lasi_intr_ack __P((void *v, u_int32_t mask));
87 
88 
89 int
90 lasimatch(parent, cfdata, aux)
91 	struct device *parent;
92 	void *cfdata;
93 	void *aux;
94 {
95 	register struct confargs *ca = aux;
96 	/* register struct cfdata *cf = cfdata; */
97 
98 	if (ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
99 	    ca->ca_type.iodc_sv_model != HPPA_BHA_LASI)
100 		return 0;
101 
102 	return 1;
103 }
104 
105 void
106 lasiattach(parent, self, aux)
107 	struct device *parent;
108 	struct device *self;
109 	void *aux;
110 {
111 	register struct confargs *ca = aux;
112 	register struct lasi_softc *sc = (struct lasi_softc *)self;
113 	struct gsc_attach_args ga;
114 	bus_space_handle_t ioh;
115 	int s, in;
116 
117 	if (bus_space_map(ca->ca_iot, ca->ca_hpa + 0xc000,
118 			  IOMOD_HPASIZE, 0, &ioh)) {
119 #ifdef DEBUG
120 		printf("lasiattach: can't map IO space\n");
121 #endif
122 		return;
123 	}
124 
125 	sc->sc_trs = (struct lasi_trs *)ca->ca_hpa;
126 	sc->sc_hw = (struct lasi_hwr *)(ca->ca_hpa + 0xc000);
127 
128 	/* XXX should we reset the chip here? */
129 
130 	printf (": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4,
131 		sc->sc_hw->lasi_version & 0xf);
132 
133 	/* interrupts guts */
134 	s = splhigh();
135 	sc->sc_trs->lasi_iar = cpu_gethpa(0) | (31 - ca->ca_irq);
136 	sc->sc_trs->lasi_icr = 0;
137 	sc->sc_trs->lasi_imr = ~0U;
138 	in = sc->sc_trs->lasi_irr;
139 	sc->sc_trs->lasi_imr = 0;
140 	splx(s);
141 
142 	sc->sc_ic.gsc_type = gsc_lasi;
143 	sc->sc_ic.gsc_dv = sc;
144 	sc->sc_ic.gsc_intr_establish = lasi_intr_establish;
145 	sc->sc_ic.gsc_intr_disestablish = lasi_intr_disestablish;
146 	sc->sc_ic.gsc_intr_check = lasi_intr_check;
147 	sc->sc_ic.gsc_intr_ack = lasi_intr_ack;
148 
149 	ga.ga_ca = *ca;	/* clone from us */
150 	ga.ga_name = "gsc";
151 	ga.ga_ic = &sc->sc_ic;
152 	config_found(self, &ga, gscprint);
153 }
154 
155 void
156 lasi_intr_establish(v, mask)
157 	void *v;
158 	u_int32_t mask;
159 {
160 	register struct lasi_softc *sc = v;
161 
162 	sc->sc_trs->lasi_imr |= mask;
163 }
164 
165 void
166 lasi_intr_disestablish(v, mask)
167 	void *v;
168 	u_int32_t mask;
169 {
170 	register struct lasi_softc *sc = v;
171 
172 	sc->sc_trs->lasi_imr &= ~mask;
173 }
174 
175 u_int32_t
176 lasi_intr_check(v)
177 	void *v;
178 {
179 	register struct lasi_softc *sc = v;
180 	register u_int32_t irr, imr, ipr;
181 
182 	imr = sc->sc_trs->lasi_imr;
183 	ipr = sc->sc_trs->lasi_ipr;
184 	irr = sc->sc_trs->lasi_irr;
185 	sc->sc_trs->lasi_imr = 0;
186 	sc->sc_trs->lasi_imr = imr &= ~irr;
187 
188 #ifdef LASIDEBUG
189 	printf ("%s: imr=0x%x, irr=0x%x, ipr=0x%x, iar=0x%x, icr=0x%x\n",
190 		sc->sc_dev.dv_xname, imr, irr, ipr,
191 		sc->sc_trs->lasi_iar, sc->sc_trs->lasi_icr);
192 #endif
193 
194 	return irr;
195 }
196 
197 void
198 lasi_intr_ack(v, mask)
199 	void *v;
200 	u_int32_t mask;
201 {
202 	register struct lasi_softc *sc = v;
203 
204 	sc->sc_trs->lasi_imr |= mask;
205 }
206