Annotation of sys/arch/macppc/pci/vgafb.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: vgafb.c,v 1.33 2006/12/17 22:18:14 miod Exp $ */
! 2: /* $NetBSD: vga.c,v 1.3 1996/12/02 22:24:54 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/buf.h>
! 36:
! 37: #include <uvm/uvm_extern.h>
! 38:
! 39: #include <machine/bus.h>
! 40:
! 41: #include <dev/cons.h>
! 42: #include <dev/ofw/openfirm.h>
! 43: #include <macppc/macppc/ofw_machdep.h>
! 44:
! 45: #include <dev/wscons/wsconsio.h>
! 46: #include <dev/wscons/wsdisplayvar.h>
! 47: #include <dev/rasops/rasops.h>
! 48: #include <dev/wsfont/wsfont.h>
! 49:
! 50: #include <macppc/pci/vgafbvar.h>
! 51:
! 52: struct cfdriver vgafb_cd = {
! 53: NULL, "vgafb", DV_DULL,
! 54: };
! 55:
! 56: void vgafb_setcolor(struct vgafb_config *vc, unsigned int index,
! 57: u_int8_t r, u_int8_t g, u_int8_t b);
! 58: void vgafb_restore_default_colors(struct vgafb_config *vc);
! 59:
! 60: struct vgafb_devconfig {
! 61: struct rasops_info dc_rinfo; /* raster display data */
! 62: int dc_blanked; /* currently had video disabled */
! 63: };
! 64:
! 65: struct vgafb_devconfig vgafb_console_dc;
! 66:
! 67: struct wsscreen_descr vgafb_stdscreen = {
! 68: "std",
! 69: 0, 0, /* will be filled in -- XXX shouldn't, it's global */
! 70: 0,
! 71: 0, 0,
! 72: WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
! 73: WSSCREEN_REVERSE | WSSCREEN_WSCOLORS
! 74: };
! 75: const struct wsscreen_descr *vgafb_scrlist[] = {
! 76: &vgafb_stdscreen,
! 77: /* XXX other formats, graphics screen? */
! 78: };
! 79:
! 80: struct wsscreen_list vgafb_screenlist = {
! 81: sizeof(vgafb_scrlist) / sizeof(struct wsscreen_descr *), vgafb_scrlist
! 82: };
! 83:
! 84: struct wsdisplay_accessops vgafb_accessops = {
! 85: vgafb_ioctl,
! 86: vgafb_mmap,
! 87: vgafb_alloc_screen,
! 88: vgafb_free_screen,
! 89: vgafb_show_screen,
! 90: NULL, /* load_font */
! 91: NULL, /* scrollback */
! 92: NULL, /* getchar */
! 93: vgafb_burn, /* burner */
! 94: };
! 95:
! 96: int vgafb_getcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm);
! 97: int vgafb_putcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm);
! 98:
! 99: #define FONT_WIDTH 8
! 100: #define FONT_HEIGHT 16
! 101:
! 102: #ifdef APERTURE
! 103: extern int allowaperture;
! 104: #endif
! 105:
! 106: /*
! 107: * The following functions implement back-end configuration grabbing
! 108: * and attachment.
! 109: */
! 110: int
! 111: vgafb_common_probe(bus_space_tag_t iot, bus_space_tag_t memt, u_int32_t iobase,
! 112: size_t iosize, u_int32_t membase, size_t memsize, u_int32_t mmiobase,
! 113: size_t mmiosize)
! 114: {
! 115: bus_space_handle_t ioh_b, ioh_c, ioh_d, memh, mmioh;
! 116: int gotio_b, gotio_c, gotio_d, gotmem, gotmmio, rv;
! 117:
! 118: gotio_b = gotio_c = gotio_d = gotmem = gotmmio = rv = 0;
! 119:
! 120: if (iosize != 0) {
! 121: if (bus_space_map(iot, iobase+0x3b0, 0xc, 0, &ioh_b))
! 122: goto bad;
! 123: gotio_b = 1;
! 124: if (bus_space_map(iot, iobase+0x3c0, 0x10, 0, &ioh_c))
! 125: goto bad;
! 126: gotio_c = 1;
! 127: if (bus_space_map(iot, iobase+0x3d0, 0x10, 0, &ioh_d))
! 128: goto bad;
! 129: gotio_d = 1;
! 130: }
! 131: if (mmiosize != 0) {
! 132: if (bus_space_map(iot, mmiobase, mmiosize, 0, &mmioh))
! 133: goto bad;
! 134: gotmmio = 1;
! 135: }
! 136:
! 137: rv = 1;
! 138:
! 139: bad:
! 140: if (gotio_b)
! 141: bus_space_unmap(iot, ioh_b, 0xc);
! 142: if (gotio_c)
! 143: bus_space_unmap(iot, ioh_c, 0x10);
! 144: if (gotio_d)
! 145: bus_space_unmap(iot, ioh_d, 0x10);
! 146: if (gotmmio)
! 147: bus_space_unmap(memt, mmioh, mmiosize);
! 148: if (gotmem)
! 149: bus_space_unmap(memt, memh, memsize);
! 150:
! 151: return (rv);
! 152: }
! 153:
! 154: void
! 155: vgafb_common_setup(bus_space_tag_t iot, bus_space_tag_t memt,
! 156: struct vgafb_config *vc, u_int32_t iobase, size_t iosize,
! 157: u_int32_t membase, size_t memsize, u_int32_t mmiobase, size_t mmiosize)
! 158: {
! 159: vc->vc_iot = iot;
! 160: vc->vc_memt = memt;
! 161: vc->vc_paddr = membase;
! 162:
! 163: if (iosize != 0) {
! 164: if (bus_space_map(vc->vc_iot, iobase+0x3b0, 0xc, 0, &vc->vc_ioh_b))
! 165: panic("vgafb_common_setup: couldn't map io b");
! 166: if (bus_space_map(vc->vc_iot, iobase+0x3c0, 0x10, 0, &vc->vc_ioh_c))
! 167: panic("vgafb_common_setup: couldn't map io c");
! 168: if (bus_space_map(vc->vc_iot, iobase+0x3d0, 0x10, 0, &vc->vc_ioh_d))
! 169: panic("vgafb_common_setup: couldn't map io d");
! 170: }
! 171: if (mmiosize != 0)
! 172: if (bus_space_map(vc->vc_memt, mmiobase, mmiosize, 0,
! 173: &vc->vc_mmioh))
! 174: panic("vgafb_common_setup: couldn't map mmio");
! 175:
! 176: /* memsize should only be visible region for console */
! 177: memsize = cons_height * cons_linebytes;
! 178: if (bus_space_map(vc->vc_memt, membase, memsize,
! 179: /* XXX */ppc_proc_is_64b ? 0 : 1, &vc->vc_memh))
! 180: panic("vgafb_common_setup: couldn't map memory");
! 181: cons_display_mem_h = vc->vc_memh;
! 182: vc->vc_ofh = cons_display_ofh;
! 183:
! 184:
! 185: vc->vc_crow = vc->vc_ccol = 0; /* Has to be some onscreen value */
! 186: vc->vc_so = 0;
! 187:
! 188: /* clear screen, frob cursor, etc.? */
! 189: /*
! 190: */
! 191:
! 192: vc->vc_at = 0x00 | 0xf; /* black bg|white fg */
! 193: vc->vc_so_at = 0x00 | 0xf | 0x80; /* black bg|white fg|blink */
! 194:
! 195: if (cons_depth == 8) {
! 196: vgafb_restore_default_colors(vc);
! 197: }
! 198: }
! 199:
! 200: void
! 201: vgafb_restore_default_colors(struct vgafb_config *vc)
! 202: {
! 203: int i;
! 204:
! 205: for (i = 0; i < 256; i++) {
! 206: const u_char *color;
! 207:
! 208: color = &rasops_cmap[i * 3];
! 209: vgafb_setcolor(vc, i, color[0], color[1], color[2]);
! 210: }
! 211: }
! 212:
! 213: void
! 214: vgafb_wsdisplay_attach(struct device *parent, struct vgafb_config *vc,
! 215: int console)
! 216: {
! 217: struct wsemuldisplaydev_attach_args aa;
! 218:
! 219: aa.console = console;
! 220: aa.scrdata = &vgafb_screenlist;
! 221: aa.accessops = &vgafb_accessops;
! 222: aa.accesscookie = vc;
! 223: aa.defaultscreens = 0;
! 224:
! 225: /* no need to keep the burner function if no hw support */
! 226: if (cons_backlight_available == 0)
! 227: vgafb_accessops.burn_screen = NULL;
! 228: else {
! 229: vc->vc_backlight_on = WSDISPLAYIO_VIDEO_OFF;
! 230: vgafb_burn(vc, WSDISPLAYIO_VIDEO_ON, 0); /* paranoia */
! 231: }
! 232:
! 233: config_found(parent, &aa, wsemuldisplaydevprint);
! 234: }
! 235:
! 236: int
! 237: vgafb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
! 238: {
! 239: struct vgafb_config *vc = v;
! 240: struct wsdisplay_fbinfo *wdf;
! 241:
! 242: switch (cmd) {
! 243: case WSDISPLAYIO_GTYPE:
! 244: *(u_int *)data = WSDISPLAY_TYPE_PCIVGA;
! 245: return 0;
! 246: case WSDISPLAYIO_GINFO:
! 247: wdf = (void *)data;
! 248: wdf->height = cons_height;
! 249: wdf->width = cons_width;
! 250: wdf->depth = cons_depth;
! 251: wdf->cmsize = 256;
! 252: return 0;
! 253:
! 254: case WSDISPLAYIO_LINEBYTES:
! 255: *(u_int *)data = cons_linebytes;
! 256: return 0;
! 257:
! 258: case WSDISPLAYIO_GETCMAP:
! 259: return vgafb_getcmap(vc, (struct wsdisplay_cmap *)data);
! 260:
! 261: case WSDISPLAYIO_PUTCMAP:
! 262: return vgafb_putcmap(vc, (struct wsdisplay_cmap *)data);
! 263:
! 264: case WSDISPLAYIO_SMODE:
! 265: vc->vc_mode = *(u_int *)data;
! 266: /* track the state of the display,
! 267: * if returning to WSDISPLAYIO_MODE_EMUL
! 268: * restore the last palette, workaround for
! 269: * bad accellerated X servers that does not restore
! 270: * the correct palette.
! 271: */
! 272: if (cons_depth == 8)
! 273: vgafb_restore_default_colors(vc);
! 274: break;
! 275:
! 276: case WSDISPLAYIO_GETPARAM:
! 277: {
! 278: struct wsdisplay_param *dp = (struct wsdisplay_param *)data;
! 279:
! 280: switch (dp->param) {
! 281: case WSDISPLAYIO_PARAM_BRIGHTNESS:
! 282: if (cons_backlight_available != 0) {
! 283: dp->min = MIN_BRIGHTNESS;
! 284: dp->max = MAX_BRIGHTNESS;
! 285: dp->curval = cons_brightness;
! 286: return 0;
! 287: }
! 288: return -1;
! 289: case WSDISPLAYIO_PARAM_BACKLIGHT:
! 290: if (cons_backlight_available != 0) {
! 291: dp->min = 0;
! 292: dp->max = 1;
! 293: dp->curval = vc->vc_backlight_on;
! 294: return 0;
! 295: } else
! 296: return -1;
! 297: }
! 298: }
! 299: return -1;
! 300:
! 301: case WSDISPLAYIO_SETPARAM:
! 302: {
! 303: struct wsdisplay_param *dp = (struct wsdisplay_param *)data;
! 304:
! 305: switch (dp->param) {
! 306: case WSDISPLAYIO_PARAM_BRIGHTNESS:
! 307: if (cons_backlight_available == 1) {
! 308: of_setbrightness(dp->curval);
! 309: return 0;
! 310: } else
! 311: return -1;
! 312: case WSDISPLAYIO_PARAM_BACKLIGHT:
! 313: if (cons_backlight_available != 0) {
! 314: vgafb_burn(vc,
! 315: dp->curval ? WSDISPLAYIO_VIDEO_ON :
! 316: WSDISPLAYIO_VIDEO_OFF, 0);
! 317: return 0;
! 318: } else
! 319: return -1;
! 320: }
! 321: }
! 322: return -1;
! 323:
! 324: case WSDISPLAYIO_SVIDEO:
! 325: case WSDISPLAYIO_GVIDEO:
! 326: break;
! 327:
! 328: case WSDISPLAYIO_GCURPOS:
! 329: case WSDISPLAYIO_SCURPOS:
! 330: case WSDISPLAYIO_GCURMAX:
! 331: case WSDISPLAYIO_GCURSOR:
! 332: case WSDISPLAYIO_SCURSOR:
! 333: default:
! 334: return -1; /* not supported yet */
! 335: }
! 336:
! 337: return (0);
! 338: }
! 339:
! 340: paddr_t
! 341: vgafb_mmap(void *v, off_t offset, int prot)
! 342: {
! 343: struct vgafb_config *vc = v;
! 344: bus_space_handle_t h;
! 345:
! 346: switch (vc->vc_mode) {
! 347: case WSDISPLAYIO_MODE_MAPPED:
! 348: #ifdef APERTURE
! 349: if (allowaperture == 0) {
! 350: h = -1;
! 351: break;
! 352: }
! 353: #endif
! 354: if (offset >= 0xa0000 && offset < 0xfffff)
! 355: h = offset;
! 356: /* XXX the following are probably wrong.
! 357: we want physical addresses here, not virtual ones */
! 358: else if (offset >= 0x10000000 && offset < 0x10040000 )
! 359: /* 256KB of iohb */
! 360: h = vc->vc_ioh_b;
! 361: else if (offset >= 0x10040000 && offset < 0x10080000)
! 362: /* 256KB of iohc */
! 363: h = vc->vc_ioh_c;
! 364: else if (offset >= 0x18880000 && offset < 0x100c0000)
! 365: /* 256KB of iohd */
! 366: h = vc->vc_ioh_d;
! 367: else if (offset >= 0x20000000 && offset < 0x20000000+vc->mmiosize)
! 368: /* mmiosize... */
! 369: h = vc->vc_mmioh + (offset - 0x20000000);
! 370: else if (offset >= vc->membase && (offset < vc->membase+vc->memsize)) {
! 371: /* allow mmapping of memory */
! 372: h = offset;
! 373: } else if (offset >= vc->mmiobase &&
! 374: (offset < vc->mmiobase+vc->mmiosize)) {
! 375: /* allow mmapping of mmio space */
! 376: h = offset;
! 377:
! 378: } else {
! 379: h = -1;
! 380: }
! 381: break;
! 382:
! 383: case WSDISPLAYIO_MODE_DUMBFB:
! 384: if (offset >= 0x00000 && offset < vc->memsize)
! 385: h = vc->vc_paddr + offset;
! 386: break;
! 387:
! 388: }
! 389: return h;
! 390: }
! 391:
! 392:
! 393: void
! 394: vgafb_cnprobe(struct consdev *cp)
! 395: {
! 396: if (cons_displaytype != 1)
! 397: return;
! 398:
! 399: cp->cn_pri = CN_INTERNAL;
! 400: }
! 401:
! 402: void
! 403: vgafb_cnattach(bus_space_tag_t iot, bus_space_tag_t memt, void *pc, int bus,
! 404: int device, int function)
! 405: {
! 406: long defattr;
! 407:
! 408: struct vgafb_devconfig *dc = &vgafb_console_dc;
! 409: struct rasops_info *ri = &dc->dc_rinfo;
! 410:
! 411: ri->ri_flg = RI_CENTER;
! 412: ri->ri_depth = cons_depth;
! 413: ri->ri_bits = (void *)cons_display_mem_h;
! 414: ri->ri_width = cons_width;
! 415: ri->ri_height = cons_height;
! 416: ri->ri_stride = cons_linebytes;
! 417: ri->ri_hw = dc;
! 418:
! 419: rasops_init(ri, 160, 160); /* XXX */
! 420:
! 421: vgafb_stdscreen.nrows = ri->ri_rows;
! 422: vgafb_stdscreen.ncols = ri->ri_cols;
! 423: vgafb_stdscreen.textops = &ri->ri_ops;
! 424: ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
! 425:
! 426: wsdisplay_cnattach(&vgafb_stdscreen, ri, 0, 0, defattr);
! 427: }
! 428:
! 429: struct {
! 430: u_int8_t r;
! 431: u_int8_t g;
! 432: u_int8_t b;
! 433: } vgafb_color[256];
! 434:
! 435: void
! 436: vgafb_setcolor(struct vgafb_config *vc, unsigned int index, u_int8_t r,
! 437: u_int8_t g, u_int8_t b)
! 438: {
! 439: vc->vc_cmap_red[index] = r;
! 440: vc->vc_cmap_green[index] = g;
! 441: vc->vc_cmap_blue[index] = b;
! 442:
! 443: vgafb_color[index].r = r;
! 444: vgafb_color[index].g = g;
! 445: vgafb_color[index].b = b;
! 446: OF_call_method_1("set-colors", cons_display_ofh, 3,
! 447: &vgafb_color[index], index, 1);
! 448: }
! 449:
! 450: int
! 451: vgafb_getcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm)
! 452: {
! 453: u_int index = cm->index;
! 454: u_int count = cm->count;
! 455: int error;
! 456:
! 457: if (index >= 256 || count > 256 - index)
! 458: return EINVAL;
! 459:
! 460: error = copyout(&vc->vc_cmap_red[index], cm->red, count);
! 461: if (error)
! 462: return error;
! 463: error = copyout(&vc->vc_cmap_green[index], cm->green, count);
! 464: if (error)
! 465: return error;
! 466: error = copyout(&vc->vc_cmap_blue[index], cm->blue, count);
! 467: if (error)
! 468: return error;
! 469:
! 470: return 0;
! 471: }
! 472:
! 473: int
! 474: vgafb_putcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm)
! 475: {
! 476: u_int index = cm->index;
! 477: u_int count = cm->count;
! 478: u_int i;
! 479: int error;
! 480: u_int8_t *r, *g, *b;
! 481:
! 482: if (index >= 256 || count > 256 - index)
! 483: return EINVAL;
! 484:
! 485: if ((error = copyin(cm->red, &vc->vc_cmap_red[index], count)) != 0)
! 486: return (error);
! 487: if ((error = copyin(cm->green, &vc->vc_cmap_green[index], count)) != 0)
! 488: return (error);
! 489: if ((error = copyin(cm->blue, &vc->vc_cmap_blue[index], count)) != 0)
! 490: return (error);
! 491:
! 492: r = &(vc->vc_cmap_red[index]);
! 493: g = &(vc->vc_cmap_green[index]);
! 494: b = &(vc->vc_cmap_blue[index]);
! 495:
! 496: for (i = 0; i < count; i++) {
! 497: vgafb_color[i].r = *r;
! 498: vgafb_color[i].g = *g;
! 499: vgafb_color[i].b = *b;
! 500: r++, g++, b++;
! 501: }
! 502: OF_call_method_1("set-colors", cons_display_ofh, 3,
! 503: &vgafb_color, index, count);
! 504: return 0;
! 505: }
! 506:
! 507: void
! 508: vgafb_burn(void *v, u_int on, u_int flags)
! 509: {
! 510: struct vgafb_config *vc = v;
! 511:
! 512: if (cons_backlight_available == 1 &&
! 513: vc->vc_backlight_on != on) {
! 514: if (on == WSDISPLAYIO_VIDEO_ON) {
! 515: OF_call_method_1("backlight-on", cons_display_ofh, 0);
! 516: } else {
! 517: OF_call_method_1("backlight-off", cons_display_ofh, 0);
! 518: }
! 519: vc->vc_backlight_on = on;
! 520: }
! 521: }
CVSweb