am79c930.c revision 1.2 1 /* $NetBSD: am79c930.c,v 1.2 1999/11/05 05:13:36 sommerfeld Exp $ */
2
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Bill Sommerfeld
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * Am79c930 chip driver.
41 *
42 * This is used by the awi driver to use the shared
43 * memory attached to the 79c930 to communicate with the firmware running
44 * in the 930's on-board 80188 core.
45 *
46 * The 79c930 can be mapped into just I/O space, or also have a
47 * memory mapping; the mapping must be set up by the bus front-end
48 * before am79c930_init is called.
49 */
50
51 /*
52 * operations:
53 *
54 * read_8, read_16, read_32, read_64, read_bytes
55 * write_8, write_16, write_32, write_64, write_bytes
56 * (two versions, depending on whether memory-space or i/o space is in use).
57 *
58 * interrupt E.C.
59 * start isr
60 * end isr
61 */
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
66 #include <sys/device.h>
67
68 #include <machine/cpu.h>
69 #include <machine/bus.h>
70 #include <machine/intr.h>
71
72 #include <dev/ic/am79c930reg.h>
73 #include <dev/ic/am79c930var.h>
74
75 #define AM930_DELAY(x) /*nothing*/;
76
77 void am79c930_regdump __P((struct am79c930_softc *sc));
78
79 static void io_write_1 __P((struct am79c930_softc *, u_int32_t, u_int8_t));
80 static void io_write_2 __P((struct am79c930_softc *, u_int32_t, u_int16_t));
81 static void io_write_4 __P((struct am79c930_softc *, u_int32_t, u_int32_t));
82 static void io_write_bytes __P((struct am79c930_softc *, u_int32_t, u_int8_t *, size_t));
83
84 static u_int8_t io_read_1 __P((struct am79c930_softc *, u_int32_t));
85 static u_int16_t io_read_2 __P((struct am79c930_softc *, u_int32_t));
86 static u_int32_t io_read_4 __P((struct am79c930_softc *, u_int32_t));
87 static void io_read_bytes __P((struct am79c930_softc *, u_int32_t, u_int8_t *, size_t));
88
89 static void mem_write_1 __P((struct am79c930_softc *, u_int32_t, u_int8_t));
90 static void mem_write_2 __P((struct am79c930_softc *, u_int32_t, u_int16_t));
91 static void mem_write_4 __P((struct am79c930_softc *, u_int32_t, u_int32_t));
92 static void mem_write_bytes __P((struct am79c930_softc *, u_int32_t, u_int8_t *, size_t));
93
94 static u_int8_t mem_read_1 __P((struct am79c930_softc *, u_int32_t));
95 static u_int16_t mem_read_2 __P((struct am79c930_softc *, u_int32_t));
96 static u_int32_t mem_read_4 __P((struct am79c930_softc *, u_int32_t));
97 static void mem_read_bytes __P((struct am79c930_softc *, u_int32_t, u_int8_t *, size_t));
98
99 static struct am79c930_ops iospace_ops = {
100 io_write_1,
101 io_write_2,
102 io_write_4,
103 io_write_bytes,
104 io_read_1,
105 io_read_2,
106 io_read_4,
107 io_read_bytes
108 };
109
110 struct am79c930_ops memspace_ops = {
111 mem_write_1,
112 mem_write_2,
113 mem_write_4,
114 mem_write_bytes,
115 mem_read_1,
116 mem_read_2,
117 mem_read_4,
118 mem_read_bytes
119 };
120
121 static void io_write_1 (sc, off, val)
122 struct am79c930_softc *sc;
123 u_int32_t off;
124 u_int8_t val;
125 {
126 /* XXX bank-switching? */
127 AM930_DELAY(1);
128 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
129 ((off>>8)& 0x7f));
130 AM930_DELAY(1);
131 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
132 AM930_DELAY(1);
133 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA, val);
134 AM930_DELAY(1);
135 }
136
137 static void io_write_2 (sc, off, val)
138 struct am79c930_softc *sc;
139 u_int32_t off;
140 u_int16_t val;
141 {
142 io_write_1(sc, off, val & 0xff);
143 io_write_1(sc, off+1, (val >> 8) & 0xff);
144 }
145
146 static void io_write_4 (sc, off, val)
147 struct am79c930_softc *sc;
148 u_int32_t off;
149 u_int32_t val;
150 {
151 /* XXX higher offset values needed for bank-switching! */
152 io_write_1(sc, off, val & 0xff);
153 io_write_1(sc, off+1, (val >> 8) & 0xff);
154 io_write_1(sc, off+2, (val >> 16) & 0xff);
155 io_write_1(sc, off+3, (val >> 24) & 0xff);
156 }
157
158 static void io_write_bytes (sc, off, ptr, len)
159 struct am79c930_softc *sc;
160 u_int32_t off;
161 u_int8_t *ptr;
162 size_t len;
163 {
164 int i;
165 /* XXX higher offset values needed for bank-switching! */
166
167 for (i=0; i<len; i++)
168 io_write_1 (sc, off+i, ptr[i]);
169 }
170
171 static u_int8_t io_read_1 (sc, off)
172 struct am79c930_softc *sc;
173 u_int32_t off;
174 {
175 u_int8_t val;
176
177 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
178 ((off>>8)& 0x7f));
179 AM930_DELAY(1);
180 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
181 AM930_DELAY(1);
182 val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
183 AM930_DELAY(1);
184 return val;
185 }
186
187 static u_int16_t io_read_2 (sc, off)
188 struct am79c930_softc *sc;
189 u_int32_t off;
190 {
191 return io_read_1 (sc, off) |
192 (io_read_1 (sc, off+1) << 8);
193 }
194
195 static u_int32_t io_read_4 (sc, off)
196 struct am79c930_softc *sc;
197 u_int32_t off;
198 {
199 /* XXX bank-switching? */
200 return io_read_1 (sc, off) |
201 (io_read_1 (sc, off+1) << 8) |
202 (io_read_1 (sc, off+2) << 16) |
203 (io_read_1 (sc, off+3) << 24);
204 }
205
206 static void io_read_bytes (sc, off, ptr, len)
207 struct am79c930_softc *sc;
208 u_int32_t off;
209 u_int8_t *ptr;
210 size_t len;
211 {
212 int i;
213
214 for (i=0; i<len; i++)
215 ptr[i] = io_read_1(sc, off+i);
216 }
217
218
219
220 static void mem_write_1 (sc, off, val)
221 struct am79c930_softc *sc;
222 u_int32_t off;
223 u_int8_t val;
224 {
225 /* XXX higher offset values needed for bank-switching! */
226 bus_space_write_1(sc->sc_memt, sc->sc_memh, off, val);
227 }
228
229 static void mem_write_2 (sc, off, val)
230 struct am79c930_softc *sc;
231 u_int32_t off;
232 u_int16_t val;
233 {
234 /* XXX higher offset values needed for bank-switching! */
235 bus_space_write_1(sc->sc_memt, sc->sc_memh, off, val & 0xff);
236 bus_space_write_1(sc->sc_memt, sc->sc_memh, off+1, (val >> 8) & 0xff);
237 }
238
239 static void mem_write_4 (sc, off, val)
240 struct am79c930_softc *sc;
241 u_int32_t off;
242 u_int32_t val;
243 {
244 /* XXX higher offset values needed for bank-switching! */
245 bus_space_write_1(sc->sc_memt, sc->sc_memh, off, val & 0xff);
246 bus_space_write_1(sc->sc_memt, sc->sc_memh, off+1, (val >> 8) & 0xff);
247 bus_space_write_1(sc->sc_memt, sc->sc_memh, off+2, (val >> 16) & 0xff);
248 bus_space_write_1(sc->sc_memt, sc->sc_memh, off+3, (val >> 24) & 0xff);
249 }
250
251 static void mem_write_bytes (sc, off, ptr, len)
252 struct am79c930_softc *sc;
253 u_int32_t off;
254 u_int8_t *ptr;
255 size_t len;
256 {
257 int i;
258 /* XXX higher offset values needed for bank-switching! */
259
260 for (i=0; i<len; i++)
261 bus_space_write_1 (sc->sc_memt, sc->sc_memh, off+i, ptr[i]);
262 }
263
264
265 static u_int8_t mem_read_1 (sc, off)
266 struct am79c930_softc *sc;
267 u_int32_t off;
268 {
269 /* XXX higher offset values needed for bank-switching! */
270 return bus_space_read_1(sc->sc_memt, sc->sc_memh, off);
271 }
272
273 static u_int16_t mem_read_2 (sc, off)
274 struct am79c930_softc *sc;
275 u_int32_t off;
276 {
277 /* XXX higher offset values needed for bank-switching! */
278 return
279 bus_space_read_1(sc->sc_memt, sc->sc_memh, off) |
280 (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) <<8);
281 }
282
283 static u_int32_t mem_read_4 (sc, off)
284 struct am79c930_softc *sc;
285 u_int32_t off;
286 {
287 /* XXX higher offset values needed for bank-switching! */
288 return
289 bus_space_read_1(sc->sc_memt, sc->sc_memh, off) |
290 (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) <<8)|
291 (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+2) <<16) |
292 (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+3) <<24);
293 }
294
295
296
297 static void mem_read_bytes (sc, off, ptr, len)
298 struct am79c930_softc *sc;
299 u_int32_t off;
300 u_int8_t *ptr;
301 size_t len;
302 {
303 int i;
304
305 /* XXX higher offset values needed for bank-switching! */
306
307 for (i=0; i<len; i++)
308 ptr[i] = bus_space_read_1(sc->sc_memt, sc->sc_memh, off+i);
309 }
310
311
312
313
314 /*
315 * Set bits in GCR.
316 */
317
318 void am79c930_gcr_setbits (sc, bits)
319 struct am79c930_softc *sc;
320 u_int8_t bits;
321 {
322 u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
323
324 gcr |= bits;
325
326 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
327 }
328
329 /*
330 * Clear bits in GCR.
331 */
332
333 void am79c930_gcr_clearbits (sc, bits)
334 struct am79c930_softc *sc;
335 u_int8_t bits;
336 {
337 u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
338
339 gcr &= ~bits;
340
341 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
342 }
343
344 u_int8_t am79c930_gcr_read (sc)
345 struct am79c930_softc *sc;
346 {
347 return bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
348 }
349
350 #if 0
351 void am79c930_regdump (sc)
352 struct am79c930_softc *sc;
353 {
354 u_int8_t buf[8];
355 int i;
356
357 AM930_DELAY(5);
358 for (i=0; i<8; i++) {
359 buf[i] = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, i);
360 AM930_DELAY(5);
361 }
362 printf("am79c930: regdump:");
363 for (i=0; i<8; i++) {
364 printf(" %02x", buf[i]);
365 }
366 printf("\n");
367 }
368 #endif
369
370 void am79c930_chip_init (sc, how)
371 struct am79c930_softc *sc;
372 {
373 /* zero the bank select register, and leave it that way.. */
374 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_BSS, 0);
375 if (how)
376 sc->sc_ops = &memspace_ops;
377 else
378 sc->sc_ops = &iospace_ops;
379 }
380
381
382