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