Annotation of sys/arch/sparc/dev/cgfourteen.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: cgfourteen.c,v 1.35 2007/03/13 19:40:48 miod Exp $ */
! 2: /* $NetBSD: cgfourteen.c,v 1.7 1997/05/24 20:16:08 pk Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2002, 2003, 2005 Miodrag Vallat.
! 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: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 19: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 22: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 25: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 26: * POSSIBILITY OF SUCH DAMAGE.
! 27: *
! 28: *
! 29: * Copyright (c) 1996
! 30: * The President and Fellows of Harvard College. All rights reserved.
! 31: * Copyright (c) 1992, 1993
! 32: * The Regents of the University of California. All rights reserved.
! 33: *
! 34: * This software was developed by the Computer Systems Engineering group
! 35: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
! 36: * contributed to Berkeley.
! 37: *
! 38: * All advertising materials mentioning features or use of this software
! 39: * must display the following acknowledgement:
! 40: * This product includes software developed by Harvard University.
! 41: * This product includes software developed by the University of
! 42: * California, Lawrence Berkeley Laboratory.
! 43: *
! 44: * Redistribution and use in source and binary forms, with or without
! 45: * modification, are permitted provided that the following conditions
! 46: * are met:
! 47: * 1. Redistributions of source code must retain the above copyright
! 48: * notice, this list of conditions and the following disclaimer.
! 49: * 2. Redistributions in binary form must reproduce the above copyright
! 50: * notice, this list of conditions and the following disclaimer in the
! 51: * documentation and/or other materials provided with the distribution.
! 52: * 3. All advertising materials mentioning features or use of this software
! 53: * must display the following acknowledgement:
! 54: * This product includes software developed by the University of
! 55: * California, Berkeley and its contributors.
! 56: * This product includes software developed by Harvard University and
! 57: * its contributors.
! 58: * 4. Neither the name of the University nor the names of its contributors
! 59: * may be used to endorse or promote products derived from this software
! 60: * without specific prior written permission.
! 61: *
! 62: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 63: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 64: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 65: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 66: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 67: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 68: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 69: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 70: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 71: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 72: * SUCH DAMAGE.
! 73: *
! 74: * Based on:
! 75: * NetBSD: cgthree.c,v 1.28 1996/05/31 09:59:22 pk Exp
! 76: * NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp
! 77: */
! 78:
! 79: /*
! 80: * Driver for Campus-II on-board mbus-based video (cgfourteen).
! 81: *
! 82: * XXX should bring hardware cursor code back
! 83: */
! 84:
! 85: #include <sys/param.h>
! 86: #include <sys/systm.h>
! 87: #include <sys/buf.h>
! 88: #include <sys/device.h>
! 89: #include <sys/ioctl.h>
! 90: #include <sys/malloc.h>
! 91: #include <sys/mman.h>
! 92: #include <sys/tty.h>
! 93: #include <sys/conf.h>
! 94:
! 95: #include <uvm/uvm_extern.h>
! 96:
! 97: #include <machine/autoconf.h>
! 98: #include <machine/pmap.h>
! 99: #include <machine/cpu.h>
! 100: #include <machine/conf.h>
! 101:
! 102: #include <dev/wscons/wsconsio.h>
! 103: #include <dev/wscons/wsdisplayvar.h>
! 104: #include <dev/rasops/rasops.h>
! 105: #include <machine/fbvar.h>
! 106:
! 107: #include <sparc/dev/cgfourteenreg.h>
! 108:
! 109: #include <dev/cons.h> /* for prom console hook */
! 110:
! 111: /*
! 112: * Per-display variables/state
! 113: */
! 114:
! 115: union cgfourteen_cmap {
! 116: u_char cm_map[256][4]; /* 256 R/G/B/A entries (B is high)*/
! 117: u_int32_t cm_chip[256]; /* the way the chip gets loaded */
! 118: };
! 119:
! 120: struct cgfourteen_softc {
! 121: struct sunfb sc_sunfb; /* common base part */
! 122:
! 123: struct rom_reg sc_phys; /* phys address of frame buffer */
! 124: union cgfourteen_cmap sc_cmap; /* current colormap */
! 125: u_int sc_cmap_start, sc_cmap_count; /* deferred cmap range */
! 126:
! 127: /* registers mappings */
! 128: struct cg14ctl *sc_ctl;
! 129: struct cg14curs *sc_hwc;
! 130: struct cg14dac *sc_dac;
! 131: struct cg14xlut *sc_xlut;
! 132: struct cg14clut *sc_clut1;
! 133: struct cg14clut *sc_clut2;
! 134: struct cg14clut *sc_clut3;
! 135: u_int32_t *sc_autoincr;
! 136:
! 137: int sc_rev; /* VSIMM revision */
! 138: int sc_32; /* can do 32bit at this resolution */
! 139: size_t sc_vramsize; /* total video memory size */
! 140:
! 141: struct intrhand sc_ih;
! 142: };
! 143:
! 144: int cgfourteen_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 145: paddr_t cgfourteen_mmap(void *, off_t, int);
! 146: void cgfourteen_reset(struct cgfourteen_softc *, int);
! 147: void cgfourteen_burner(void *, u_int, u_int);
! 148:
! 149: int cgfourteen_getcmap(union cgfourteen_cmap *, struct wsdisplay_cmap *);
! 150: int cgfourteen_intr(void *);
! 151: void cgfourteen_loadcmap_deferred(struct cgfourteen_softc *, u_int, u_int);
! 152: void cgfourteen_loadcmap_immediate(struct cgfourteen_softc *, u_int, u_int);
! 153: void cgfourteen_prom(void *);
! 154: int cgfourteen_putcmap(union cgfourteen_cmap *, struct wsdisplay_cmap *);
! 155: void cgfourteen_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
! 156:
! 157: struct wsdisplay_accessops cgfourteen_accessops = {
! 158: cgfourteen_ioctl,
! 159: cgfourteen_mmap,
! 160: NULL, /* alloc_screen */
! 161: NULL, /* free_screen */
! 162: NULL, /* show_screen */
! 163: NULL, /* load_font */
! 164: NULL, /* scrollback */
! 165: NULL, /* getchar */
! 166: cgfourteen_burner,
! 167: NULL /* pollc */
! 168: };
! 169:
! 170: void cgfourteenattach(struct device *, struct device *, void *);
! 171: int cgfourteenmatch(struct device *, void *, void *);
! 172:
! 173: struct cfattach cgfourteen_ca = {
! 174: sizeof(struct cgfourteen_softc), cgfourteenmatch, cgfourteenattach
! 175: };
! 176:
! 177: struct cfdriver cgfourteen_cd = {
! 178: NULL, "cgfourteen", DV_DULL
! 179: };
! 180:
! 181: /*
! 182: * Match a cgfourteen.
! 183: */
! 184: int
! 185: cgfourteenmatch(struct device *parent, void *vcf, void *aux)
! 186: {
! 187: struct cfdata *cf = vcf;
! 188: struct confargs *ca = aux;
! 189: struct romaux *ra = &ca->ca_ra;
! 190:
! 191: if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
! 192: return (0);
! 193:
! 194: /*
! 195: * This driver should not be attached without an "addr" locator,
! 196: * as this is the only way to differentiate the main and secondary
! 197: * VSIMM.
! 198: */
! 199: if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != (int)ra->ra_paddr)
! 200: return (0);
! 201:
! 202: /*
! 203: * The cgfourteen is a local-bus video adaptor, accessed directly
! 204: * via the processor, and not through device space or an external
! 205: * bus. Thus we look _only_ at the obio bus.
! 206: * Additionally, these things exist only on the Sun4m.
! 207: */
! 208: if (CPU_ISSUN4M && ca->ca_bustype == BUS_OBIO)
! 209: return (1);
! 210:
! 211: return (0);
! 212: }
! 213:
! 214: /*
! 215: * Attach a display.
! 216: */
! 217: void
! 218: cgfourteenattach(struct device *parent, struct device *self, void *args)
! 219: {
! 220: struct cgfourteen_softc *sc = (struct cgfourteen_softc *)self;
! 221: struct confargs *ca = args;
! 222: int node, pri, i;
! 223: u_int32_t *lut;
! 224: int isconsole;
! 225: char *nam;
! 226:
! 227: pri = ca->ca_ra.ra_intr[0].int_pri;
! 228: printf(" pri %d: ", pri);
! 229:
! 230: /*
! 231: * Sanity checks
! 232: */
! 233: if (ca->ca_ra.ra_len < 0x10000) {
! 234: printf("expected %x bytes of control registers, got %x\n",
! 235: 0x10000, ca->ca_ra.ra_len);
! 236: return;
! 237: }
! 238: if (ca->ca_ra.ra_nreg < CG14_NREG) {
! 239: printf("expected %d registers, got %d\n",
! 240: CG14_NREG, ca->ca_ra.ra_nreg);
! 241: return;
! 242: }
! 243: if (ca->ca_ra.ra_nintr != 1) {
! 244: printf("expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
! 245: return;
! 246: }
! 247:
! 248: node = ca->ca_ra.ra_node;
! 249: nam = getpropstring(node, "model");
! 250: if (*nam != '\0')
! 251: printf("%s, ", nam);
! 252:
! 253: isconsole = node == fbnode;
! 254:
! 255: /*
! 256: * Map in the 8 useful pages of registers
! 257: */
! 258: sc->sc_ctl = (struct cg14ctl *) mapiodev(
! 259: &ca->ca_ra.ra_reg[CG14_REG_CONTROL], 0, ca->ca_ra.ra_len);
! 260:
! 261: sc->sc_hwc = (struct cg14curs *) ((u_int)sc->sc_ctl +
! 262: CG14_OFFSET_CURS);
! 263: sc->sc_dac = (struct cg14dac *) ((u_int)sc->sc_ctl +
! 264: CG14_OFFSET_DAC);
! 265: sc->sc_xlut = (struct cg14xlut *) ((u_int)sc->sc_ctl +
! 266: CG14_OFFSET_XLUT);
! 267: sc->sc_clut1 = (struct cg14clut *) ((u_int)sc->sc_ctl +
! 268: CG14_OFFSET_CLUT1);
! 269: sc->sc_clut2 = (struct cg14clut *) ((u_int)sc->sc_ctl +
! 270: CG14_OFFSET_CLUT2);
! 271: sc->sc_clut3 = (struct cg14clut *) ((u_int)sc->sc_ctl +
! 272: CG14_OFFSET_CLUT3);
! 273: sc->sc_autoincr = (u_int32_t *) ((u_int)sc->sc_ctl +
! 274: CG14_OFFSET_AUTOINCR);
! 275:
! 276: sc->sc_rev =
! 277: (sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) >> CG14_RSR_REVSHIFT;
! 278:
! 279: printf("%dMB, rev %d.%d", ca->ca_ra.ra_reg[CG14_REG_VRAM].rr_len >> 20,
! 280: sc->sc_rev, sc->sc_ctl->ctl_rsr & CG14_RSR_IMPLMASK);
! 281:
! 282: sc->sc_phys = ca->ca_ra.ra_reg[CG14_REG_VRAM];
! 283:
! 284: fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
! 285:
! 286: /*
! 287: * The prom will report depth == 8, since this is the mode it will
! 288: * get initialized in.
! 289: * Check if we will be able to use 32 bit mode later (i.e. if it will
! 290: * fit in the video memory. Note that, if this is not the case, the
! 291: * VSIMM will usually not appear in the OBP device tree!
! 292: */
! 293: sc->sc_vramsize = ca->ca_ra.ra_reg[CG14_REG_VRAM].rr_len;
! 294: sc->sc_32 = sc->sc_sunfb.sf_fbsize * 4 <= sc->sc_vramsize;
! 295:
! 296: sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&ca->ca_ra.ra_reg[CG14_REG_VRAM],
! 297: 0, /* CHUNKY_XBGR */
! 298: sc->sc_vramsize);
! 299:
! 300: printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
! 301:
! 302: sc->sc_ih.ih_fun = cgfourteen_intr;
! 303: sc->sc_ih.ih_arg = sc;
! 304: intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname);
! 305:
! 306: /*
! 307: * Reset frame buffer controls
! 308: */
! 309: sc->sc_sunfb.sf_depth = 0; /* force action */
! 310: cgfourteen_reset(sc, 8);
! 311:
! 312: /*
! 313: * Grab the initial colormap
! 314: */
! 315: lut = (u_int32_t *)sc->sc_clut1->clut_lut;
! 316: for (i = 0; i < CG14_CLUT_SIZE; i++)
! 317: sc->sc_cmap.cm_chip[i] = lut[i];
! 318:
! 319: /*
! 320: * Enable the video.
! 321: */
! 322: cgfourteen_burner(sc, 1, 0);
! 323:
! 324: sc->sc_sunfb.sf_ro.ri_hw = sc;
! 325: fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
! 326: fbwscons_setcolormap(&sc->sc_sunfb, cgfourteen_setcolor);
! 327:
! 328: if (isconsole) {
! 329: fbwscons_console_init(&sc->sc_sunfb, -1);
! 330: shutdownhook_establish(cgfourteen_prom, sc);
! 331: }
! 332:
! 333: fbwscons_attach(&sc->sc_sunfb, &cgfourteen_accessops, isconsole);
! 334: }
! 335:
! 336: int
! 337: cgfourteen_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
! 338: {
! 339: struct cgfourteen_softc *sc = dev;
! 340: struct wsdisplay_cmap *cm;
! 341: struct wsdisplay_fbinfo *wdf;
! 342: int error;
! 343:
! 344: /*
! 345: * Note that, although the emulation (text) mode is running in a
! 346: * 8-bit plane, we advertize the frame buffer as 32-bit if it can
! 347: * support this mode.
! 348: */
! 349: switch (cmd) {
! 350: case WSDISPLAYIO_GTYPE:
! 351: *(u_int *)data = WSDISPLAY_TYPE_SUNCG14;
! 352: break;
! 353: case WSDISPLAYIO_GINFO:
! 354: wdf = (struct wsdisplay_fbinfo *)data;
! 355: wdf->height = sc->sc_sunfb.sf_height;
! 356: wdf->width = sc->sc_sunfb.sf_width;
! 357: wdf->depth = sc->sc_32 ? 32 : 8;
! 358: wdf->cmsize = sc->sc_32 ? 0 : 256;
! 359: break;
! 360: case WSDISPLAYIO_GETSUPPORTEDDEPTH:
! 361: if (sc->sc_32)
! 362: *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
! 363: else
! 364: return (-1);
! 365: break;
! 366: case WSDISPLAYIO_LINEBYTES:
! 367: if (sc->sc_32)
! 368: *(u_int *)data = sc->sc_sunfb.sf_linebytes * 4;
! 369: else
! 370: *(u_int *)data = sc->sc_sunfb.sf_linebytes;
! 371: break;
! 372:
! 373: case WSDISPLAYIO_GETCMAP:
! 374: if (sc->sc_32 == 0) {
! 375: cm = (struct wsdisplay_cmap *)data;
! 376: error = cgfourteen_getcmap(&sc->sc_cmap, cm);
! 377: if (error)
! 378: return (error);
! 379: }
! 380: break;
! 381: case WSDISPLAYIO_PUTCMAP:
! 382: if (sc->sc_32 == 0) {
! 383: cm = (struct wsdisplay_cmap *)data;
! 384: error = cgfourteen_putcmap(&sc->sc_cmap, cm);
! 385: if (error)
! 386: return (error);
! 387: cgfourteen_loadcmap_deferred(sc, cm->index, cm->count);
! 388: }
! 389: break;
! 390:
! 391: case WSDISPLAYIO_SMODE:
! 392: if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
! 393: /* Back from X11 to text mode */
! 394: cgfourteen_reset(sc, 8);
! 395: } else {
! 396: /* Starting X11, try to switch to 32 bit mode */
! 397: if (sc->sc_32)
! 398: cgfourteen_reset(sc, 32);
! 399: }
! 400: break;
! 401:
! 402: case WSDISPLAYIO_GVIDEO:
! 403: case WSDISPLAYIO_SVIDEO:
! 404: break;
! 405:
! 406: default:
! 407: return (-1); /* not supported yet */
! 408: }
! 409: return (0);
! 410: }
! 411:
! 412: /*
! 413: * Return the address that would map the given device at the given
! 414: * offset, allowing for the given protection, or return -1 for error.
! 415: */
! 416: paddr_t
! 417: cgfourteen_mmap(void *v, off_t offset, int prot)
! 418: {
! 419: struct cgfourteen_softc *sc = v;
! 420:
! 421: if (offset & PGOFSET || offset < 0)
! 422: return (-1);
! 423:
! 424: /* Allow mapping as a dumb framebuffer from offset 0 */
! 425: if (offset < sc->sc_sunfb.sf_fbsize * (sc->sc_32 ? 4 : 1)) {
! 426: return (REG2PHYS(&sc->sc_phys, offset) | PMAP_NC);
! 427: }
! 428:
! 429: return (-1);
! 430: }
! 431:
! 432: /* Initialize the framebuffer, storing away useful state for later reset */
! 433: void
! 434: cgfourteen_reset(struct cgfourteen_softc *sc, int depth)
! 435: {
! 436: u_int i;
! 437:
! 438: if (sc->sc_sunfb.sf_depth != depth) {
! 439: if (depth == 8) {
! 440: /*
! 441: * Enable the video and put it in 8 bit mode
! 442: */
! 443: if (sc->sc_rev == 0)
! 444: sc->sc_ctl->ctl_mctl = CG14_MCTL_R0_ENABLEHW |
! 445: CG14_MCTL_PIXMODE_8;
! 446: else
! 447: sc->sc_ctl->ctl_mctl = CG14_MCTL_R1_ENABLEHW |
! 448: CG14_MCTL_R1_ENABLEVID |
! 449: CG14_MCTL_PIXMODE_8;
! 450:
! 451: fbwscons_setcolormap(&sc->sc_sunfb,
! 452: cgfourteen_setcolor);
! 453: } else {
! 454: /*
! 455: * Clear the screen to black
! 456: */
! 457: bzero(sc->sc_sunfb.sf_ro.ri_bits,
! 458: sc->sc_sunfb.sf_fbsize);
! 459:
! 460: /*
! 461: * Enable the video, and put in 32 bit mode
! 462: */
! 463: if (sc->sc_rev == 0)
! 464: sc->sc_ctl->ctl_mctl = CG14_MCTL_R0_ENABLEHW |
! 465: CG14_MCTL_PIXMODE_32;
! 466: else
! 467: sc->sc_ctl->ctl_mctl = CG14_MCTL_R1_ENABLEHW |
! 468: CG14_MCTL_R1_ENABLEVID |
! 469: CG14_MCTL_PIXMODE_32;
! 470:
! 471: /*
! 472: * Zero the xlut to enable direct-color mode
! 473: */
! 474: sc->sc_xlut->xlut_lutinc[0] = 0;
! 475: for (i = CG14_CLUT_SIZE; i; i--)
! 476: *sc->sc_autoincr = 0;
! 477: }
! 478: }
! 479:
! 480: sc->sc_cmap_count = 0;
! 481: sc->sc_sunfb.sf_depth = depth;
! 482: }
! 483:
! 484: void
! 485: cgfourteen_prom(void *v)
! 486: {
! 487: struct cgfourteen_softc *sc = v;
! 488: extern struct consdev consdev_prom;
! 489:
! 490: if (sc->sc_sunfb.sf_depth != 8) {
! 491: /*
! 492: * Go back to 8-bit mode.
! 493: */
! 494: cgfourteen_reset(sc, 8);
! 495:
! 496: /*
! 497: * Go back to prom output for the last few messages, so they
! 498: * will be displayed correctly.
! 499: */
! 500: cn_tab = &consdev_prom;
! 501: }
! 502: }
! 503:
! 504: void
! 505: cgfourteen_burner(void *v, u_int on, u_int flags)
! 506: {
! 507: struct cgfourteen_softc *sc = v;
! 508: u_int bits;
! 509:
! 510: /*
! 511: * We can only use DPMS to power down the display if the chip revision
! 512: * is greater than 0.
! 513: */
! 514: if (sc->sc_rev == 0)
! 515: bits = CG14_MCTL_R0_ENABLEHW;
! 516: else
! 517: bits = CG14_MCTL_R1_ENABLEHW | CG14_MCTL_R1_ENABLEVID;
! 518:
! 519: if (on) {
! 520: sc->sc_ctl->ctl_mctl |= bits;
! 521: } else {
! 522: sc->sc_ctl->ctl_mctl &= ~bits;
! 523: }
! 524: }
! 525:
! 526: /* Read the software shadow colormap */
! 527: int
! 528: cgfourteen_getcmap(union cgfourteen_cmap *cm, struct wsdisplay_cmap *rcm)
! 529: {
! 530: u_int index = rcm->index, count = rcm->count, i;
! 531: int error;
! 532:
! 533: if (index >= CG14_CLUT_SIZE || count > CG14_CLUT_SIZE - index)
! 534: return (EINVAL);
! 535:
! 536: for (i = 0; i < count; i++) {
! 537: if ((error = copyout(&cm->cm_map[index + i][3],
! 538: &rcm->red[i], 1)) != 0)
! 539: return (error);
! 540: if ((error = copyout(&cm->cm_map[index + i][2],
! 541: &rcm->green[i], 1)) != 0)
! 542: return (error);
! 543: if ((error = copyout(&cm->cm_map[index + i][1],
! 544: &rcm->blue[i], 1)) != 0)
! 545: return (error);
! 546: }
! 547: return (0);
! 548: }
! 549:
! 550: /* Write the software shadow colormap */
! 551: int
! 552: cgfourteen_putcmap(union cgfourteen_cmap *cm, struct wsdisplay_cmap *rcm)
! 553: {
! 554: u_int index = rcm->index, count = rcm->count, i;
! 555: int error;
! 556:
! 557: if (index >= CG14_CLUT_SIZE || count > CG14_CLUT_SIZE - index)
! 558: return (EINVAL);
! 559:
! 560: for (i = 0; i < count; i++) {
! 561: if ((error = copyin(&rcm->red[i],
! 562: &cm->cm_map[index + i][3], 1)) != 0)
! 563: return (error);
! 564: if ((error = copyin(&rcm->green[i],
! 565: &cm->cm_map[index + i][2], 1)) != 0)
! 566: return (error);
! 567: if ((error = copyin(&rcm->blue[i],
! 568: &cm->cm_map[index + i][1], 1)) != 0)
! 569: return (error);
! 570: cm->cm_map[index +i][0] = 0; /* no alpha channel */
! 571: }
! 572: return (0);
! 573: }
! 574:
! 575: void
! 576: cgfourteen_loadcmap_deferred(struct cgfourteen_softc *sc, u_int start,
! 577: u_int ncolors)
! 578: {
! 579: u_int end;
! 580:
! 581: /* Grow the deferred colormap update range if necessary */
! 582: if (sc->sc_cmap_count == 0) {
! 583: sc->sc_cmap_start = start;
! 584: sc->sc_cmap_count = ncolors;
! 585: } else {
! 586: end = MAX(start + ncolors,
! 587: sc->sc_cmap_start + sc->sc_cmap_count);
! 588: sc->sc_cmap_start = min(sc->sc_cmap_start, start);
! 589: sc->sc_cmap_count = end - sc->sc_cmap_start;
! 590: }
! 591:
! 592: /* Enable interrupts */
! 593: sc->sc_ctl->ctl_mctl |= CG14_MCTL_ENABLEINTR;
! 594: }
! 595:
! 596: void
! 597: cgfourteen_loadcmap_immediate(struct cgfourteen_softc *sc, u_int start,
! 598: u_int ncolors)
! 599: {
! 600: u_int32_t *colp = &sc->sc_cmap.cm_chip[start];
! 601:
! 602: sc->sc_clut1->clut_lutinc[start] = 0;
! 603: while (ncolors-- != 0)
! 604: *sc->sc_autoincr = *colp++;
! 605: }
! 606:
! 607: void
! 608: cgfourteen_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
! 609: {
! 610: struct cgfourteen_softc *sc = v;
! 611:
! 612: sc->sc_cmap.cm_map[index][3] = r;
! 613: sc->sc_cmap.cm_map[index][2] = g;
! 614: sc->sc_cmap.cm_map[index][1] = b;
! 615: sc->sc_cmap.cm_map[index][0] = 0; /* no alpha channel */
! 616:
! 617: cgfourteen_loadcmap_immediate(sc, index, 1);
! 618: }
! 619:
! 620: int
! 621: cgfourteen_intr(void *v)
! 622: {
! 623: struct cgfourteen_softc *sc = v;
! 624: u_int msr;
! 625: int claim = 0;
! 626:
! 627: msr = sc->sc_ctl->ctl_msr;
! 628:
! 629: /* check that the interrupt is ours */
! 630: if (!ISSET(msr, CG14_MSR_PENDING) ||
! 631: !ISSET(sc->sc_ctl->ctl_mctl, CG14_MCTL_ENABLEINTR)) {
! 632: return (0);
! 633: }
! 634:
! 635: /* vertical retrace interrupt */
! 636: if (ISSET(msr, CG14_MSR_VRETRACE)) {
! 637: /* acknowledge by writing to the (read only) msr */
! 638: sc->sc_ctl->ctl_msr = 0;
! 639:
! 640: /* disable interrupts until next colormap change */
! 641: sc->sc_ctl->ctl_mctl &= ~CG14_MCTL_ENABLEINTR;
! 642:
! 643: cgfourteen_loadcmap_immediate(sc,
! 644: sc->sc_cmap_start, sc->sc_cmap_count);
! 645:
! 646: claim = 1;
! 647: }
! 648:
! 649: /* engine fault */
! 650: if (ISSET(msr, CG14_MSR_FAULT)) {
! 651: /* acknowledge by reading the fault status register */
! 652: claim = 1 | sc->sc_ctl->ctl_fsr;
! 653: }
! 654:
! 655: if (claim == 0) {
! 656: #ifdef DEBUG
! 657: printf("%s: unknown interrupt cause, msr=%x\n",
! 658: sc->sc_sunfb.sf_dev.dv_xname, msr);
! 659: #endif
! 660: claim = 1; /* claim anyway */
! 661: }
! 662:
! 663: return (claim & 1);
! 664: }
CVSweb