Annotation of sys/arch/alpha/tc/cfb.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: cfb.c,v 1.18 2006/11/29 12:13:51 miod Exp $ */
! 2: /* $NetBSD: cfb.c,v 1.7 1996/12/05 01:39:39 cgd Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1995, 1996 Carnegie-Mellon University.
! 6: * All rights reserved.
! 7: *
! 8: * Author: Chris G. Demetriou
! 9: *
! 10: * Permission to use, copy, modify and distribute this software and
! 11: * its documentation is hereby granted, provided that both the copyright
! 12: * notice and this permission notice appear in all copies of the
! 13: * software, derivative works or modified versions, and any portions
! 14: * thereof, and that both notices appear in supporting documentation.
! 15: *
! 16: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
! 17: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
! 18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
! 19: *
! 20: * Carnegie Mellon requests users of this software to return to
! 21: *
! 22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
! 23: * School of Computer Science
! 24: * Carnegie Mellon University
! 25: * Pittsburgh PA 15213-3890
! 26: *
! 27: * any improvements or extensions that they make and grant Carnegie the
! 28: * rights to redistribute these changes.
! 29: */
! 30:
! 31: #include <sys/param.h>
! 32: #include <sys/systm.h>
! 33: #include <sys/kernel.h>
! 34: #include <sys/device.h>
! 35: #include <sys/malloc.h>
! 36: #include <sys/buf.h>
! 37: #include <sys/conf.h>
! 38: #include <sys/ioctl.h>
! 39:
! 40: #include <uvm/uvm_extern.h>
! 41:
! 42: #include <machine/bus.h>
! 43: #include <machine/intr.h>
! 44:
! 45: #include <dev/tc/tcvar.h>
! 46: #include <machine/cfbreg.h>
! 47: #include <alpha/tc/cfbvar.h>
! 48:
! 49: #include <dev/rcons/raster.h>
! 50: #include <dev/wscons/wscons_raster.h>
! 51: #include <dev/wscons/wsdisplayvar.h>
! 52: #include <machine/fbio.h>
! 53:
! 54: #include <machine/autoconf.h>
! 55: #include <machine/pte.h>
! 56:
! 57: int cfbmatch(struct device *, void *, void *);
! 58: void cfbattach(struct device *, struct device *, void *);
! 59:
! 60: struct cfattach cfb_ca = {
! 61: sizeof(struct cfb_softc), cfbmatch, cfbattach,
! 62: };
! 63:
! 64: struct cfdriver cfb_cd = {
! 65: NULL, "cfb", DV_DULL,
! 66: };
! 67:
! 68: void cfb_getdevconfig(tc_addr_t dense_addr, struct cfb_devconfig *dc);
! 69: struct cfb_devconfig cfb_console_dc;
! 70: tc_addr_t cfb_consaddr;
! 71:
! 72: struct wsdisplay_emulops cfb_emulfuncs = {
! 73: rcons_cursor, /* could use hardware cursor; punt */
! 74: rcons_mapchar,
! 75: rcons_putchar,
! 76: rcons_copycols,
! 77: rcons_erasecols,
! 78: rcons_copyrows,
! 79: rcons_eraserows,
! 80: rcons_alloc_attr
! 81: };
! 82:
! 83: struct wsscreen_descr cfb_stdscreen = {
! 84: "std",
! 85: 0, 0, /* will be filled in -- XXX shouldn't, it's global */
! 86: &cfb_emulfuncs,
! 87: 0, 0
! 88: };
! 89:
! 90: const struct wsscreen_descr *_cfb_scrlist[] = {
! 91: &cfb_stdscreen,
! 92: /* XXX other formats, graphics screen? */
! 93: };
! 94:
! 95: struct wsscreen_list cfb_screenlist = {
! 96: sizeof(_cfb_scrlist) / sizeof(struct wsscreen_descr *), _cfb_scrlist
! 97: };
! 98:
! 99: int cfbioctl(void *, u_long, caddr_t, int, struct proc *);
! 100: paddr_t cfbmmap(void *, off_t, int);
! 101:
! 102: int cfbintr(void *);
! 103: static int cfb_alloc_screen(void *, const struct wsscreen_descr *,
! 104: void **, int *, int *, long *);
! 105: static void cfb_free_screen(void *, void *);
! 106: static int cfb_show_screen(void *, void *, int,
! 107: void (*) (void *, int, int), void *);
! 108:
! 109: struct wsdisplay_accessops cfb_accessops = {
! 110: cfbioctl,
! 111: cfbmmap,
! 112: cfb_alloc_screen,
! 113: cfb_free_screen,
! 114: cfb_show_screen,
! 115: };
! 116:
! 117: int
! 118: cfbmatch(parent, match, aux)
! 119: struct device *parent;
! 120: void *match;
! 121: void *aux;
! 122: {
! 123: struct tc_attach_args *ta = aux;
! 124:
! 125: if (strncmp("PMAG-BA ", ta->ta_modname, TC_ROM_LLEN) != 0)
! 126: return (0);
! 127:
! 128: return (10);
! 129: }
! 130:
! 131: void
! 132: cfb_getdevconfig(dense_addr, dc)
! 133: tc_addr_t dense_addr;
! 134: struct cfb_devconfig *dc;
! 135: {
! 136: struct raster *rap;
! 137: struct rcons *rcp;
! 138: char *ramdacregp;
! 139: int i;
! 140:
! 141: dc->dc_vaddr = dense_addr;
! 142: dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
! 143: dc->dc_size = CFB_SIZE;
! 144:
! 145: ramdacregp = (char *)dc->dc_vaddr + CFB_RAMDAC_OFFSET;
! 146:
! 147: dc->dc_wid = 1024;
! 148: dc->dc_ht = 864;
! 149: dc->dc_depth = 8; /* 8 plane */
! 150: dc->dc_rowbytes = dc->dc_wid * (dc->dc_depth / 8);
! 151:
! 152: dc->dc_videobase = dc->dc_vaddr + CFB_FB_OFFSET;
! 153:
! 154: /* Initialize the RAMDAC/colormap */
! 155: /* start XXX XXX XXX */
! 156: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_ADDRLOW)) = 0;
! 157: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_ADDRHIGH)) = 0;
! 158: tc_wmb();
! 159: for (i = 0; i < 256; i++) {
! 160: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_CMAPDATA)) =
! 161: i ? 0xff : 0;
! 162: tc_wmb();
! 163: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_CMAPDATA)) =
! 164: i ? 0xff : 0;
! 165: tc_wmb();
! 166: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_CMAPDATA)) =
! 167: i ? 0xff : 0;
! 168: tc_wmb();
! 169: }
! 170: /* end XXX XXX XXX */
! 171:
! 172: /* clear the screen */
! 173: for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
! 174: *(u_int32_t *)(dc->dc_videobase + i) = 0x00000000;
! 175:
! 176: rap = &dc->dc_raster;
! 177: rap->width = dc->dc_wid;
! 178: rap->height = dc->dc_ht;
! 179: rap->depth = 8;
! 180: rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t);
! 181: rap->pixels = (u_int32_t *)dc->dc_videobase;
! 182:
! 183: /* initialize the raster console blitter */
! 184: rcp = &dc->dc_rcons;
! 185: rcp->rc_sp = rap;
! 186: rcp->rc_crow = rcp->rc_ccol = -1;
! 187: rcp->rc_crowp = &rcp->rc_crow;
! 188: rcp->rc_ccolp = &rcp->rc_ccol;
! 189: rcons_init(rcp, 34, 80);
! 190:
! 191: cfb_stdscreen.nrows = dc->dc_rcons.rc_maxrow;
! 192: cfb_stdscreen.ncols = dc->dc_rcons.rc_maxcol;
! 193: }
! 194:
! 195: void
! 196: cfbattach(parent, self, aux)
! 197: struct device *parent, *self;
! 198: void *aux;
! 199: {
! 200: struct cfb_softc *sc = (struct cfb_softc *)self;
! 201: struct tc_attach_args *ta = aux;
! 202: struct wsemuldisplaydev_attach_args waa;
! 203: int console;
! 204:
! 205: console = (ta->ta_addr == cfb_consaddr);
! 206: if (console) {
! 207: sc->sc_dc = &cfb_console_dc;
! 208: sc->nscreens = 1;
! 209: } else {
! 210: sc->sc_dc = (struct cfb_devconfig *)
! 211: malloc(sizeof(struct cfb_devconfig), M_DEVBUF, M_WAITOK);
! 212: cfb_getdevconfig(ta->ta_addr, sc->sc_dc);
! 213: }
! 214: if (sc->sc_dc->dc_vaddr == NULL) {
! 215: printf(": couldn't map memory space; punt!\n");
! 216: return;
! 217: }
! 218: printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
! 219: sc->sc_dc->dc_depth);
! 220:
! 221: /* Establish an interrupt handler, and clear any pending interrupts */
! 222: tc_intr_establish(parent, ta->ta_cookie, TC_IPL_TTY, cfbintr, sc);
! 223: *(volatile u_int32_t *)(sc->sc_dc->dc_vaddr + CFB_IREQCTRL_OFFSET) = 0;
! 224:
! 225: /* initialize the raster */
! 226: waa.console = console;
! 227: waa.scrdata = &cfb_screenlist;
! 228: waa.accessops = &cfb_accessops;
! 229: waa.accesscookie = sc;
! 230: waa.defaultscreens = 0;
! 231:
! 232: config_found(self, &waa, wsemuldisplaydevprint);
! 233: }
! 234:
! 235: int
! 236: cfbioctl(v, cmd, data, flag, p)
! 237: void *v;
! 238: u_long cmd;
! 239: caddr_t data;
! 240: int flag;
! 241: struct proc *p;
! 242: {
! 243: struct cfb_softc *sc = v;
! 244: struct cfb_devconfig *dc = sc->sc_dc;
! 245:
! 246: switch (cmd) {
! 247: case FBIOGTYPE:
! 248: #define fbt ((struct fbtype *)data)
! 249: fbt->fb_type = FBTYPE_CFB;
! 250: fbt->fb_height = sc->sc_dc->dc_ht;
! 251: fbt->fb_width = sc->sc_dc->dc_wid;
! 252: fbt->fb_depth = sc->sc_dc->dc_depth;
! 253: fbt->fb_cmsize = 256; /* XXX ??? */
! 254: fbt->fb_size = sc->sc_dc->dc_size;
! 255: #undef fbt
! 256: return (0);
! 257:
! 258: #if 0
! 259: case FBIOPUTCMAP:
! 260: return (*tgar->tgar_set_cmap)(dc, (struct fbcmap *)data);
! 261:
! 262: case FBIOGETCMAP:
! 263: return (*tgar->tgar_get_cmap)(dc, (struct fbcmap *)data);
! 264: #endif
! 265:
! 266: case FBIOGATTR:
! 267: return (ENOTTY); /* XXX ? */
! 268:
! 269: #if 0
! 270: case FBIOSVIDEO:
! 271: if (*(int *)data == FBVIDEO_OFF)
! 272: cfb_blank(sc->sc_dc);
! 273: else
! 274: cfb_unblank(sc->sc_dc);
! 275: return (0);
! 276: #endif
! 277:
! 278: case FBIOGVIDEO:
! 279: *(int *)data = dc->dc_blanked ? FBVIDEO_OFF : FBVIDEO_ON;
! 280: return (0);
! 281:
! 282: #if 0
! 283: case FBIOSCURSOR:
! 284: return (*tgar->tgar_set_cursor)(dc, (struct fbcursor *)data);
! 285:
! 286: case FBIOGCURSOR:
! 287: return (*tgar->tgar_get_cursor)(dc, (struct fbcursor *)data);
! 288:
! 289: case FBIOSCURPOS:
! 290: return (*tgar->tgar_set_curpos)(dc, (struct fbcurpos *)data);
! 291:
! 292: case FBIOGCURPOS:
! 293: return (*tgar->tgar_get_curpos)(dc, (struct fbcurpos *)data);
! 294:
! 295: case FBIOGCURMAX:
! 296: return (*tgar->tgar_get_curmax)(dc, (struct fbcurpos *)data);
! 297: #endif
! 298: }
! 299: return (-1);
! 300: }
! 301:
! 302: paddr_t
! 303: cfbmmap(v, offset, prot)
! 304: void *v;
! 305: off_t offset;
! 306: int prot;
! 307: {
! 308: struct cfb_softc *sc = v;
! 309:
! 310: if (offset > CFB_SIZE)
! 311: return (-1);
! 312: return atop(sc->sc_dc->dc_paddr + offset);
! 313: }
! 314:
! 315: int
! 316: cfbintr(v)
! 317: void *v;
! 318: {
! 319: struct cfb_softc *sc = v;
! 320:
! 321: *(volatile u_int32_t *)(sc->sc_dc->dc_vaddr + CFB_IREQCTRL_OFFSET) = 0;
! 322:
! 323: return (1);
! 324: }
! 325:
! 326: int
! 327: cfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
! 328: void *v;
! 329: const struct wsscreen_descr *type;
! 330: void **cookiep;
! 331: int *curxp, *curyp;
! 332: long *attrp;
! 333: {
! 334: struct cfb_softc *sc = v;
! 335: long defattr;
! 336:
! 337: if (sc->nscreens > 0)
! 338: return (ENOMEM);
! 339:
! 340: *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
! 341: *curxp = 0;
! 342: *curyp = 0;
! 343: rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr);
! 344: *attrp = defattr;
! 345: sc->nscreens++;
! 346: return(0);
! 347: }
! 348:
! 349: void
! 350: cfb_free_screen(v, cookie)
! 351: void *v;
! 352: void *cookie;
! 353: {
! 354: struct cfb_softc *sc = v;
! 355:
! 356: if (sc->sc_dc == &cfb_console_dc)
! 357: panic("cfb_free_screen: console");
! 358:
! 359: sc->nscreens--;
! 360: }
! 361:
! 362: int
! 363: cfb_show_screen(v, cookie, waitok, cb, cbarg)
! 364: void *v;
! 365: void *cookie;
! 366: int waitok;
! 367: void (*cb)(void *, int, int);
! 368: void *cbarg;
! 369: {
! 370: return (0);
! 371: }
! 372:
! 373: #if 0
! 374: int
! 375: cfb_cnattach(addr)
! 376: tc_addr_t addr;
! 377: {
! 378: struct cfb_devconfig *dc = &cfb_console_dc;
! 379: long defattr;
! 380:
! 381: cfb_getdevconfig(addr, dcp);
! 382:
! 383: rcons_alloc_attr(&dcp->dc_rcons, 0, 0, 0, &defattr);
! 384:
! 385: wsdisplay_cnattach(&cfb_stdscreen, &dcp->dc_rcons,
! 386: 0,0, defattr;);
! 387:
! 388: cfb_consaddr = addr;
! 389: return (0);
! 390: }
! 391: #endif
CVSweb