am79c930.c revision 1.3 1 /* $NetBSD: am79c930.c,v 1.3 2000/02/17 17:37:23 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 AM930_DELAY(1);
127 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
128 ((off>>8)& 0x7f));
129 AM930_DELAY(1);
130 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
131 AM930_DELAY(1);
132 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA, val);
133 AM930_DELAY(1);
134 }
135
136 static void io_write_2 (sc, off, val)
137 struct am79c930_softc *sc;
138 u_int32_t off;
139 u_int16_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 & 0xff);
148 AM930_DELAY(1);
149 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA, (val>>8)&0xff);
150 AM930_DELAY(1);
151 }
152
153 static void io_write_4 (sc, off, val)
154 struct am79c930_softc *sc;
155 u_int32_t off;
156 u_int32_t val;
157 {
158 AM930_DELAY(1);
159 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
160 ((off>>8)& 0x7f));
161 AM930_DELAY(1);
162 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
163 AM930_DELAY(1);
164 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,val & 0xff);
165 AM930_DELAY(1);
166 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>8)&0xff);
167 AM930_DELAY(1);
168 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>16)&0xff);
169 AM930_DELAY(1);
170 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>24)&0xff);
171 AM930_DELAY(1);
172 }
173
174 static void io_write_bytes (sc, off, ptr, len)
175 struct am79c930_softc *sc;
176 u_int32_t off;
177 u_int8_t *ptr;
178 size_t len;
179 {
180 int i;
181
182 AM930_DELAY(1);
183 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
184 ((off>>8)& 0x7f));
185 AM930_DELAY(1);
186 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff));
187 AM930_DELAY(1);
188 for (i=0; i<len; i++)
189 bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,ptr[i]);
190 }
191
192 static u_int8_t io_read_1 (sc, off)
193 struct am79c930_softc *sc;
194 u_int32_t off;
195 {
196 u_int8_t val;
197
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 val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
204 AM930_DELAY(1);
205 return val;
206 }
207
208 static u_int16_t io_read_2 (sc, off)
209 struct am79c930_softc *sc;
210 u_int32_t off;
211 {
212 u_int16_t val;
213
214 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
215 ((off>>8)& 0x7f));
216 AM930_DELAY(1);
217 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
218 AM930_DELAY(1);
219 val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
220 AM930_DELAY(1);
221 val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8;
222 AM930_DELAY(1);
223 return val;
224 }
225
226 static u_int32_t io_read_4 (sc, off)
227 struct am79c930_softc *sc;
228 u_int32_t off;
229 {
230 u_int32_t val;
231
232 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
233 ((off>>8)& 0x7f));
234 AM930_DELAY(1);
235 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
236 AM930_DELAY(1);
237 val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA);
238 AM930_DELAY(1);
239 val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8;
240 AM930_DELAY(1);
241 val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 16;
242 AM930_DELAY(1);
243 val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 24;
244 AM930_DELAY(1);
245 return val;
246 }
247
248 static void io_read_bytes (sc, off, ptr, len)
249 struct am79c930_softc *sc;
250 u_int32_t off;
251 u_int8_t *ptr;
252 size_t len;
253 {
254 int i;
255
256 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI,
257 ((off>>8)& 0x7f));
258 AM930_DELAY(1);
259 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff));
260 AM930_DELAY(1);
261 for (i=0; i<len; i++)
262 ptr[i] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
263 AM79C930_IODPA);
264 }
265
266 static void mem_write_1 (sc, off, val)
267 struct am79c930_softc *sc;
268 u_int32_t off;
269 u_int8_t val;
270 {
271 bus_space_write_1(sc->sc_memt, sc->sc_memh, off, val);
272 }
273
274 static void mem_write_2 (sc, off, val)
275 struct am79c930_softc *sc;
276 u_int32_t off;
277 u_int16_t val;
278 {
279 bus_space_write_2(sc->sc_memt, sc->sc_memh, off, val);
280 }
281
282 static void mem_write_4 (sc, off, val)
283 struct am79c930_softc *sc;
284 u_int32_t off;
285 u_int32_t val;
286 {
287 bus_space_write_4(sc->sc_memt, sc->sc_memh, off, val);
288 }
289
290 static void mem_write_bytes (sc, off, ptr, len)
291 struct am79c930_softc *sc;
292 u_int32_t off;
293 u_int8_t *ptr;
294 size_t len;
295 {
296 bus_space_write_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len);
297 }
298
299
300 static u_int8_t mem_read_1 (sc, off)
301 struct am79c930_softc *sc;
302 u_int32_t off;
303 {
304 return bus_space_read_1(sc->sc_memt, sc->sc_memh, off);
305 }
306
307 static u_int16_t mem_read_2 (sc, off)
308 struct am79c930_softc *sc;
309 u_int32_t off;
310 {
311 return bus_space_read_2(sc->sc_memt, sc->sc_memh, off);
312 }
313
314 static u_int32_t mem_read_4 (sc, off)
315 struct am79c930_softc *sc;
316 u_int32_t off;
317 {
318 return bus_space_read_4(sc->sc_memt, sc->sc_memh, off);
319 }
320
321
322
323 static void mem_read_bytes (sc, off, ptr, len)
324 struct am79c930_softc *sc;
325 u_int32_t off;
326 u_int8_t *ptr;
327 size_t len;
328 {
329 bus_space_read_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len);
330 }
331
332
333
334
335 /*
336 * Set bits in GCR.
337 */
338
339 void am79c930_gcr_setbits (sc, bits)
340 struct am79c930_softc *sc;
341 u_int8_t bits;
342 {
343 u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
344
345 gcr |= bits;
346
347 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
348 }
349
350 /*
351 * Clear bits in GCR.
352 */
353
354 void am79c930_gcr_clearbits (sc, bits)
355 struct am79c930_softc *sc;
356 u_int8_t bits;
357 {
358 u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
359
360 gcr &= ~bits;
361
362 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr);
363 }
364
365 u_int8_t am79c930_gcr_read (sc)
366 struct am79c930_softc *sc;
367 {
368 return bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
369 }
370
371 #if 0
372 void am79c930_regdump (sc)
373 struct am79c930_softc *sc;
374 {
375 u_int8_t buf[8];
376 int i;
377
378 AM930_DELAY(5);
379 for (i=0; i<8; i++) {
380 buf[i] = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, i);
381 AM930_DELAY(5);
382 }
383 printf("am79c930: regdump:");
384 for (i=0; i<8; i++) {
385 printf(" %02x", buf[i]);
386 }
387 printf("\n");
388 }
389 #endif
390
391 void am79c930_chip_init (sc, how)
392 struct am79c930_softc *sc;
393 {
394 /* zero the bank select register, and leave it that way.. */
395 bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_BSS, 0);
396 if (how)
397 sc->sc_ops = &memspace_ops;
398 else
399 sc->sc_ops = &iospace_ops;
400 }
401
402
403