Annotation of sys/arch/hp300/dev/gbox.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: gbox.c,v 1.15 2007/01/07 15:13:52 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2005, Miodrag Vallat
! 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: *
! 15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 18: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 19: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 20: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 21: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 23: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 24: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 25: * POSSIBILITY OF SUCH DAMAGE.
! 26: */
! 27: /*
! 28: * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
! 29: * Copyright (c) 1988 University of Utah.
! 30: * Copyright (c) 1990, 1993
! 31: * The Regents of the University of California. All rights reserved.
! 32: *
! 33: * This code is derived from software contributed to Berkeley by
! 34: * the Systems Programming Group of the University of Utah Computer
! 35: * Science Department.
! 36: *
! 37: * Redistribution and use in source and binary forms, with or without
! 38: * modification, are permitted provided that the following conditions
! 39: * are met:
! 40: * 1. Redistributions of source code must retain the above copyright
! 41: * notice, this list of conditions and the following disclaimer.
! 42: * 2. Redistributions in binary form must reproduce the above copyright
! 43: * notice, this list of conditions and the following disclaimer in the
! 44: * documentation and/or other materials provided with the distribution.
! 45: * 3. Neither the name of the University nor the names of its contributors
! 46: * may be used to endorse or promote products derived from this software
! 47: * without specific prior written permission.
! 48: *
! 49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 59: * SUCH DAMAGE.
! 60: *
! 61: * from: Utah $Hdr: grf_gb.c 1.18 93/08/13$
! 62: *
! 63: * @(#)grf_gb.c 8.4 (Berkeley) 1/12/94
! 64: */
! 65:
! 66: /*
! 67: * Graphics routines for the Gatorbox.
! 68: *
! 69: * Note: In the context of this system, "gator" and "gatorbox" both refer to
! 70: * HP 987x0 graphics systems. "Gator" is not used for high res mono.
! 71: * (as in 9837 Gator systems)
! 72: */
! 73:
! 74: #include <sys/param.h>
! 75: #include <sys/systm.h>
! 76: #include <sys/conf.h>
! 77: #include <sys/device.h>
! 78: #include <sys/proc.h>
! 79: #include <sys/ioctl.h>
! 80:
! 81: #include <machine/autoconf.h>
! 82: #include <machine/bus.h>
! 83: #include <machine/cpu.h>
! 84:
! 85: #include <hp300/dev/dioreg.h>
! 86: #include <hp300/dev/diovar.h>
! 87: #include <hp300/dev/diodevs.h>
! 88: #include <hp300/dev/intiovar.h>
! 89:
! 90: #include <dev/wscons/wsconsio.h>
! 91: #include <dev/wscons/wsdisplayvar.h>
! 92: #include <dev/rasops/rasops.h>
! 93:
! 94: #include <hp300/dev/diofbreg.h>
! 95: #include <hp300/dev/diofbvar.h>
! 96: #include <hp300/dev/gboxreg.h>
! 97:
! 98: struct gbox_softc {
! 99: struct device sc_dev;
! 100: struct diofb *sc_fb;
! 101: struct diofb sc_fb_store;
! 102: int sc_scode;
! 103: };
! 104:
! 105: int gbox_dio_match(struct device *, void *, void *);
! 106: void gbox_dio_attach(struct device *, struct device *, void *);
! 107: int gbox_intio_match(struct device *, void *, void *);
! 108: void gbox_intio_attach(struct device *, struct device *, void *);
! 109:
! 110: struct cfattach gbox_dio_ca = {
! 111: sizeof(struct gbox_softc), gbox_dio_match, gbox_dio_attach
! 112: };
! 113:
! 114: struct cfattach gbox_intio_ca = {
! 115: sizeof(struct gbox_softc), gbox_intio_match, gbox_intio_attach
! 116: };
! 117:
! 118: struct cfdriver gbox_cd = {
! 119: NULL, "gbox", DV_DULL
! 120: };
! 121:
! 122: int gbox_reset(struct diofb *, int, struct diofbreg *);
! 123: void gbox_restore(struct diofb *);
! 124: int gbox_setcmap(struct diofb *, struct wsdisplay_cmap *);
! 125: void gbox_setcolor(struct diofb *, u_int);
! 126: int gbox_windowmove(struct diofb *, u_int16_t, u_int16_t, u_int16_t,
! 127: u_int16_t, u_int16_t, u_int16_t, int16_t, int16_t);
! 128:
! 129: int gbox_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 130: void gbox_burner(void *, u_int, u_int);
! 131:
! 132: struct wsdisplay_accessops gbox_accessops = {
! 133: gbox_ioctl,
! 134: diofb_mmap,
! 135: diofb_alloc_screen,
! 136: diofb_free_screen,
! 137: diofb_show_screen,
! 138: NULL, /* load_font */
! 139: NULL, /* scrollback */
! 140: NULL, /* getchar */
! 141: gbox_burner
! 142: };
! 143:
! 144: /*
! 145: * Attachment glue
! 146: */
! 147: int
! 148: gbox_intio_match(struct device *parent, void *match, void *aux)
! 149: {
! 150: struct intio_attach_args *ia = aux;
! 151: struct diofbreg *fbr;
! 152:
! 153: fbr = (struct diofbreg *)IIOV(GRFIADDR);
! 154:
! 155: if (badaddr((caddr_t)fbr))
! 156: return (0);
! 157:
! 158: if (fbr->id == GRFHWID && fbr->fbid == GID_GATORBOX) {
! 159: ia->ia_addr = (caddr_t)GRFIADDR;
! 160: return (1);
! 161: }
! 162:
! 163: return (0);
! 164: }
! 165:
! 166: void
! 167: gbox_intio_attach(struct device *parent, struct device *self, void *aux)
! 168: {
! 169: struct gbox_softc *sc = (struct gbox_softc *)self;
! 170: struct diofbreg *fbr;
! 171:
! 172: fbr = (struct diofbreg *)IIOV(GRFIADDR);
! 173: sc->sc_scode = CONSCODE_INTERNAL;
! 174:
! 175: if (sc->sc_scode == conscode) {
! 176: sc->sc_fb = &diofb_cn;
! 177: } else {
! 178: sc->sc_fb = &sc->sc_fb_store;
! 179: gbox_reset(sc->sc_fb, sc->sc_scode, fbr);
! 180: }
! 181:
! 182: diofb_end_attach(sc, &gbox_accessops, sc->sc_fb,
! 183: sc->sc_scode == conscode, NULL);
! 184: }
! 185:
! 186: int
! 187: gbox_dio_match(struct device *parent, void *match, void *aux)
! 188: {
! 189: struct dio_attach_args *da = aux;
! 190:
! 191: /* We can not appear in DIO-II space */
! 192: if (DIO_ISDIOII(da->da_scode))
! 193: return (0);
! 194:
! 195: if (da->da_id == DIO_DEVICE_ID_FRAMEBUFFER &&
! 196: da->da_secid == DIO_DEVICE_SECID_GATORBOX)
! 197: return (1);
! 198:
! 199: return (0);
! 200: }
! 201:
! 202: void
! 203: gbox_dio_attach(struct device *parent, struct device *self, void *aux)
! 204: {
! 205: struct gbox_softc *sc = (struct gbox_softc *)self;
! 206: struct dio_attach_args *da = aux;
! 207: struct diofbreg * fbr;
! 208:
! 209: sc->sc_scode = da->da_scode;
! 210: if (sc->sc_scode == conscode) {
! 211: fbr = (struct diofbreg *)conaddr; /* already mapped */
! 212: sc->sc_fb = &diofb_cn;
! 213: } else {
! 214: sc->sc_fb = &sc->sc_fb_store;
! 215: fbr = (struct diofbreg *)
! 216: iomap(dio_scodetopa(sc->sc_scode), da->da_size);
! 217: if (fbr == NULL ||
! 218: gbox_reset(sc->sc_fb, sc->sc_scode, fbr) != 0) {
! 219: printf(": can't map framebuffer\n");
! 220: return;
! 221: }
! 222: }
! 223:
! 224: diofb_end_attach(sc, &gbox_accessops, sc->sc_fb,
! 225: sc->sc_scode == conscode, NULL);
! 226: }
! 227:
! 228: /*
! 229: * Initialize hardware and display routines.
! 230: */
! 231:
! 232: const u_int8_t crtc_init_data[] = {
! 233: 0x29, 0x20, 0x23, 0x04, 0x30, 0x0b, 0x30,
! 234: 0x30, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00
! 235: };
! 236:
! 237: int
! 238: gbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr)
! 239: {
! 240: int rc;
! 241: u_int i;
! 242:
! 243: /* XXX don't trust hardware, force defaults */
! 244: fb->fbwidth = 1024;
! 245: fb->fbheight = 1024;
! 246: fb->dwidth = 1024;
! 247: fb->dheight = 768;
! 248: if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0)
! 249: return (rc);
! 250:
! 251: fb->bmv = gbox_windowmove;
! 252: gbox_restore(fb);
! 253:
! 254: /*
! 255: * Find out how many colors are available by determining
! 256: * which planes are installed. That is, write all ones to
! 257: * a frame buffer location, see how many ones are read back.
! 258: */
! 259: if (1 /* fb->planes == 0 */) {
! 260: volatile u_int8_t *fbp;
! 261: u_int8_t save;
! 262:
! 263: fbp = (u_int8_t *)fb->fbkva;
! 264: save = *fbp;
! 265: *fbp = 0xff;
! 266: fb->planemask = *fbp;
! 267: *fbp = save;
! 268:
! 269: for (fb->planes = 1; fb->planemask >= (1 << fb->planes);
! 270: fb->planes++);
! 271: if (fb->planes > 8)
! 272: fb->planes = 8;
! 273: fb->planemask = (1 << fb->planes) - 1;
! 274: }
! 275:
! 276: diofb_fbsetup(fb);
! 277: for (i = 0; i <= fb->planemask; i++)
! 278: gbox_setcolor(fb, i);
! 279:
! 280: return (0);
! 281: }
! 282:
! 283: void
! 284: gbox_restore(struct diofb *fb)
! 285: {
! 286: volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
! 287: u_int i;
! 288:
! 289: /*
! 290: * The minimal info here is from the Gatorbox X driver.
! 291: */
! 292: gb->write_protect = 0x0;
! 293: gb->regs.interrupt = 0x4;
! 294: gb->rep_rule = RR_COPY;
! 295: gb->blink1 = 0xff;
! 296: gb->blink2 = 0xff;
! 297:
! 298: /*
! 299: * Program the 6845.
! 300: */
! 301: for (i = 0; i < sizeof(crtc_init_data); i++) {
! 302: gb->crtc_address = i;
! 303: gb->crtc_data = crtc_init_data[i];
! 304: }
! 305:
! 306: tile_mover_waitbusy(gb);
! 307:
! 308: /* Enable display */
! 309: gb->regs.sec_interrupt = 0x01;
! 310: }
! 311:
! 312: int
! 313: gbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
! 314: {
! 315: struct diofb *fb = v;
! 316: struct wsdisplay_fbinfo *wdf;
! 317: u_int i;
! 318:
! 319: switch (cmd) {
! 320: case WSDISPLAYIO_GTYPE:
! 321: *(u_int *)data = WSDISPLAY_TYPE_GBOX;
! 322: break;
! 323: case WSDISPLAYIO_SMODE:
! 324: fb->mapmode = *(u_int *)data;
! 325: if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) {
! 326: gbox_restore(fb);
! 327: for (i = 0; i <= fb->planemask; i++)
! 328: gbox_setcolor(fb, i);
! 329: }
! 330: break;
! 331: case WSDISPLAYIO_GINFO:
! 332: wdf = (void *)data;
! 333: wdf->width = fb->ri.ri_width;
! 334: wdf->height = fb->ri.ri_height;
! 335: wdf->depth = fb->ri.ri_depth;
! 336: wdf->cmsize = 1 << fb->planes;
! 337: break;
! 338: case WSDISPLAYIO_LINEBYTES:
! 339: *(u_int *)data = fb->ri.ri_stride;
! 340: break;
! 341: case WSDISPLAYIO_GETCMAP:
! 342: return (diofb_getcmap(fb, (struct wsdisplay_cmap *)data));
! 343: case WSDISPLAYIO_PUTCMAP:
! 344: return (gbox_setcmap(fb, (struct wsdisplay_cmap *)data));
! 345: case WSDISPLAYIO_GVIDEO:
! 346: case WSDISPLAYIO_SVIDEO:
! 347: break;
! 348: default:
! 349: return (-1);
! 350: }
! 351:
! 352: return (0);
! 353: }
! 354:
! 355: void
! 356: gbox_burner(void *v, u_int on, u_int flags)
! 357: {
! 358: struct diofb *fb = v;
! 359: volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
! 360:
! 361: if (on)
! 362: gb->regs.sec_interrupt = 0x01;
! 363: else
! 364: gb->regs.sec_interrupt = 0x00;
! 365: }
! 366:
! 367: void
! 368: gbox_setcolor(struct diofb *fb, u_int index)
! 369: {
! 370: volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
! 371:
! 372: gb->creg_select = index;
! 373: gb->cmap_red = fb->cmap.r[index];
! 374: gb->cmap_grn = fb->cmap.g[index];
! 375: gb->cmap_blu = fb->cmap.b[index];
! 376: gb->cmap_write = !!index;
! 377: gbcm_waitbusy(gb);
! 378: }
! 379:
! 380: int
! 381: gbox_setcmap(struct diofb *fb, struct wsdisplay_cmap *cm)
! 382: {
! 383: u_int8_t r[256], g[256], b[256];
! 384: u_int index = cm->index, count = cm->count;
! 385: u_int colcount = 1 << fb->planes;
! 386: int error;
! 387:
! 388: if (index >= colcount || count > colcount - index)
! 389: return (EINVAL);
! 390:
! 391: if ((error = copyin(cm->red, r, count)) != 0)
! 392: return (error);
! 393: if ((error = copyin(cm->green, g, count)) != 0)
! 394: return (error);
! 395: if ((error = copyin(cm->blue, b, count)) != 0)
! 396: return (error);
! 397:
! 398: bcopy(r, fb->cmap.r + index, count);
! 399: bcopy(g, fb->cmap.g + index, count);
! 400: bcopy(b, fb->cmap.b + index, count);
! 401:
! 402: while (count-- != 0)
! 403: gbox_setcolor(fb, index++);
! 404:
! 405: return (0);
! 406: }
! 407:
! 408: int
! 409: gbox_windowmove(struct diofb *fb, u_int16_t sx, u_int16_t sy,
! 410: u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop,
! 411: int16_t planemask)
! 412: {
! 413: volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
! 414: int src, dest;
! 415:
! 416: if (planemask != 0xff)
! 417: return (EINVAL);
! 418:
! 419: src = (sy * 1024) + sx; /* upper left corner in pixels */
! 420: dest = (dy * 1024) + dx;
! 421:
! 422: tile_mover_waitbusy(gb);
! 423:
! 424: gb->width = -(cx / 4);
! 425: gb->height = -(cy / 4);
! 426: if (src < dest)
! 427: gb->rep_rule = MOVE_DOWN_RIGHT | rop;
! 428: else {
! 429: gb->rep_rule = MOVE_UP_LEFT | rop;
! 430: /*
! 431: * Adjust to top of lower right tile of the block.
! 432: */
! 433: src = src + ((cy - 4) * 1024) + (cx - 4);
! 434: dest= dest + ((cy - 4) * 1024) + (cx - 4);
! 435: }
! 436: *(volatile u_int8_t *)(fb->fbkva + dest) =
! 437: *(volatile u_int8_t *)(fb->fbkva + src);
! 438:
! 439: tile_mover_waitbusy(gb);
! 440:
! 441: return (0);
! 442: }
! 443:
! 444: /*
! 445: * Gatorbox console support
! 446: */
! 447:
! 448: void
! 449: gboxcninit()
! 450: {
! 451: gbox_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr);
! 452: diofb_cnattach(&diofb_cn);
! 453: }
CVSweb