1 /* $NetBSD: grf_nubus.c,v 1.66 2002/10/02 05:36:38 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Allen Briggs. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /* 29 * Device-specific routines for handling Nubus-based video cards. 30 */ 31 32 #include <sys/param.h> 33 34 #include <sys/device.h> 35 #include <sys/ioctl.h> 36 #include <sys/file.h> 37 #include <sys/malloc.h> 38 #include <sys/mman.h> 39 #include <sys/proc.h> 40 #include <sys/systm.h> 41 42 #include <machine/bus.h> 43 #include <machine/cpu.h> 44 #include <machine/grfioctl.h> 45 #include <machine/viareg.h> 46 47 #include <mac68k/nubus/nubus.h> 48 #include <mac68k/dev/grfvar.h> 49 50 static void load_image_data __P((caddr_t data, struct image_data *image)); 51 52 static void grfmv_intr_generic_write1 __P((void *vsc)); 53 static void grfmv_intr_generic_write4 __P((void *vsc)); 54 static void grfmv_intr_generic_or4 __P((void *vsc)); 55 56 static void grfmv_intr_cb264 __P((void *vsc)); 57 static void grfmv_intr_cb364 __P((void *vsc)); 58 static void grfmv_intr_cmax __P((void *vsc)); 59 static void grfmv_intr_cti __P((void *vsc)); 60 static void grfmv_intr_radius __P((void *vsc)); 61 static void grfmv_intr_radius24 __P((void *vsc)); 62 static void grfmv_intr_supermacgfx __P((void *vsc)); 63 static void grfmv_intr_lapis __P((void *vsc)); 64 static void grfmv_intr_formac __P((void *vsc)); 65 static void grfmv_intr_vimage __P((void *vsc)); 66 static void grfmv_intr_gvimage __P((void *vsc)); 67 static void grfmv_intr_radius_gsc __P((void *vsc)); 68 static void grfmv_intr_radius_gx __P((void *vsc)); 69 70 static int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg)); 71 static int grfmv_match __P((struct device *, struct cfdata *, void *)); 72 static void grfmv_attach __P((struct device *, struct device *, void *)); 73 74 CFATTACH_DECL(macvid, sizeof(struct grfbus_softc), 75 grfmv_match, grfmv_attach, NULL, NULL); 76 77 static void 78 load_image_data(data, image) 79 caddr_t data; 80 struct image_data *image; 81 { 82 bcopy(data , &image->size, 4); 83 bcopy(data + 4, &image->offset, 4); 84 bcopy(data + 8, &image->rowbytes, 2); 85 bcopy(data + 10, &image->top, 2); 86 bcopy(data + 12, &image->left, 2); 87 bcopy(data + 14, &image->bottom, 2); 88 bcopy(data + 16, &image->right, 2); 89 bcopy(data + 18, &image->version, 2); 90 bcopy(data + 20, &image->packType, 2); 91 bcopy(data + 22, &image->packSize, 4); 92 bcopy(data + 26, &image->hRes, 4); 93 bcopy(data + 30, &image->vRes, 4); 94 bcopy(data + 34, &image->pixelType, 2); 95 bcopy(data + 36, &image->pixelSize, 2); 96 bcopy(data + 38, &image->cmpCount, 2); 97 bcopy(data + 40, &image->cmpSize, 2); 98 bcopy(data + 42, &image->planeBytes, 4); 99 } 100 101 102 static int 103 grfmv_match(parent, cf, aux) 104 struct device *parent; 105 struct cfdata *cf; 106 void *aux; 107 { 108 struct nubus_attach_args *na = (struct nubus_attach_args *)aux; 109 110 if (na->category != NUBUS_CATEGORY_DISPLAY) 111 return 0; 112 113 if (na->type != NUBUS_TYPE_VIDEO) 114 return 0; 115 116 if (na->drsw != NUBUS_DRSW_APPLE) 117 return 0; 118 119 /* 120 * If we've gotten this far, then we're dealing with a real-live 121 * Apple QuickDraw-compatible display card resource. Now, how to 122 * determine that this is an active resource??? Dunno. But we'll 123 * proceed like it is. 124 */ 125 126 return 1; 127 } 128 129 static void 130 grfmv_attach(parent, self, aux) 131 struct device *parent, *self; 132 void *aux; 133 { 134 struct grfbus_softc *sc = (struct grfbus_softc *)self; 135 struct nubus_attach_args *na = (struct nubus_attach_args *)aux; 136 struct image_data image_store, image; 137 struct grfmode *gm; 138 char cardname[CARD_NAME_LEN]; 139 nubus_dirent dirent; 140 nubus_dir dir, mode_dir; 141 int mode; 142 143 bcopy(na->fmt, &sc->sc_slot, sizeof(nubus_slot)); 144 145 sc->sc_tag = na->na_tag; 146 sc->card_id = na->drhw; 147 sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot); 148 sc->sc_fbofs = 0; 149 150 if (bus_space_map(sc->sc_tag, sc->sc_basepa, NBMEMSIZE, 151 0, &sc->sc_handle)) { 152 printf(": grfmv_attach: failed to map slot %d\n", na->slot); 153 return; 154 } 155 156 nubus_get_main_dir(&sc->sc_slot, &dir); 157 158 if (nubus_find_rsrc(sc->sc_tag, sc->sc_handle, 159 &sc->sc_slot, &dir, na->rsrcid, &dirent) <= 0) { 160 bad: 161 bus_space_unmap(sc->sc_tag, sc->sc_handle, NBMEMSIZE); 162 return; 163 } 164 165 nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &sc->board_dir); 166 167 if (nubus_find_rsrc(sc->sc_tag, sc->sc_handle, 168 &sc->sc_slot, &sc->board_dir, NUBUS_RSRC_TYPE, &dirent) <= 0) 169 if ((na->rsrcid != 128) || 170 (nubus_find_rsrc(sc->sc_tag, sc->sc_handle, 171 &sc->sc_slot, &dir, 129, &dirent) <= 0)) 172 goto bad; 173 174 mode = NUBUS_RSRC_FIRSTMODE; 175 if (nubus_find_rsrc(sc->sc_tag, sc->sc_handle, 176 &sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) { 177 printf(": probe failed to get board rsrc.\n"); 178 goto bad; 179 } 180 181 nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &mode_dir); 182 183 if (nubus_find_rsrc(sc->sc_tag, sc->sc_handle, 184 &sc->sc_slot, &mode_dir, VID_PARAMS, &dirent) <= 0) { 185 printf(": probe failed to get mode dir.\n"); 186 goto bad; 187 } 188 189 if (nubus_get_ind_data(sc->sc_tag, sc->sc_handle, &sc->sc_slot, 190 &dirent, (caddr_t)&image_store, sizeof(struct image_data)) <= 0) { 191 printf(": probe failed to get indirect mode data.\n"); 192 goto bad; 193 } 194 195 /* Need to load display info (and driver?), etc... (?) */ 196 197 load_image_data((caddr_t)&image_store, &image); 198 199 gm = &sc->curr_mode; 200 gm->mode_id = mode; 201 gm->ptype = image.pixelType; 202 gm->psize = image.pixelSize; 203 gm->width = image.right - image.left; 204 gm->height = image.bottom - image.top; 205 gm->rowbytes = image.rowbytes; 206 gm->hres = image.hRes; 207 gm->vres = image.vRes; 208 gm->fbsize = gm->height * gm->rowbytes; 209 gm->fbbase = (caddr_t)(sc->sc_handle.base); /* XXX evil hack */ 210 gm->fboff = image.offset; 211 212 strncpy(cardname, nubus_get_card_name(sc->sc_tag, sc->sc_handle, 213 &sc->sc_slot), CARD_NAME_LEN); 214 cardname[CARD_NAME_LEN-1] = '\0'; 215 printf(": %s\n", cardname); 216 217 if (sc->card_id == NUBUS_DRHW_TFB) { 218 /* 219 * This is the Toby card, but apparently some manufacturers 220 * (like Cornerstone) didn't bother to get/use their own 221 * value here, even though the cards are different, so we 222 * so we try to differentiate here. 223 */ 224 if (strncmp(cardname, "Samsung 768", 11) == 0) 225 sc->card_id = NUBUS_DRHW_SAM768; 226 else if (strncmp(cardname, "Toby frame", 10) != 0) 227 printf("%s: This display card pretends to be a TFB!\n", 228 sc->sc_dev.dv_xname); 229 } 230 231 switch (sc->card_id) { 232 case NUBUS_DRHW_TFB: 233 case NUBUS_DRHW_M2HRVC: 234 case NUBUS_DRHW_PVC: 235 sc->cli_offset = 0xa0000; 236 sc->cli_value = 0; 237 add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc); 238 break; 239 case NUBUS_DRHW_WVC: 240 sc->cli_offset = 0xa00000; 241 sc->cli_value = 0; 242 add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc); 243 break; 244 case NUBUS_DRHW_COLORMAX: 245 add_nubus_intr(na->slot, grfmv_intr_cmax, sc); 246 break; 247 case NUBUS_DRHW_SE30: 248 /* Do nothing--SE/30 interrupts are disabled */ 249 break; 250 case NUBUS_DRHW_MDC: 251 sc->cli_offset = 0x200148; 252 sc->cli_value = 1; 253 add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc); 254 255 /* Enable interrupts; to disable, write 0x7 to this location */ 256 bus_space_write_4(sc->sc_tag, sc->sc_handle, 0x20013C, 5); 257 break; 258 case NUBUS_DRHW_CB264: 259 add_nubus_intr(na->slot, grfmv_intr_cb264, sc); 260 break; 261 case NUBUS_DRHW_CB364: 262 add_nubus_intr(na->slot, grfmv_intr_cb364, sc); 263 break; 264 case NUBUS_DRHW_RPC8: 265 sc->cli_offset = 0xfdff8f; 266 sc->cli_value = 0xff; 267 add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc); 268 break; 269 case NUBUS_DRHW_RPC8XJ: 270 sc->cli_value = 0x66; 271 add_nubus_intr(na->slot, grfmv_intr_radius, sc); 272 break; 273 case NUBUS_DRHW_RPC24X: 274 case NUBUS_DRHW_BOOGIE: 275 sc->cli_value = 0x64; 276 add_nubus_intr(na->slot, grfmv_intr_radius, sc); 277 break; 278 case NUBUS_DRHW_RPC24XP: 279 add_nubus_intr(na->slot, grfmv_intr_radius24, sc); 280 break; 281 case NUBUS_DRHW_RADGSC: 282 add_nubus_intr(na->slot, grfmv_intr_radius_gsc, sc); 283 break; 284 case NUBUS_DRHW_RDCGX: 285 add_nubus_intr(na->slot, grfmv_intr_radius_gx, sc); 286 break; 287 case NUBUS_DRHW_FIILX: 288 case NUBUS_DRHW_FIISXDSP: 289 case NUBUS_DRHW_FUTURASX: 290 sc->cli_offset = 0xf05000; 291 sc->cli_value = 0x80; 292 add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc); 293 break; 294 case NUBUS_DRHW_SAM768: 295 add_nubus_intr(na->slot, grfmv_intr_cti, sc); 296 break; 297 case NUBUS_DRHW_SUPRGFX: 298 add_nubus_intr(na->slot, grfmv_intr_supermacgfx, sc); 299 break; 300 case NUBUS_DRHW_SPECTRM8: 301 sc->cli_offset = 0x0de178; 302 sc->cli_value = 0x80; 303 add_nubus_intr(na->slot, grfmv_intr_generic_or4, sc); 304 break; 305 case NUBUS_DRHW_LAPIS: 306 add_nubus_intr(na->slot, grfmv_intr_lapis, sc); 307 break; 308 case NUBUS_DRHW_FORMAC: 309 add_nubus_intr(na->slot, grfmv_intr_formac, sc); 310 break; 311 case NUBUS_DRHW_ROPS24LXI: 312 case NUBUS_DRHW_ROPS24XLTV: 313 case NUBUS_DRHW_ROPS24MXTV: 314 sc->cli_offset = 0xfb0010; 315 sc->cli_value = 0x00; 316 add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc); 317 break; 318 case NUBUS_DRHW_ROPSPPGT: 319 sc->cli_offset = 0xf50010; 320 sc->cli_value = 0x02; 321 add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc); 322 break; 323 case NUBUS_DRHW_VIMAGE: 324 add_nubus_intr(na->slot, grfmv_intr_vimage, sc); 325 break; 326 case NUBUS_DRHW_GVIMAGE: 327 add_nubus_intr(na->slot, grfmv_intr_gvimage, sc); 328 break; 329 case NUBUS_DRHW_MC2124NB: 330 sc->cli_offset = 0xfd1000; 331 sc->cli_value = 0x00; 332 add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc); 333 break; 334 case NUBUS_DRHW_MICRON: 335 sc->cli_offset = 0xa00014; 336 sc->cli_value = 0; 337 add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc); 338 break; 339 default: 340 printf("%s: Unknown video card ID 0x%x --", 341 sc->sc_dev.dv_xname, sc->card_id); 342 printf(" Not installing interrupt routine.\n"); 343 break; 344 } 345 346 /* Perform common video attachment. */ 347 grf_establish(sc, &sc->sc_slot, grfmv_mode); 348 } 349 350 static int 351 grfmv_mode(gp, cmd, arg) 352 struct grf_softc *gp; 353 int cmd; 354 void *arg; 355 { 356 switch (cmd) { 357 case GM_GRFON: 358 case GM_GRFOFF: 359 return 0; 360 case GM_CURRMODE: 361 break; 362 case GM_NEWMODE: 363 break; 364 case GM_LISTMODES: 365 break; 366 } 367 return EINVAL; 368 } 369 370 /* Interrupt handlers... */ 371 /* 372 * Generic routine to clear interrupts for cards where it simply takes 373 * a MOV.B to clear the interrupt. The offset and value of this byte 374 * varies between cards. 375 */ 376 /*ARGSUSED*/ 377 static void 378 grfmv_intr_generic_write1(vsc) 379 void *vsc; 380 { 381 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 382 383 bus_space_write_1(sc->sc_tag, sc->sc_handle, 384 sc->cli_offset, (u_int8_t)sc->cli_value); 385 } 386 387 /* 388 * Generic routine to clear interrupts for cards where it simply takes 389 * a MOV.L to clear the interrupt. The offset and value of this byte 390 * varies between cards. 391 */ 392 /*ARGSUSED*/ 393 static void 394 grfmv_intr_generic_write4(vsc) 395 void *vsc; 396 { 397 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 398 399 bus_space_write_4(sc->sc_tag, sc->sc_handle, 400 sc->cli_offset, sc->cli_value); 401 } 402 403 /* 404 * Generic routine to clear interrupts for cards where it simply takes 405 * an OR.L to clear the interrupt. The offset and value of this byte 406 * varies between cards. 407 */ 408 /*ARGSUSED*/ 409 static void 410 grfmv_intr_generic_or4(vsc) 411 void *vsc; 412 { 413 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 414 unsigned long scratch; 415 416 scratch = bus_space_read_4(sc->sc_tag, sc->sc_handle, sc->cli_offset); 417 scratch |= 0x80; 418 bus_space_write_4(sc->sc_tag, sc->sc_handle, sc->cli_offset, scratch); 419 } 420 421 /* 422 * Routine to clear interrupts for the Radius PrecisionColor 8xj card. 423 */ 424 /*ARGSUSED*/ 425 static void 426 grfmv_intr_radius(vsc) 427 void *vsc; 428 { 429 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 430 u_int8_t c; 431 432 c = sc->cli_value; 433 434 c |= 0x80; 435 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0xd00403, c); 436 c &= 0x7f; 437 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0xd00403, c); 438 } 439 440 /* 441 * Routine to clear interrupts for the Radius PrecisionColor 24Xp card. 442 * Is this what the 8xj routine is doing, too? 443 */ 444 /*ARGSUSED*/ 445 static void 446 grfmv_intr_radius24(vsc) 447 void *vsc; 448 { 449 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 450 u_int8_t c; 451 452 c = 0x80 | bus_space_read_1(sc->sc_tag, sc->sc_handle, 0xfffd8); 453 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0xd00403, c); 454 c &= 0x7f; 455 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0xd00403, c); 456 } 457 458 /* 459 * Routine to clear interrupts on Samsung 768x1006 video controller. 460 * This controller was manufactured by Cornerstone Technology, Inc., 461 * now known as Cornerstone Imaging. 462 * 463 * To clear this interrupt, we apparently have to set, then clear, 464 * bit 2 at byte offset 0x80000 from the card's base. 465 * Information for this provided by Brad Salai <bsalai@servtech.com> 466 */ 467 /*ARGSUSED*/ 468 static void 469 grfmv_intr_cti(vsc) 470 void *vsc; 471 { 472 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 473 u_int8_t c; 474 475 c = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0x80000); 476 c |= 0x02; 477 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x80000, c); 478 c &= 0xfd; 479 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x80000, c); 480 } 481 482 /*ARGSUSED*/ 483 static void 484 grfmv_intr_cb264(vsc) 485 void *vsc; 486 { 487 struct grfbus_softc *sc; 488 volatile char *slotbase; 489 490 sc = (struct grfbus_softc *)vsc; 491 slotbase = (volatile char *)(sc->sc_handle.base); /* XXX evil hack */ 492 __asm __volatile( 493 " movl %0,%%a0 \n" 494 " movl %%a0@(0xff6028),%%d0 \n" 495 " andl #0x2,%%d0 \n" 496 " beq _mv_intr0 \n" 497 " movql #0x3,%%d0 \n" 498 "_mv_intr0: \n" 499 " movl %%a0@(0xff600c),%%d1 \n" 500 " andl #0x3,%%d1 \n" 501 " cmpl %%d1,%%d0 \n" 502 " beq _mv_intr_fin \n" 503 " movl %%d0,%%a0@(0xff600c) \n" 504 " nop \n" 505 " tstb %%d0 \n" 506 " beq _mv_intr1 \n" 507 " movl #0x0002,%%a0@(0xff6040) \n" 508 " movl #0x0102,%%a0@(0xff6044) \n" 509 " movl #0x0105,%%a0@(0xff6048) \n" 510 " movl #0x000e,%%a0@(0xff604c) \n" 511 " movl #0x001c,%%a0@(0xff6050) \n" 512 " movl #0x00bc,%%a0@(0xff6054) \n" 513 " movl #0x00c3,%%a0@(0xff6058) \n" 514 " movl #0x0061,%%a0@(0xff605c) \n" 515 " movl #0x0012,%%a0@(0xff6060) \n" 516 " bra _mv_intr_fin \n" 517 "_mv_intr1: \n" 518 " movl #0x0002,%%a0@(0xff6040) \n" 519 " movl #0x0209,%%a0@(0xff6044) \n" 520 " movl #0x020c,%%a0@(0xff6048) \n" 521 " movl #0x000f,%%a0@(0xff604c) \n" 522 " movl #0x0027,%%a0@(0xff6050) \n" 523 " movl #0x00c7,%%a0@(0xff6054) \n" 524 " movl #0x00d7,%%a0@(0xff6058) \n" 525 " movl #0x006b,%%a0@(0xff605c) \n" 526 " movl #0x0029,%%a0@(0xff6060) \n" 527 "_mv_intr_fin: \n" 528 " movl #0x1,%%a0@(0xff6014)" 529 : : "g" (slotbase) : "a0","d0","d1"); 530 } 531 532 /* 533 * Support for the Colorboard 364 might be more complex than it needs to 534 * be. If we can find more information about this card, this might be 535 * significantly simplified. Contributions welcome... :-) 536 */ 537 /*ARGSUSED*/ 538 static void 539 grfmv_intr_cb364(vsc) 540 void *vsc; 541 { 542 struct grfbus_softc *sc; 543 volatile char *slotbase; 544 545 sc = (struct grfbus_softc *)vsc; 546 slotbase = (volatile char *)(sc->sc_handle.base); /* XXX evil hack */ 547 __asm __volatile( 548 " movl %0,%%a0 \n" 549 " movl %%a0@(0xfe6028),%%d0 \n" 550 " andl #0x2,%%d0 \n" 551 " beq _cb364_intr4 \n" 552 " movql #0x3,%%d0 \n" 553 " movl %%a0@(0xfe6018),%%d1 \n" 554 " movl #0x3,%%a0@(0xfe6018) \n" 555 " movw %%a0@(0xfe7010),%%d2 \n" 556 " movl %%d1,%%a0@(0xfe6018) \n" 557 " movl %%a0@(0xfe6020),%%d1 \n" 558 " btst #0x06,%%d2 \n" 559 " beq _cb364_intr0 \n" 560 " btst #0x00,%%d1 \n" 561 " beq _cb364_intr5 \n" 562 " bsr _cb364_intr1 \n" 563 " bra _cb364_intr_out \n" 564 "_cb364_intr0: \n" 565 " btst #0x00,%%d1 \n" 566 " bne _cb364_intr5 \n" 567 " bsr _cb364_intr1 \n" 568 " bra _cb364_intr_out \n" 569 "_cb364_intr1: \n" 570 " movl %%d0,%%a0@(0xfe600c) \n" 571 " nop \n" 572 " tstb %%d0 \n" 573 " beq _cb364_intr3 \n" 574 " movl #0x0002,%%a0@(0xfe6040) \n" 575 " movl #0x0105,%%a0@(0xfe6048) \n" 576 " movl #0x000e,%%a0@(0xfe604c) \n" 577 " movl #0x00c3,%%a0@(0xfe6058) \n" 578 " movl #0x0061,%%a0@(0xfe605c) \n" 579 " btst #0x06,%%d2 \n" 580 " beq _cb364_intr2 \n" 581 " movl #0x001c,%%a0@(0xfe6050) \n" 582 " movl #0x00bc,%%a0@(0xfe6054) \n" 583 " movl #0x0012,%%a0@(0xfe6060) \n" 584 " movl #0x000e,%%a0@(0xfe6044) \n" 585 " movl #0x00c3,%%a0@(0xfe6064) \n" 586 " movl #0x0061,%%a0@(0xfe6020) \n" 587 " rts \n" 588 "_cb364_intr2: \n" 589 " movl #0x0016,%%a0@(0xfe6050) \n" 590 " movl #0x00b6,%%a0@(0xfe6054) \n" 591 " movl #0x0011,%%a0@(0xfe6060) \n" 592 " movl #0x0101,%%a0@(0xfe6044) \n" 593 " movl #0x00bf,%%a0@(0xfe6064) \n" 594 " movl #0x0001,%%a0@(0xfe6020) \n" 595 " rts \n" 596 "_cb364_intr3: \n" 597 " movl #0x0002,%%a0@(0xfe6040) \n" 598 " movl #0x0209,%%a0@(0xfe6044) \n" 599 " movl #0x020c,%%a0@(0xfe6048) \n" 600 " movl #0x000f,%%a0@(0xfe604c) \n" 601 " movl #0x0027,%%a0@(0xfe6050) \n" 602 " movl #0x00c7,%%a0@(0xfe6054) \n" 603 " movl #0x00d7,%%a0@(0xfe6058) \n" 604 " movl #0x006b,%%a0@(0xfe605c) \n" 605 " movl #0x0029,%%a0@(0xfe6060) \n" 606 " oril #0x0040,%%a0@(0xfe6064) \n" 607 " movl #0x0000,%%a0@(0xfe6020) \n" 608 " rts \n" 609 "_cb364_intr4: \n" 610 " movq #0x00,%%d0 \n" 611 "_cb364_intr5: \n" 612 " movl %%a0@(0xfe600c),%%d1 \n" 613 " andl #0x3,%%d1 \n" 614 " cmpl %%d1,%%d0 \n" 615 " beq _cb364_intr_out \n" 616 " bsr _cb364_intr1 \n" 617 "_cb364_intr_out: \n" 618 " movl #0x1,%%a0@(0xfe6014) \n" 619 "_cb364_intr_quit:" 620 : : "g" (slotbase) : "a0","d0","d1","d2"); 621 } 622 623 /* 624 * Interrupt clearing routine for SuperMac GFX card. 625 */ 626 /*ARGSUSED*/ 627 static void 628 grfmv_intr_supermacgfx(vsc) 629 void *vsc; 630 { 631 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 632 u_int8_t dummy; 633 634 dummy = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0xE70D3); 635 } 636 637 /* 638 * Routine to clear interrupts for the Sigma Designs ColorMax card. 639 */ 640 /*ARGSUSED*/ 641 static void 642 grfmv_intr_cmax(vsc) 643 void *vsc; 644 { 645 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 646 u_int32_t dummy; 647 648 dummy = bus_space_read_4(sc->sc_tag, sc->sc_handle, 0xf501c); 649 dummy = bus_space_read_4(sc->sc_tag, sc->sc_handle, 0xf5018); 650 } 651 652 /* 653 * Routine to clear interrupts for the Lapis ProColorServer 8 PDS card 654 * (for the SE/30). 655 */ 656 /*ARGSUSED*/ 657 static void 658 grfmv_intr_lapis(vsc) 659 void *vsc; 660 { 661 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 662 663 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0xff7000, 0x08); 664 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0xff7000, 0x0C); 665 } 666 667 /* 668 * Routine to clear interrupts for the Formac Color Card II 669 */ 670 /*ARGSUSED*/ 671 static void 672 grfmv_intr_formac(vsc) 673 void *vsc; 674 { 675 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 676 u_int8_t dummy; 677 678 dummy = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0xde80db); 679 dummy = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0xde80d3); 680 } 681 682 /* 683 * Routine to clear interrupts for the Vimage by Interware Co., Ltd. 684 */ 685 /*ARGSUSED*/ 686 static void 687 grfmv_intr_vimage(vsc) 688 void *vsc; 689 { 690 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 691 692 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x800000, 0x67); 693 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x800000, 0xE7); 694 } 695 696 /* 697 * Routine to clear interrupts for the Grand Vimage by Interware Co., Ltd. 698 */ 699 /*ARGSUSED*/ 700 static void 701 grfmv_intr_gvimage(vsc) 702 void *vsc; 703 { 704 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 705 u_int8_t dummy; 706 707 dummy = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0xf00000); 708 } 709 710 /* 711 * Routine to clear interrupts for the Radius GS/C 712 */ 713 /*ARGSUSED*/ 714 static void 715 grfmv_intr_radius_gsc(vsc) 716 void *vsc; 717 { 718 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 719 u_int8_t dummy; 720 721 dummy = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0xfb802); 722 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0xfb802, 0xff); 723 } 724 725 /* 726 * Routine to clear interrupts for the Radius GS/C 727 */ 728 /*ARGSUSED*/ 729 static void 730 grfmv_intr_radius_gx(vsc) 731 void *vsc; 732 { 733 struct grfbus_softc *sc = (struct grfbus_softc *)vsc; 734 735 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x600000, 0x00); 736 bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x600000, 0x20); 737 } 738