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