Home | History | Annotate | Line # | Download | only in jazz
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