Annotation of sys/arch/hp300/dev/topcat.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: topcat.c,v 1.15 2006/08/11 18:33:13 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2005, Miodrag Vallat.
! 5: * 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: *
! 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: /*
! 30: * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
! 31: * Copyright (c) 1988 University of Utah.
! 32: * Copyright (c) 1990, 1993
! 33: * The Regents of the University of California. All rights reserved.
! 34: *
! 35: * This code is derived from software contributed to Berkeley by
! 36: * the Systems Programming Group of the University of Utah Computer
! 37: * Science Department.
! 38: *
! 39: * Redistribution and use in source and binary forms, with or without
! 40: * modification, are permitted provided that the following conditions
! 41: * are met:
! 42: * 1. Redistributions of source code must retain the above copyright
! 43: * notice, this list of conditions and the following disclaimer.
! 44: * 2. Redistributions in binary form must reproduce the above copyright
! 45: * notice, this list of conditions and the following disclaimer in the
! 46: * documentation and/or other materials provided with the distribution.
! 47: * 3. Neither the name of the University nor the names of its contributors
! 48: * may be used to endorse or promote products derived from this software
! 49: * without specific prior written permission.
! 50: *
! 51: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 52: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 53: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 54: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 55: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 56: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 57: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 58: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 59: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 60: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 61: * SUCH DAMAGE.
! 62: *
! 63: * from: Utah $Hdr: grf_tc.c 1.20 93/08/13$
! 64: *
! 65: * @(#)grf_tc.c 8.4 (Berkeley) 1/12/94
! 66: */
! 67:
! 68: /*
! 69: * Graphics routines for TOPCAT, CATSEYE and KATHMANDU frame buffers
! 70: */
! 71:
! 72: #include <sys/param.h>
! 73: #include <sys/systm.h>
! 74: #include <sys/conf.h>
! 75: #include <sys/device.h>
! 76: #include <sys/proc.h>
! 77: #include <sys/ioctl.h>
! 78:
! 79: #include <machine/autoconf.h>
! 80: #include <machine/bus.h>
! 81: #include <machine/cpu.h>
! 82:
! 83: #include <hp300/dev/dioreg.h>
! 84: #include <hp300/dev/diovar.h>
! 85: #include <hp300/dev/diodevs.h>
! 86: #include <hp300/dev/intiovar.h>
! 87:
! 88: #include <dev/wscons/wsconsio.h>
! 89: #include <dev/wscons/wsdisplayvar.h>
! 90: #include <dev/rasops/rasops.h>
! 91:
! 92: #include <hp300/dev/diofbreg.h>
! 93: #include <hp300/dev/diofbvar.h>
! 94: #include <hp300/dev/topcatreg.h>
! 95:
! 96: struct topcat_softc {
! 97: struct device sc_dev;
! 98: struct diofb *sc_fb;
! 99: struct diofb sc_fb_store;
! 100: int sc_scode;
! 101: };
! 102:
! 103: int topcat_dio_match(struct device *, void *, void *);
! 104: void topcat_dio_attach(struct device *, struct device *, void *);
! 105: int topcat_intio_match(struct device *, void *, void *);
! 106: void topcat_intio_attach(struct device *, struct device *, void *);
! 107:
! 108: struct cfattach topcat_dio_ca = {
! 109: sizeof(struct topcat_softc), topcat_dio_match, topcat_dio_attach
! 110: };
! 111:
! 112: struct cfattach topcat_intio_ca = {
! 113: sizeof(struct topcat_softc), topcat_intio_match, topcat_intio_attach
! 114: };
! 115:
! 116: struct cfdriver topcat_cd = {
! 117: NULL, "topcat", DV_DULL
! 118: };
! 119:
! 120: void topcat_end_attach(struct topcat_softc *, u_int8_t);
! 121: int topcat_reset(struct diofb *, int, struct diofbreg *);
! 122: void topcat_restore(struct diofb *);
! 123: int topcat_setcmap(struct diofb *, struct wsdisplay_cmap *);
! 124: void topcat_setcolor(struct diofb *, u_int);
! 125: int topcat_windowmove(struct diofb *, u_int16_t, u_int16_t, u_int16_t,
! 126: u_int16_t, u_int16_t, u_int16_t, int16_t, int16_t);
! 127:
! 128: int topcat_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 129: void topcat_burner(void *, u_int, u_int);
! 130:
! 131: struct wsdisplay_accessops topcat_accessops = {
! 132: topcat_ioctl,
! 133: diofb_mmap,
! 134: diofb_alloc_screen,
! 135: diofb_free_screen,
! 136: diofb_show_screen,
! 137: NULL, /* load_font */
! 138: NULL, /* scrollback */
! 139: NULL, /* getchar */
! 140: topcat_burner
! 141: };
! 142:
! 143: /*
! 144: * Attachment glue
! 145: */
! 146:
! 147: int
! 148: topcat_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) {
! 159: switch (fbr->fbid) {
! 160: case GID_TOPCAT:
! 161: case GID_LRCATSEYE:
! 162: case GID_HRCCATSEYE:
! 163: case GID_HRMCATSEYE:
! 164: #if 0
! 165: case GID_XXXCATSEYE:
! 166: #endif
! 167: ia->ia_addr = (caddr_t)GRFIADDR;
! 168: return (1);
! 169: }
! 170: }
! 171:
! 172: return (0);
! 173: }
! 174:
! 175: void
! 176: topcat_intio_attach(struct device *parent, struct device *self, void *aux)
! 177: {
! 178: struct topcat_softc *sc = (struct topcat_softc *)self;
! 179: struct diofbreg *fbr;
! 180:
! 181: fbr = (struct diofbreg *)IIOV(GRFIADDR);
! 182: sc->sc_scode = CONSCODE_INTERNAL;
! 183:
! 184: if (sc->sc_scode == conscode) {
! 185: sc->sc_fb = &diofb_cn;
! 186: } else {
! 187: sc->sc_fb = &sc->sc_fb_store;
! 188: topcat_reset(sc->sc_fb, sc->sc_scode, fbr);
! 189: }
! 190:
! 191: topcat_end_attach(sc, fbr->fbid);
! 192: }
! 193:
! 194: int
! 195: topcat_dio_match(struct device *parent, void *match, void *aux)
! 196: {
! 197: struct dio_attach_args *da = aux;
! 198:
! 199: if (da->da_id == DIO_DEVICE_ID_FRAMEBUFFER) {
! 200: switch (da->da_secid) {
! 201: case DIO_DEVICE_SECID_TOPCAT:
! 202: case DIO_DEVICE_SECID_LRCATSEYE:
! 203: case DIO_DEVICE_SECID_HRCCATSEYE:
! 204: case DIO_DEVICE_SECID_HRMCATSEYE:
! 205: #if 0
! 206: case DIO_DEVICE_SECID_XXXCATSEYE:
! 207: #endif
! 208: return (1);
! 209: }
! 210: }
! 211:
! 212: return (0);
! 213: }
! 214:
! 215: void
! 216: topcat_dio_attach(struct device *parent, struct device *self, void *aux)
! 217: {
! 218: struct topcat_softc *sc = (struct topcat_softc *)self;
! 219: struct dio_attach_args *da = aux;
! 220: struct diofbreg *fbr;
! 221:
! 222: sc->sc_scode = da->da_scode;
! 223: if (sc->sc_scode == conscode) {
! 224: fbr = (struct diofbreg *)conaddr; /* already mapped */
! 225: sc->sc_fb = &diofb_cn;
! 226: } else {
! 227: sc->sc_fb = &sc->sc_fb_store;
! 228: fbr = (struct diofbreg *)
! 229: iomap(dio_scodetopa(sc->sc_scode), da->da_size);
! 230: if (fbr == NULL ||
! 231: topcat_reset(sc->sc_fb, sc->sc_scode, fbr) != 0) {
! 232: printf(": can't map framebuffer\n");
! 233: return;
! 234: }
! 235: }
! 236:
! 237: topcat_end_attach(sc, fbr->fbid);
! 238: }
! 239:
! 240: void
! 241: topcat_end_attach(struct topcat_softc *sc, u_int8_t id)
! 242: {
! 243: const char *fbname = "unknown";
! 244:
! 245: switch (id) {
! 246: case GID_TOPCAT:
! 247: switch (sc->sc_fb->planes) {
! 248: case 1:
! 249: fbname = "HP98544 topcat";
! 250: break;
! 251: case 4:
! 252: if (sc->sc_fb->dheight == 400)
! 253: fbname = "HP98543 topcat";
! 254: else
! 255: fbname = "HP98545 topcat";
! 256: break;
! 257: case 6:
! 258: fbname = "HP98547 topcat";
! 259: break;
! 260: }
! 261: break;
! 262: case GID_HRCCATSEYE:
! 263: fbname = "HP98550 catseye"; /* also A1416 kathmandu */
! 264: break;
! 265: case GID_LRCATSEYE:
! 266: fbname = "HP98549 catseye";
! 267: break;
! 268: case GID_HRMCATSEYE:
! 269: fbname = "HP98548 catseye";
! 270: break;
! 271: }
! 272:
! 273: diofb_end_attach(sc, &topcat_accessops, sc->sc_fb,
! 274: sc->sc_scode == conscode, fbname);
! 275: }
! 276:
! 277: /*
! 278: * Initialize hardware and display routines.
! 279: */
! 280: int
! 281: topcat_reset(struct diofb *fb, int scode, struct diofbreg *fbr)
! 282: {
! 283: volatile struct tcboxfb *tc = (struct tcboxfb *)fbr;
! 284: int rc;
! 285: u_int i;
! 286:
! 287: if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0)
! 288: return (rc);
! 289:
! 290: /*
! 291: * If we could not get a valid number of planes, determine it
! 292: * by writing to the first frame buffer display location,
! 293: * then reading it back.
! 294: */
! 295: if (fb->planes == 0) {
! 296: volatile u_int8_t *fbp;
! 297: u_int8_t save;
! 298:
! 299: fbp = (u_int8_t *)fb->fbkva;
! 300: tc->fben = ~0;
! 301: tc->wen = ~0;
! 302: tc->ren = ~0;
! 303: tc->prr = RR_COPY;
! 304: save = *fbp;
! 305: *fbp = 0xff;
! 306: fb->planemask = *fbp;
! 307: *fbp = save;
! 308:
! 309: for (fb->planes = 1; fb->planemask >= (1 << fb->planes);
! 310: fb->planes++);
! 311: if (fb->planes > 8)
! 312: fb->planes = 8;
! 313: fb->planemask = (1 << fb->planes) - 1;
! 314: }
! 315:
! 316: fb->bmv = topcat_windowmove;
! 317: topcat_restore(fb);
! 318: diofb_fbsetup(fb);
! 319: for (i = 0; i <= fb->planemask; i++)
! 320: topcat_setcolor(fb, i);
! 321:
! 322: return (0);
! 323: }
! 324:
! 325: void
! 326: topcat_restore(struct diofb *fb)
! 327: {
! 328: volatile struct tcboxfb *tc = (struct tcboxfb *)fb->regkva;
! 329:
! 330: /*
! 331: * Catseye looks a lot like a topcat, but not completely.
! 332: * So, we set some bits to make it work.
! 333: */
! 334: if (tc->regs.fbid != GID_TOPCAT) {
! 335: while ((tc->catseye_status & 1))
! 336: ;
! 337: tc->catseye_status = 0x0;
! 338: tc->vb_select = 0x0;
! 339: tc->tcntrl = 0x0;
! 340: tc->acntrl = 0x0;
! 341: tc->pncntrl = 0x0;
! 342: tc->rug_cmdstat = 0x90;
! 343: }
! 344:
! 345: /*
! 346: * Enable reading/writing of all the planes.
! 347: */
! 348: tc->fben = fb->planemask;
! 349: tc->wen = fb->planemask;
! 350: tc->ren = fb->planemask;
! 351: tc->prr = RR_COPY;
! 352:
! 353: /* Enable display */
! 354: tc->nblank = 0xff;
! 355: }
! 356:
! 357: int
! 358: topcat_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
! 359: {
! 360: struct diofb *fb = v;
! 361: struct wsdisplay_fbinfo *wdf;
! 362: u_int i;
! 363:
! 364: switch (cmd) {
! 365: case WSDISPLAYIO_GTYPE:
! 366: *(u_int *)data = WSDISPLAY_TYPE_TOPCAT;
! 367: break;
! 368: case WSDISPLAYIO_SMODE:
! 369: fb->mapmode = *(u_int *)data;
! 370: if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) {
! 371: topcat_restore(fb);
! 372: for (i = 0; i <= fb->planemask; i++)
! 373: topcat_setcolor(fb, i);
! 374: }
! 375: break;
! 376: case WSDISPLAYIO_GINFO:
! 377: wdf = (void *)data;
! 378: wdf->width = fb->ri.ri_width;
! 379: wdf->height = fb->ri.ri_height;
! 380: wdf->depth = fb->ri.ri_depth;
! 381: wdf->cmsize = 1 << fb->planes;
! 382: break;
! 383: case WSDISPLAYIO_LINEBYTES:
! 384: *(u_int *)data = fb->ri.ri_stride;
! 385: break;
! 386: case WSDISPLAYIO_GETCMAP:
! 387: return (diofb_getcmap(fb, (struct wsdisplay_cmap *)data));
! 388: case WSDISPLAYIO_PUTCMAP:
! 389: return (topcat_setcmap(fb, (struct wsdisplay_cmap *)data));
! 390: case WSDISPLAYIO_GVIDEO:
! 391: case WSDISPLAYIO_SVIDEO:
! 392: break;
! 393: default:
! 394: return (-1);
! 395: }
! 396:
! 397: return (0);
! 398: }
! 399:
! 400: void
! 401: topcat_burner(void *v, u_int on, u_int flags)
! 402: {
! 403: struct diofb *fb = v;
! 404: volatile struct tcboxfb *tc = (struct tcboxfb *)fb->regkva;
! 405:
! 406: if (on) {
! 407: tc->nblank = 0xff;
! 408: } else {
! 409: tc->nblank = 0;
! 410: }
! 411: }
! 412:
! 413: void
! 414: topcat_setcolor(struct diofb *fb, u_int index)
! 415: {
! 416: volatile struct tcboxfb *tc = (struct tcboxfb *)fb->regkva;
! 417:
! 418: if (tc->regs.fbid != GID_TOPCAT) {
! 419: tccm_waitbusy(tc);
! 420: tc->plane_mask = 0xff;
! 421: tc->cindex = ~index;
! 422: tc->rdata = fb->cmap.r[index];
! 423: tc->gdata = fb->cmap.g[index];
! 424: tc->bdata = fb->cmap.b[index];
! 425: tc->strobe = 0xff;
! 426:
! 427: tccm_waitbusy(tc);
! 428: tc->cindex = 0;
! 429: } else {
! 430: tccm_waitbusy(tc);
! 431: tc->plane_mask = 0xff;
! 432: tc->rdata = fb->cmap.r[index];
! 433: tc->gdata = fb->cmap.g[index];
! 434: tc->bdata = fb->cmap.b[index];
! 435: tc->cindex = ~index;
! 436: tc->strobe = 0xff;
! 437:
! 438: tccm_waitbusy(tc);
! 439: tc->rdata = 0;
! 440: tc->gdata = 0;
! 441: tc->bdata = 0;
! 442: tc->cindex = 0;
! 443: }
! 444: }
! 445:
! 446: int
! 447: topcat_setcmap(struct diofb *fb, struct wsdisplay_cmap *cm)
! 448: {
! 449: u_int8_t r[256], g[256], b[256];
! 450: u_int index = cm->index, count = cm->count;
! 451: u_int colcount = 1 << fb->planes;
! 452: int error;
! 453:
! 454: if (index >= colcount || count > colcount - index)
! 455: return (EINVAL);
! 456:
! 457: if ((error = copyin(cm->red, r, count)) != 0)
! 458: return (error);
! 459: if ((error = copyin(cm->green, g, count)) != 0)
! 460: return (error);
! 461: if ((error = copyin(cm->blue, b, count)) != 0)
! 462: return (error);
! 463:
! 464: bcopy(r, fb->cmap.r + index, count);
! 465: bcopy(g, fb->cmap.g + index, count);
! 466: bcopy(b, fb->cmap.b + index, count);
! 467:
! 468: while (count-- != 0)
! 469: topcat_setcolor(fb, index++);
! 470:
! 471: return (0);
! 472: }
! 473:
! 474: /*
! 475: * Accelerated routines
! 476: */
! 477:
! 478: int
! 479: topcat_windowmove(struct diofb *fb, u_int16_t sx, u_int16_t sy,
! 480: u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop,
! 481: int16_t planemask)
! 482: {
! 483: volatile struct tcboxfb *tc = (struct tcboxfb *)fb->regkva;
! 484:
! 485: tc_waitbusy(tc, fb->planemask);
! 486:
! 487: tc->wen = planemask;
! 488: tc->wmrr = rop;
! 489: if (planemask != 0xff) {
! 490: tc->wen = planemask ^ 0xff;
! 491: tc->wmrr = rop ^ 0x0f;
! 492: tc->wen = fb->planemask;
! 493: }
! 494: tc->source_y = sy;
! 495: tc->source_x = sx;
! 496: tc->dest_y = dy;
! 497: tc->dest_x = dx;
! 498: tc->wheight = cy;
! 499: tc->wwidth = cx;
! 500: tc->wmove = fb->planemask;
! 501:
! 502: tc_waitbusy(tc, fb->planemask);
! 503:
! 504: return (0);
! 505: }
! 506:
! 507: /*
! 508: * Topcat/catseye console support
! 509: */
! 510:
! 511: void
! 512: topcatcninit()
! 513: {
! 514: topcat_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr);
! 515: diofb_cnattach(&diofb_cn);
! 516: }
CVSweb