jazzio.c revision 1.2 1 /* $NetBSD: jazzio.c,v 1.2 2001/02/17 04:27:55 tsutsui Exp $ */
2 /* $OpenBSD: picabus.c,v 1.11 1999/01/11 05:11:10 millert Exp $ */
3 /* NetBSD: tc.c,v 1.2 1995/03/08 00:39:05 cgd Exp */
4
5 /*
6 * Copyright (c) 1994, 1995 Carnegie-Mellon University.
7 * All rights reserved.
8 *
9 * Author: Chris G. Demetriou
10 * Author: Per Fogelstrom. (Mips R4x00)
11 *
12 * Permission to use, copy, modify and distribute this software and
13 * its documentation is hereby granted, provided that both the copyright
14 * notice and this permission notice appear in all copies of the
15 * software, derivative works or modified versions, and any portions
16 * thereof, and that both notices appear in supporting documentation.
17 *
18 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
19 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
20 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
21 *
22 * Carnegie Mellon requests users of this software to return to
23 *
24 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
25 * School of Computer Science
26 * Carnegie Mellon University
27 * Pittsburgh PA 15213-3890
28 *
29 * any improvements or extensions that they make and grant Carnegie the
30 * rights to redistribute these changes.
31 */
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/proc.h>
36 #include <sys/user.h>
37 #include <sys/device.h>
38
39 #include <uvm/uvm_extern.h>
40
41 #include <machine/bus.h>
42 #include <machine/intr.h>
43 #include <machine/cpu.h>
44 #include <machine/pio.h>
45 #include <machine/autoconf.h>
46
47 #include <arc/jazz/jazziovar.h>
48 #include <arc/jazz/pica.h>
49 #include <arc/jazz/rd94.h>
50 #include <arc/arc/arctype.h>
51 #include <arc/jazz/jazzdmatlbreg.h>
52 #include <arc/jazz/dma.h>
53
54 struct jazzio_softc {
55 struct device sc_dv;
56 struct abus sc_bus;
57 struct arc_bus_dma_tag sc_dmat;
58 struct pica_dev *sc_devs;
59 };
60
61 /* Definition of the driver for autoconfig. */
62 int jazziomatch(struct device *, struct cfdata *, void *);
63 void jazzioattach(struct device *, struct device *, void *);
64 int jazzioprint(void *, const char *);
65
66 struct cfattach jazzio_ca = {
67 sizeof(struct jazzio_softc), jazziomatch, jazzioattach
68 };
69 extern struct cfdriver jazzio_cd;
70
71 void jazzio_intr_establish(int, int (*)(void *), void *);
72 void jazzio_intr_disestablish(int);
73 int pica_iointr(unsigned int, struct clockframe *);
74 int pica_clkintr(unsigned int, struct clockframe *);
75 int rd94_iointr(unsigned int, struct clockframe *);
76 int rd94_clkintr(unsigned int, struct clockframe *);
77
78 intr_handler_t pica_clock_handler;
79
80 /*
81 * Interrupt dispatch table.
82 */
83 struct pica_int_desc int_table[] = {
84 {0, pica_intrnull, (void *)NULL, 0 }, /* 0 */
85 {0, pica_intrnull, (void *)NULL, 0 }, /* 1 */
86 {0, pica_intrnull, (void *)NULL, 0 }, /* 2 */
87 {0, pica_intrnull, (void *)NULL, 0 }, /* 3 */
88 {0, pica_intrnull, (void *)NULL, 0 }, /* 4 */
89 {0, pica_intrnull, (void *)NULL, 0 }, /* 5 */
90 {0, pica_intrnull, (void *)NULL, 0 }, /* 6 */
91 {0, pica_intrnull, (void *)NULL, 0 }, /* 7 */
92 {0, pica_intrnull, (void *)NULL, 0 }, /* 8 */
93 {0, pica_intrnull, (void *)NULL, 0 }, /* 9 */
94 {0, pica_intrnull, (void *)NULL, 0 }, /* 10 */
95 {0, pica_intrnull, (void *)NULL, 0 }, /* 11 */
96 {0, pica_intrnull, (void *)NULL, 0 }, /* 12 */
97 {0, pica_intrnull, (void *)NULL, 0 }, /* 13 */
98 {0, pica_intrnull, (void *)NULL, 0 }, /* 14 */
99 {0, pica_intrnull, (void *)NULL, 0 }, /* 15 */
100 };
101
102 struct pica_dev {
103 struct confargs ps_ca;
104 u_int ps_mask;
105 intr_handler_t ps_handler;
106 caddr_t ps_base;
107 };
108
109 struct pica_dev acer_pica_61_cpu[] = {
110 {{ "dallas_rtc",0, 0, },
111 0, pica_intrnull, (void *)PICA_SYS_CLOCK, },
112 {{ "lpt", 1, 0, },
113 PICA_SYS_LB_IE_PAR1, pica_intrnull, (void *)PICA_SYS_PAR1, },
114 {{ "fdc", 2, 0, },
115 PICA_SYS_LB_IE_FLOPPY,pica_intrnull, (void *)PICA_SYS_FLOPPY, },
116 {{ NULL, 3, NULL, },
117 0, pica_intrnull, (void *)NULL, },
118 {{ "vga", 4, NULL, },
119 0, pica_intrnull, (void *)PICA_V_LOCAL_VIDEO, },
120 {{ "sonic", 5, 0, },
121 PICA_SYS_LB_IE_SONIC, pica_intrnull, (void *)PICA_SYS_SONIC, },
122 {{ "asc", 6, 0, },
123 PICA_SYS_LB_IE_SCSI, pica_intrnull, (void *)PICA_SYS_SCSI, },
124 {{ "pckbd", 7, 0, },
125 PICA_SYS_LB_IE_KBD, pica_intrnull, (void *)PICA_SYS_KBD, },
126 {{ "pms", 8, NULL, },
127 PICA_SYS_LB_IE_MOUSE, pica_intrnull, (void *)PICA_SYS_KBD, },
128 {{ "com", 9, 0, },
129 PICA_SYS_LB_IE_COM1, pica_intrnull, (void *)PICA_SYS_COM1, },
130 {{ "com", 10, 0, },
131 PICA_SYS_LB_IE_COM2, pica_intrnull, (void *)PICA_SYS_COM2, },
132 {{ NULL, -1, NULL, },
133 0, NULL, (void *)NULL, },
134 };
135
136 struct pica_dev mips_magnum_r4000_cpu[] = {
137 {{ "dallas_rtc",0, 0, },
138 0, pica_intrnull, (void *)PICA_SYS_CLOCK, },
139 {{ "lpt", 1, 0, },
140 PICA_SYS_LB_IE_PAR1, pica_intrnull, (void *)PICA_SYS_PAR1, },
141 {{ "fdc", 2, 0, },
142 PICA_SYS_LB_IE_FLOPPY,pica_intrnull, (void *)PICA_SYS_FLOPPY, },
143 {{ NULL, 3, NULL, },
144 0, pica_intrnull, (void *)NULL, },
145 {{ "vxl", 4, 0, },
146 PICA_SYS_LB_IE_VIDEO, pica_intrnull, (void *)PICA_V_LOCAL_VIDEO, },
147 {{ "sonic", 5, 0, },
148 PICA_SYS_LB_IE_SONIC, pica_intrnull, (void *)PICA_SYS_SONIC, },
149 {{ "asc", 6, 0, },
150 PICA_SYS_LB_IE_SCSI, pica_intrnull, (void *)PICA_SYS_SCSI, },
151 {{ "pckbd", 7, 0, },
152 PICA_SYS_LB_IE_KBD, pica_intrnull, (void *)PICA_SYS_KBD, },
153 {{ "pms", 8, NULL, },
154 PICA_SYS_LB_IE_MOUSE, pica_intrnull, (void *)PICA_SYS_KBD, },
155 {{ "com", 9, 0, },
156 PICA_SYS_LB_IE_COM1, pica_intrnull, (void *)PICA_SYS_COM1, },
157 {{ "com", 10, 0, },
158 PICA_SYS_LB_IE_COM2, pica_intrnull, (void *)PICA_SYS_COM2, },
159 {{ NULL, -1, NULL, },
160 0, NULL, (void *)NULL, },
161 };
162
163 struct pica_dev nec_rd94_cpu[] = {
164 {{ "dallas_rtc",0, 0, },
165 0, pica_intrnull, (void *)RD94_SYS_CLOCK, },
166 {{ "lpt", 1, 0, },
167 RD94_SYS_LB_IE_PAR1, pica_intrnull, (void *)RD94_SYS_PAR1, },
168 {{ "fdc", 2, 0, },
169 RD94_SYS_LB_IE_FLOPPY,pica_intrnull, (void *)RD94_SYS_FLOPPY, },
170 {{ NULL, 3, NULL, },
171 0, pica_intrnull, (void *)NULL, },
172 {{ "sonic", 4, 0, },
173 RD94_SYS_LB_IE_SONIC, pica_intrnull, (void *)RD94_SYS_SONIC, },
174 {{ NULL, 5, 0, },
175 0, pica_intrnull, (void *)NULL, },
176 {{ NULL, 6, NULL, },
177 0, pica_intrnull, (void *)NULL, },
178 {{ "pckbd", 7, 0, },
179 RD94_SYS_LB_IE_KBD, pica_intrnull, (void *)RD94_SYS_KBD, },
180 {{ "pms", 8, NULL, },
181 RD94_SYS_LB_IE_MOUSE, pica_intrnull, (void *)RD94_SYS_KBD, },
182 {{ "com", 9, 0, },
183 RD94_SYS_LB_IE_COM1, pica_intrnull, (void *)RD94_SYS_COM1, },
184 {{ "com", 10, 0, },
185 RD94_SYS_LB_IE_COM2, pica_intrnull, (void *)RD94_SYS_COM2, },
186 {{ NULL, -1, NULL, },
187 0, NULL, (void *)NULL, },
188 };
189
190 struct pica_dev *pica_cpu_devs[] = {
191 NULL, /* Unused */
192 acer_pica_61_cpu, /* Acer PICA */
193 mips_magnum_r4000_cpu, /* Mips MAGNUM R4000 */
194 nec_rd94_cpu, /* NEC-R94 */
195 nec_rd94_cpu, /* NEC-RA'94 */
196 nec_rd94_cpu, /* NEC-RD94 */
197 nec_rd94_cpu, /* NEC-R96 */
198 NULL,
199 NULL,
200 NULL,
201 NULL,
202 nec_rd94_cpu, /* NEC-JC94 */
203 };
204 int npica_cpu_devs = sizeof pica_cpu_devs / sizeof pica_cpu_devs[0];
205
206 int jazzio_found = 0;
207 int local_int_mask = 0; /* Local interrupt enable mask */
208
209 extern struct arc_bus_space pica_bus;
210
211 int
212 jazziomatch(parent, match, aux)
213 struct device *parent;
214 struct cfdata *match;
215 void *aux;
216 {
217 struct confargs *ca = aux;
218
219 /* Make sure that we're looking for a PICA. */
220 if (strcmp(ca->ca_name, jazzio_cd.cd_name) != 0)
221 return (0);
222
223 /* Make sure that unit exists. */
224 if (jazzio_found ||
225 cputype > npica_cpu_devs || pica_cpu_devs[cputype] == NULL)
226 return (0);
227
228 return (1);
229 }
230
231 void
232 jazzioattach(parent, self, aux)
233 struct device *parent;
234 struct device *self;
235 void *aux;
236 {
237 struct jazzio_softc *sc = (struct jazzio_softc *)self;
238 struct jazzio_attach_args ja;
239 int i;
240
241 printf("\n");
242
243 jazzio_found = 1;
244
245 /* keep our CPU device description handy */
246 sc->sc_devs = pica_cpu_devs[cputype];
247
248 /* set up interrupt handlers */
249 switch (cputype) {
250 case ACER_PICA_61:
251 case MAGNUM:
252 set_intr(MIPS_INT_MASK_1, pica_iointr, 2);
253 break;
254 case NEC_R94:
255 case NEC_RAx94:
256 case NEC_RD94:
257 case NEC_R96:
258 case NEC_JC94:
259 set_intr(MIPS_INT_MASK_1, rd94_iointr, 2);
260 break;
261 }
262
263 sc->sc_bus.ab_dv = (struct device *)sc;
264
265 /* Initialize PICA Dma */
266 picaDmaInit();
267
268 /* Create bus_dma_tag */
269 jazz_bus_dma_tag_init(&sc->sc_dmat);
270
271 /* Try to configure each PICA attached device */
272 for (i = 0; sc->sc_devs[i].ps_ca.ca_slot >= 0; i++) {
273
274 if(sc->sc_devs[i].ps_ca.ca_name == NULL)
275 continue; /* Empty slot */
276
277 ja.ja_name = sc->sc_devs[i].ps_ca.ca_name;
278 ja.ja_bus = &sc->sc_bus;
279 ja.ja_bust = &pica_bus;
280 ja.ja_dmat = &sc->sc_dmat;
281 ja.ja_addr = (bus_addr_t)sc->sc_devs[i].ps_base;
282 ja.ja_intr = sc->sc_devs[i].ps_ca.ca_slot;
283 ja.ja_dma = 0;
284
285 /* Tell the autoconfig machinery we've found the hardware. */
286 config_found(self, &ja, jazzioprint);
287 }
288 }
289
290 int
291 jazzioprint(aux, pnp)
292 void *aux;
293 const char *pnp;
294 {
295 struct jazzio_attach_args *ja = aux;
296
297 if (pnp)
298 printf("%s at %s", ja->ja_name, pnp);
299 printf(" addr 0x%lx intr %d", ja->ja_addr, ja->ja_intr);
300 return (UNCONF);
301 }
302
303 void
304 jazzio_intr_establish(slot, handler, val)
305 int slot;
306 intr_handler_t handler;
307 void *val;
308 {
309 struct jazzio_softc *sc = jazzio_cd.cd_devs[0];
310
311 if(slot == 0) { /* Slot 0 is special, clock */
312 pica_clock_handler = handler;
313 switch (cputype) {
314 case ACER_PICA_61:
315 case MAGNUM:
316 set_intr(MIPS_INT_MASK_4, pica_clkintr, 1);
317 break;
318 case NEC_R94:
319 case NEC_RAx94:
320 case NEC_RD94:
321 case NEC_R96:
322 case NEC_JC94:
323 set_intr(MIPS_INT_MASK_3, rd94_clkintr, 1);
324 break;
325 }
326 }
327
328 if(int_table[slot].int_mask != 0) {
329 panic("pica intr already set");
330 }
331 else {
332 int_table[slot].int_mask = sc->sc_devs[slot].ps_mask;;
333 local_int_mask |= int_table[slot].int_mask;
334 int_table[slot].int_hand = handler;
335 int_table[slot].param = val;
336 }
337
338 switch (cputype) {
339 case ACER_PICA_61:
340 case MAGNUM:
341 out16(PICA_SYS_LB_IE, local_int_mask);
342 break;
343
344 case NEC_R94:
345 case NEC_RAx94:
346 case NEC_RD94:
347 case NEC_R96:
348 case NEC_JC94:
349 /* XXX: I don't know why, but firmware does. */
350 if (in32(0xe0000560) != 0)
351 out16(RD94_SYS_LB_IE+2, local_int_mask);
352 else
353 out16(RD94_SYS_LB_IE, local_int_mask);
354 break;
355 }
356 }
357
358 void
359 jazzio_intr_disestablish(slot)
360 int slot;
361 {
362 if(slot != 0) { /* Slot 0 is special, clock */
363 local_int_mask &= ~int_table[slot].int_mask;
364 int_table[slot].int_mask = 0;
365 int_table[slot].int_hand = pica_intrnull;
366 int_table[slot].param = (void *)NULL;
367 }
368 }
369
370 int
371 pica_intrnull(val)
372 void *val;
373 {
374 panic("uncaught PICA intr for slot %p", val);
375 }
376
377 /*
378 * Handle pica i/o interrupt.
379 */
380 int
381 pica_iointr(mask, cf)
382 unsigned mask;
383 struct clockframe *cf;
384 {
385 int vector;
386
387 while((vector = inb(PVIS) >> 2) != 0) {
388 (*int_table[vector].int_hand)(int_table[vector].param);
389 }
390 return(~0); /* Dont reenable */
391 }
392
393 /*
394 * Handle pica interval clock interrupt.
395 */
396 int
397 pica_clkintr(mask, cf)
398 unsigned mask;
399 struct clockframe *cf;
400 {
401 int temp;
402
403 temp = inw(R4030_SYS_IT_STAT);
404 (*pica_clock_handler)(cf);
405
406 /* Re-enable clock interrupts */
407 splx(MIPS_INT_MASK_4 | MIPS_SR_INT_IE);
408
409 return(~MIPS_INT_MASK_4); /* Keep clock interrupts enabled */
410 }
411
412 /*
413 * Handle NEC-RD94 i/o interrupt.
414 */
415 int
416 rd94_iointr(mask, cf)
417 unsigned mask;
418 struct clockframe *cf;
419 {
420 int vector;
421
422 while((vector = inb(RD94_SYS_INTSTAT1) >> 2) != 0) {
423 (*int_table[vector].int_hand)(int_table[vector].param);
424 }
425 return(~0); /* Dont reenable */
426 }
427
428 /*
429 * Handle NEC-RD94 interval clock interrupt.
430 */
431 int
432 rd94_clkintr(mask, cf)
433 unsigned mask;
434 struct clockframe *cf;
435 {
436 int temp;
437
438 temp = in32(RD94_SYS_INTSTAT3);
439 (*pica_clock_handler)(cf);
440
441 /* Re-enable clock interrupts */
442 splx(MIPS_INT_MASK_3 | MIPS_SR_INT_IE);
443
444 return(~MIPS_INT_MASK_3); /* Keep clock interrupts enabled */
445 }
446