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