1 /* $OpenBSD: cgthree.c,v 1.35 2003/08/01 19:24:47 miod Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Jason L. Wright (jason@thought.net) 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 * Effort sponsored in part by the Defense Advanced Research Projects 29 * Agency (DARPA) and Air Force Research Laboratory, Air Force 30 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 31 * 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/errno.h> 38 #include <sys/device.h> 39 #include <sys/ioctl.h> 40 #include <sys/malloc.h> 41 42 #include <machine/bus.h> 43 #include <machine/intr.h> 44 #include <machine/autoconf.h> 45 #include <machine/openfirm.h> 46 47 #include <dev/sbus/sbusvar.h> 48 #include <dev/wscons/wsconsio.h> 49 #include <dev/wscons/wsdisplayvar.h> 50 #include <dev/wscons/wscons_raster.h> 51 #include <dev/rasops/rasops.h> 52 #include <machine/fbvar.h> 53 54 #include <dev/ic/bt458reg.h> 55 56 #define CGTHREE_CTRL_OFFSET 0x400000 57 #define CGTHREE_CTRL_SIZE (sizeof(u_int32_t) * 8) 58 #define CGTHREE_VID_OFFSET 0x800000 59 #define CGTHREE_VID_SIZE (1024 * 1024) 60 61 union bt_cmap { 62 u_int8_t cm_map[256][3]; /* 256 r/b/g entries */ 63 u_int32_t cm_chip[256 * 3 / 4]; /* the way the chip is loaded */ 64 }; 65 66 #define BT_ADDR 0x00 /* map address register */ 67 #define BT_CMAP 0x04 /* colormap data register */ 68 #define BT_CTRL 0x08 /* control register */ 69 #define BT_OMAP 0x0c /* overlay (cursor) map register */ 70 #define CG3_FBC_CTRL 0x10 /* control */ 71 #define CG3_FBC_STAT 0x11 /* status */ 72 #define CG3_FBC_START 0x12 /* cursor start */ 73 #define CG3_FBC_END 0x13 /* cursor end */ 74 #define CG3_FBC_VCTRL 0x14 /* 12 bytes of timing goo */ 75 76 #define BT_WRITE(sc, reg, val) \ 77 bus_space_write_4((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), (val)) 78 #define BT_READ(sc, reg) \ 79 bus_space_read_4((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg)) 80 #define BT_BARRIER(sc,reg,flags) \ 81 bus_space_barrier((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), \ 82 sizeof(u_int32_t), (flags)) 83 84 #define BT_D4M3(x) ((((x) >> 2) << 1) + ((x) >> 2)) /* (x / 4) * 3 */ 85 #define BT_D4M4(x) ((x) & ~3) /* (x / 4) * 4 */ 86 87 #define FBC_CTRL_IENAB 0x80 /* interrupt enable */ 88 #define FBC_CTRL_VENAB 0x40 /* video enable */ 89 #define FBC_CTRL_TIME 0x20 /* timing enable */ 90 #define FBC_CTRL_CURS 0x10 /* cursor compare enable */ 91 #define FBC_CTRL_XTAL 0x0c /* xtal select (0,1,2,test): */ 92 #define FBC_CTRL_XTAL_0 0x00 /* 0 */ 93 #define FBC_CTRL_XTAL_1 0x04 /* 0 */ 94 #define FBC_CTRL_XTAL_2 0x08 /* 0 */ 95 #define FBC_CTRL_XTAL_TEST 0x0c /* 0 */ 96 #define FBC_CTRL_DIV 0x03 /* divisor (1,2,3,4): */ 97 #define FBC_CTRL_DIV_1 0x00 /* / 1 */ 98 #define FBC_CTRL_DIV_2 0x01 /* / 2 */ 99 #define FBC_CTRL_DIV_3 0x02 /* / 3 */ 100 #define FBC_CTRL_DIV_4 0x03 /* / 4 */ 101 102 #define FBC_STAT_INTR 0x80 /* interrupt pending */ 103 #define FBC_STAT_RES 0x70 /* monitor sense: */ 104 #define FBC_STAT_RES_1024 0x10 /* 1024x768 */ 105 #define FBC_STAT_RES_1280 0x40 /* 1280x1024 */ 106 #define FBC_STAT_RES_1152 0x30 /* 1152x900 */ 107 #define FBC_STAT_RES_1152A 0x40 /* 1152x900x76, A */ 108 #define FBC_STAT_RES_1600 0x50 /* 1600x1200 */ 109 #define FBC_STAT_RES_1152B 0x60 /* 1152x900x86, B */ 110 #define FBC_STAT_ID 0x0f /* id mask: */ 111 #define FBC_STAT_ID_COLOR 0x01 /* color */ 112 #define FBC_STAT_ID_MONO 0x02 /* monochrome */ 113 #define FBC_STAT_ID_MONOECL 0x03 /* monochrome, ecl */ 114 115 #define FBC_READ(sc, reg) \ 116 bus_space_read_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg)) 117 #define FBC_WRITE(sc, reg, val) \ 118 bus_space_write_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), (val)) 119 120 struct cgthree_softc { 121 struct sunfb sc_sunfb; 122 struct sbusdev sc_sd; 123 bus_space_tag_t sc_bustag; 124 bus_addr_t sc_paddr; 125 bus_space_handle_t sc_ctrl_regs; 126 bus_space_handle_t sc_vid_regs; 127 int sc_nscreens; 128 union bt_cmap sc_cmap; 129 u_int sc_mode; 130 }; 131 132 struct wsscreen_descr cgthree_stdscreen = { 133 "std", 134 }; 135 136 const struct wsscreen_descr *cgthree_scrlist[] = { 137 &cgthree_stdscreen, 138 /* XXX other formats? */ 139 }; 140 141 struct wsscreen_list cgthree_screenlist = { 142 sizeof(cgthree_scrlist) / sizeof(struct wsscreen_descr *), cgthree_scrlist 143 }; 144 145 int cgthree_ioctl(void *, u_long, caddr_t, int, struct proc *); 146 int cgthree_alloc_screen(void *, const struct wsscreen_descr *, void **, 147 int *, int *, long *); 148 void cgthree_free_screen(void *, void *); 149 int cgthree_show_screen(void *, void *, int, void (*cb)(void *, int, int), 150 void *); 151 paddr_t cgthree_mmap(void *, off_t, int); 152 int cgthree_is_console(int); 153 void cgthree_loadcmap(struct cgthree_softc *, u_int, u_int); 154 int cg3_bt_putcmap(union bt_cmap *, struct wsdisplay_cmap *); 155 int cg3_bt_getcmap(union bt_cmap *, struct wsdisplay_cmap *); 156 void cgthree_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t); 157 void cgthree_burner(void *, u_int, u_int); 158 void cgthree_reset(struct cgthree_softc *); 159 void cgthree_updatecursor(struct rasops_info *); 160 161 struct wsdisplay_accessops cgthree_accessops = { 162 cgthree_ioctl, 163 cgthree_mmap, 164 cgthree_alloc_screen, 165 cgthree_free_screen, 166 cgthree_show_screen, 167 NULL, /* load_font */ 168 NULL, /* scrollback */ 169 NULL, /* getchar */ 170 cgthree_burner, 171 }; 172 173 int cgthreematch(struct device *, void *, void *); 174 void cgthreeattach(struct device *, struct device *, void *); 175 176 struct cfattach cgthree_ca = { 177 sizeof (struct cgthree_softc), cgthreematch, cgthreeattach 178 }; 179 180 struct cfdriver cgthree_cd = { 181 NULL, "cgthree", DV_DULL 182 }; 183 184 #define CG3_TYPE_DEFAULT 0 185 #define CG3_TYPE_76HZ 1 186 #define CG3_TYPE_SMALL 2 187 188 struct cg3_videoctrl { 189 u_int8_t sense; 190 u_int8_t vctrl[12]; 191 u_int8_t ctrl; 192 } cg3_videoctrl[] = { 193 { /* cpd-1790 */ 194 0x31, 195 { 0xbb, 0x2b, 0x04, 0x14, 0xae, 0x03, 196 0xa8, 0x24, 0x01, 0x05, 0xff, 0x01 }, 197 FBC_CTRL_XTAL_0 | FBC_CTRL_DIV_1 198 }, 199 { /* gdm-20e20 */ 200 0x41, 201 { 0xb7, 0x27, 0x03, 0x0f, 0xae, 0x03, 202 0xae, 0x2a, 0x01, 0x09, 0xff, 0x01 }, 203 FBC_CTRL_XTAL_1 | FBC_CTRL_DIV_1 204 }, 205 { /* defaults, should be last */ 206 0xff, 207 { 0xbb, 0x2b, 0x03, 0x0b, 0xb3, 0x03, 208 0xaf, 0x2b, 0x02, 0x0a, 0xff, 0x01 }, 209 0, 210 }, 211 }; 212 213 int 214 cgthreematch(struct device *parent, void *vcf, void *aux) 215 { 216 struct cfdata *cf = vcf; 217 struct sbus_attach_args *sa = aux; 218 219 return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0); 220 } 221 222 void 223 cgthreeattach(struct device *parent, struct device *self, void *aux) 224 { 225 struct cgthree_softc *sc = (struct cgthree_softc *)self; 226 struct sbus_attach_args *sa = aux; 227 struct wsemuldisplaydev_attach_args waa; 228 int console, i; 229 230 sc->sc_bustag = sa->sa_bustag; 231 sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset); 232 233 fb_setsize(&sc->sc_sunfb, 8, 1152, 900, sa->sa_node, 0); 234 235 if (sa->sa_nreg != 1) { 236 printf(": expected %d registers, got %d\n", 1, sa->sa_nreg); 237 goto fail; 238 } 239 240 /* 241 * Map just CTRL and video RAM. 242 */ 243 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, 244 sa->sa_reg[0].sbr_offset + CGTHREE_CTRL_OFFSET, 245 CGTHREE_CTRL_SIZE, 0, 0, &sc->sc_ctrl_regs) != 0) { 246 printf(": cannot map ctrl registers\n"); 247 goto fail_ctrl; 248 } 249 250 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, 251 sa->sa_reg[0].sbr_offset + CGTHREE_VID_OFFSET, 252 sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR, 253 0, &sc->sc_vid_regs) != 0) { 254 printf(": cannot map vid registers\n"); 255 goto fail_vid; 256 } 257 258 console = cgthree_is_console(sa->sa_node); 259 260 sbus_establish(&sc->sc_sd, &sc->sc_sunfb.sf_dev); 261 262 cgthree_reset(sc); 263 264 BT_WRITE(sc, BT_ADDR, 0); 265 for (i = 0; i < 256 * 3 / 4; i++) 266 sc->sc_cmap.cm_chip[i] = BT_READ(sc, BT_CMAP); 267 268 cgthree_burner(sc, 1, 0); 269 270 sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag, 271 sc->sc_vid_regs); 272 sc->sc_sunfb.sf_ro.ri_hw = sc; 273 274 printf("\n"); 275 276 /* 277 * If the framebuffer width is under 1024x768, which is the case for 278 * some clones on laptops, as well as with the VS10-EK, switch from 279 * the PROM font to the more adequate 8x16 font here. 280 * However, we need to adjust two things in this case: 281 * - the display row should be overrided from the current PROM metrics, 282 * to prevent us from overwriting the last few lines of text. 283 * - if the 80x34 screen would make a large margin appear around it, 284 * choose to clear the screen rather than keeping old prom output in 285 * the margins. 286 * XXX there should be a rasops "clear margins" feature 287 */ 288 fbwscons_init(&sc->sc_sunfb, console && 289 (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR); 290 291 cgthree_stdscreen.capabilities = sc->sc_sunfb.sf_ro.ri_caps; 292 cgthree_stdscreen.nrows = sc->sc_sunfb.sf_ro.ri_rows; 293 cgthree_stdscreen.ncols = sc->sc_sunfb.sf_ro.ri_cols; 294 cgthree_stdscreen.textops = &sc->sc_sunfb.sf_ro.ri_ops; 295 296 fbwscons_setcolormap(&sc->sc_sunfb, cgthree_setcolor); 297 298 if (console) { 299 sc->sc_sunfb.sf_ro.ri_updatecursor = cgthree_updatecursor; 300 fbwscons_console_init(&sc->sc_sunfb, &cgthree_stdscreen, 301 sc->sc_sunfb.sf_width >= 1024 ? -1 : 0, cgthree_burner); 302 } 303 304 waa.console = console; 305 waa.scrdata = &cgthree_screenlist; 306 waa.accessops = &cgthree_accessops; 307 waa.accesscookie = sc; 308 config_found(self, &waa, wsemuldisplaydevprint); 309 310 return; 311 312 fail_vid: 313 bus_space_unmap(sa->sa_bustag, sc->sc_ctrl_regs, CGTHREE_CTRL_SIZE); 314 fail_ctrl: 315 fail: 316 ; 317 } 318 319 int 320 cgthree_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) 321 { 322 struct cgthree_softc *sc = v; 323 struct wsdisplay_fbinfo *wdf; 324 struct wsdisplay_cmap *cm; 325 int error; 326 327 switch (cmd) { 328 case WSDISPLAYIO_GTYPE: 329 *(u_int *)data = WSDISPLAY_TYPE_SUNCG3; 330 break; 331 case WSDISPLAYIO_SMODE: 332 sc->sc_mode = *(u_int *)data; 333 break; 334 case WSDISPLAYIO_GINFO: 335 wdf = (void *)data; 336 wdf->height = sc->sc_sunfb.sf_height; 337 wdf->width = sc->sc_sunfb.sf_width; 338 wdf->depth = sc->sc_sunfb.sf_depth; 339 wdf->cmsize = 256; 340 break; 341 case WSDISPLAYIO_LINEBYTES: 342 *(u_int *)data = sc->sc_sunfb.sf_linebytes; 343 break; 344 345 case WSDISPLAYIO_GETCMAP: 346 cm = (struct wsdisplay_cmap *)data; 347 error = cg3_bt_getcmap(&sc->sc_cmap, cm); 348 if (error) 349 return (error); 350 break; 351 352 case WSDISPLAYIO_PUTCMAP: 353 cm = (struct wsdisplay_cmap *)data; 354 error = cg3_bt_putcmap(&sc->sc_cmap, cm); 355 if (error) 356 return (error); 357 cgthree_loadcmap(sc, cm->index, cm->count); 358 break; 359 360 case WSDISPLAYIO_SVIDEO: 361 case WSDISPLAYIO_GVIDEO: 362 case WSDISPLAYIO_GCURPOS: 363 case WSDISPLAYIO_SCURPOS: 364 case WSDISPLAYIO_GCURMAX: 365 case WSDISPLAYIO_GCURSOR: 366 case WSDISPLAYIO_SCURSOR: 367 default: 368 return -1; /* not supported yet */ 369 } 370 371 return (0); 372 } 373 374 int 375 cgthree_alloc_screen(void *v, const struct wsscreen_descr *type, 376 void **cookiep, int *curxp, int *curyp, long *attrp) 377 { 378 struct cgthree_softc *sc = v; 379 380 if (sc->sc_nscreens > 0) 381 return (ENOMEM); 382 383 *cookiep = &sc->sc_sunfb.sf_ro; 384 *curyp = 0; 385 *curxp = 0; 386 sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro, 387 WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp); 388 sc->sc_nscreens++; 389 return (0); 390 } 391 392 void 393 cgthree_free_screen(void *v, void *cookie) 394 { 395 struct cgthree_softc *sc = v; 396 397 sc->sc_nscreens--; 398 } 399 400 int 401 cgthree_show_screen(void *v, void *cookie, int waitok, 402 void (*cb)(void *, int, int), void *cbarg) 403 { 404 return (0); 405 } 406 407 #define START (128 * 1024 + 128 * 1024) 408 #define NOOVERLAY (0x04000000) 409 410 paddr_t 411 cgthree_mmap(void *v, off_t offset, int prot) 412 { 413 struct cgthree_softc *sc = v; 414 415 if (offset & PGOFSET || offset < 0) 416 return (-1); 417 418 switch (sc->sc_mode) { 419 case WSDISPLAYIO_MODE_MAPPED: 420 if (offset >= NOOVERLAY) 421 offset -= NOOVERLAY; 422 else if (offset >= START) 423 offset -= START; 424 else 425 offset = 0; 426 if (offset >= sc->sc_sunfb.sf_fbsize) 427 return (-1); 428 return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr, 429 CGTHREE_VID_OFFSET + offset, prot, BUS_SPACE_MAP_LINEAR)); 430 case WSDISPLAYIO_MODE_DUMBFB: 431 if (offset < sc->sc_sunfb.sf_fbsize) 432 return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr, 433 CGTHREE_VID_OFFSET + offset, prot, 434 BUS_SPACE_MAP_LINEAR)); 435 break; 436 } 437 return (-1); 438 } 439 440 int 441 cgthree_is_console(int node) 442 { 443 extern int fbnode; 444 445 return (fbnode == node); 446 } 447 448 void 449 cgthree_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b) 450 { 451 struct cgthree_softc *sc = v; 452 union bt_cmap *bcm = &sc->sc_cmap; 453 454 bcm->cm_map[index][0] = r; 455 bcm->cm_map[index][1] = g; 456 bcm->cm_map[index][2] = b; 457 cgthree_loadcmap(sc, index, 1); 458 } 459 460 void 461 cgthree_loadcmap(struct cgthree_softc *sc, u_int start, u_int ncolors) 462 { 463 u_int cstart; 464 int count; 465 466 cstart = BT_D4M3(start); 467 count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3; 468 BT_WRITE(sc, BT_ADDR, BT_D4M4(start)); 469 while (--count >= 0) { 470 BT_WRITE(sc, BT_CMAP, sc->sc_cmap.cm_chip[cstart]); 471 cstart++; 472 } 473 } 474 475 int 476 cg3_bt_getcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm) 477 { 478 u_int index = rcm->index, count = rcm->count, i; 479 int error; 480 481 if (index >= 256 || count > 256 - index) 482 return (EINVAL); 483 for (i = 0; i < count; i++) { 484 if ((error = copyout(&bcm->cm_map[index + i][0], 485 &rcm->red[i], 1)) != 0) 486 return (error); 487 if ((error = copyout(&bcm->cm_map[index + i][1], 488 &rcm->green[i], 1)) != 0) 489 return (error); 490 if ((error = copyout(&bcm->cm_map[index + i][2], 491 &rcm->blue[i], 1)) != 0) 492 return (error); 493 } 494 return (0); 495 } 496 497 int 498 cg3_bt_putcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm) 499 { 500 u_int index = rcm->index, count = rcm->count, i; 501 int error; 502 503 if (index >= 256 || count > 256 - index) 504 return (EINVAL); 505 for (i = 0; i < count; i++) { 506 if ((error = copyin(&rcm->red[i], 507 &bcm->cm_map[index + i][0], 1)) != 0) 508 return (error); 509 if ((error = copyin(&rcm->green[i], 510 &bcm->cm_map[index + i][1], 1)) != 0) 511 return (error); 512 if ((error = copyin(&rcm->blue[i], 513 &bcm->cm_map[index + i][2], 1)) != 0) 514 return (error); 515 } 516 return (0); 517 } 518 519 void 520 cgthree_reset(struct cgthree_softc *sc) 521 { 522 int i, j; 523 u_int8_t sts, ctrl; 524 525 sts = FBC_READ(sc, CG3_FBC_STAT); 526 ctrl = FBC_READ(sc, CG3_FBC_CTRL); 527 528 if (ctrl & FBC_CTRL_TIME) { 529 /* already initialized */ 530 return; 531 } 532 533 for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]); i++) { 534 if (cg3_videoctrl[i].sense == 0xff || 535 (cg3_videoctrl[i].sense == 536 (sts & (FBC_STAT_RES | FBC_STAT_ID)))) { 537 for (j = 0; j < 12; j++) 538 FBC_WRITE(sc, CG3_FBC_VCTRL + j, 539 cg3_videoctrl[i].vctrl[j]); 540 ctrl &= ~(FBC_CTRL_XTAL | FBC_CTRL_DIV); 541 ctrl |= cg3_videoctrl[i].ctrl | 542 FBC_CTRL_TIME; 543 FBC_WRITE(sc, CG3_FBC_CTRL, ctrl); 544 break; 545 } 546 } 547 548 /* enable all the bit planes */ 549 BT_WRITE(sc, BT_ADDR, BT_RMR); 550 BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE); 551 BT_WRITE(sc, BT_CTRL, 0xff); 552 BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE); 553 554 /* no plane should blink */ 555 BT_WRITE(sc, BT_ADDR, BT_BMR); 556 BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE); 557 BT_WRITE(sc, BT_CTRL, 0x00); 558 BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE); 559 560 /* 561 * enable the RAMDAC, disable blink, disable overlay 0 and 1, 562 * use 4:1 multiplexor. 563 */ 564 BT_WRITE(sc, BT_ADDR, BT_CR); 565 BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE); 566 BT_WRITE(sc, BT_CTRL, 567 (BTCR_MPLX_4 | BTCR_RAMENA | BTCR_BLINK_6464)); 568 BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE); 569 570 /* disable the D/A read pins */ 571 BT_WRITE(sc, BT_ADDR, BT_CTR); 572 BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE); 573 BT_WRITE(sc, BT_CTRL, 0x00); 574 BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE); 575 } 576 577 void 578 cgthree_burner(void *vsc, u_int on, u_int flags) 579 { 580 struct cgthree_softc *sc = vsc; 581 int s; 582 u_int8_t fbc; 583 584 s = splhigh(); 585 fbc = FBC_READ(sc, CG3_FBC_CTRL); 586 if (on) 587 fbc |= FBC_CTRL_VENAB | FBC_CTRL_TIME; 588 else { 589 fbc &= ~FBC_CTRL_VENAB; 590 if (flags & WSDISPLAY_BURN_VBLANK) 591 fbc &= ~FBC_CTRL_TIME; 592 } 593 FBC_WRITE(sc, CG3_FBC_CTRL, fbc); 594 splx(s); 595 } 596 597 void 598 cgthree_updatecursor(struct rasops_info *ri) 599 { 600 struct cgthree_softc *sc = ri->ri_hw; 601 602 if (sc->sc_sunfb.sf_crowp != NULL) 603 *sc->sc_sunfb.sf_crowp = ri->ri_crow; 604 if (sc->sc_sunfb.sf_ccolp != NULL) 605 *sc->sc_sunfb.sf_ccolp = ri->ri_ccol; 606 } 607