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