1 /* $OpenBSD: tga.c,v 1.45 2024/07/22 12:05:38 jsg Exp $ */ 2 /* $NetBSD: tga.c,v 1.40 2002/03/13 15:05:18 ad 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/conf.h> 36 #include <sys/malloc.h> 37 #include <sys/buf.h> 38 #include <sys/ioctl.h> 39 40 #include <machine/bus.h> 41 #include <machine/intr.h> 42 43 #include <dev/pci/pcireg.h> 44 #include <dev/pci/pcivar.h> 45 #include <dev/pci/pcidevs.h> 46 #include <dev/pci/tgareg.h> 47 #include <dev/pci/tgavar.h> 48 #include <dev/ic/bt485reg.h> 49 #include <dev/ic/bt485var.h> 50 #include <dev/ic/bt463reg.h> 51 #include <dev/ic/bt463var.h> 52 #include <dev/ic/ibm561var.h> 53 54 #include <dev/wscons/wsconsio.h> 55 #include <dev/rasops/rasops.h> 56 #include <dev/wsfont/wsfont.h> 57 58 #if defined(__alpha__) || defined(__mips__) 59 #include <uvm/uvm_extern.h> 60 #endif 61 62 #ifdef __alpha__ 63 #include <machine/pte.h> 64 #endif 65 #ifdef __mips__ 66 #include <mips/pte.h> 67 #endif 68 69 int tgamatch(struct device *, struct cfdata *, void *); 70 void tgaattach(struct device *, struct device *, void *); 71 72 struct cfdriver tga_cd = { 73 NULL, "tga", DV_DULL 74 }; 75 76 const struct cfattach tga_ca = { 77 sizeof(struct tga_softc), (cfmatch_t)tgamatch, tgaattach, 78 }; 79 80 int tga_identify(struct tga_devconfig *); 81 const struct tga_conf *tga_getconf(int); 82 void tga_getdevconfig(bus_space_tag_t memt, pci_chipset_tag_t pc, 83 pcitag_t tag, struct tga_devconfig *dc); 84 unsigned tga_getdotclock(struct tga_devconfig *dc); 85 86 struct tga_devconfig tga_console_dc; 87 88 int tga_ioctl(void *, u_long, caddr_t, int, struct proc *); 89 paddr_t tga_mmap(void *, off_t, int); 90 int tga_alloc_screen(void *, const struct wsscreen_descr *, 91 void **, int *, int *, uint32_t *); 92 void tga_free_screen(void *, void *); 93 int tga_show_screen(void *, void *, int, 94 void (*) (void *, int, int), void *); 95 int tga_load_font(void *, void *, struct wsdisplay_font *); 96 int tga_list_font(void *, struct wsdisplay_font *); 97 void tga_burner(void *, u_int, u_int); 98 99 int tga_copyrows(void *, int, int, int); 100 int tga_copycols(void *, int, int, int, int); 101 int tga_eraserows(void *, int, int, uint32_t); 102 int tga_erasecols(void *, int, int, int, uint32_t); 103 int tga_putchar(void *c, int row, int col, u_int uc, uint32_t attr); 104 105 int tga_rop(struct rasops_info *, int, int, int, int, 106 struct rasops_info *, int, int); 107 int tga_rop_vtov(struct rasops_info *, int, int, int, 108 int, struct rasops_info *, int, int ); 109 void tga2_init(struct tga_devconfig *); 110 111 void tga_config_interrupts(struct device *); 112 113 /* RAMDAC interface functions */ 114 int tga_sched_update(void *, void (*)(void *)); 115 void tga_ramdac_wr(void *, u_int, u_int8_t); 116 u_int8_t tga_ramdac_rd(void *, u_int); 117 void tga_bt463_wr(void *, u_int, u_int8_t); 118 u_int8_t tga_bt463_rd(void *, u_int); 119 void tga2_ramdac_wr(void *, u_int, u_int8_t); 120 u_int8_t tga2_ramdac_rd(void *, u_int); 121 122 /* Interrupt handler */ 123 int tga_intr(void *); 124 125 /* The NULL entries will get filled in by rasops_init(). 126 * XXX and the non-NULL ones will be overwritten; reset after calling it. 127 */ 128 struct wsdisplay_emulops tga_emulops = { 129 NULL, 130 NULL, 131 tga_putchar, 132 tga_copycols, 133 tga_erasecols, 134 tga_copyrows, 135 tga_eraserows, 136 NULL, 137 NULL 138 }; 139 140 struct wsscreen_descr tga_stdscreen = { 141 "std", 142 0, 0, /* will be filled in -- XXX shouldn't, it's global */ 143 &tga_emulops, 144 0, 0, 145 WSSCREEN_UNDERLINE | WSSCREEN_HILIT | 146 WSSCREEN_WSCOLORS | WSSCREEN_REVERSE 147 }; 148 149 const struct wsscreen_descr *_tga_scrlist[] = { 150 &tga_stdscreen, 151 /* XXX other formats, graphics screen? */ 152 }; 153 154 struct wsscreen_list tga_screenlist = { 155 sizeof(_tga_scrlist) / sizeof(struct wsscreen_descr *), _tga_scrlist 156 }; 157 158 struct wsdisplay_accessops tga_accessops = { 159 .ioctl = tga_ioctl, 160 .mmap = tga_mmap, 161 .alloc_screen = tga_alloc_screen, 162 .free_screen = tga_free_screen, 163 .show_screen = tga_show_screen, 164 .load_font = tga_load_font, 165 .list_font = tga_list_font, 166 .burn_screen = tga_burner 167 }; 168 169 void tga_blank(struct tga_devconfig *); 170 void tga_unblank(struct tga_devconfig *); 171 172 #ifdef TGA_DEBUG 173 #define DPRINTF(...) printf (__VA_ARGS__) 174 #define DPRINTFN(n, ...) if (tgadebug > (n)) printf (__VA_ARGS__) 175 int tgadebug = 0; 176 #else 177 #define DPRINTF(...) 178 #define DPRINTFN(n,...) 179 #endif 180 181 const struct pci_matchid tga_devices[] = { 182 { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21030 }, 183 { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PBXGB }, 184 }; 185 186 int 187 tgamatch(parent, match, aux) 188 struct device *parent; 189 struct cfdata *match; 190 void *aux; 191 { 192 if (pci_matchbyid((struct pci_attach_args *)aux, tga_devices, 193 sizeof(tga_devices) / sizeof(tga_devices[0]))) 194 return (10); /* need to return more than vga_pci here! */ 195 196 return (0); 197 } 198 199 void 200 tga_getdevconfig(memt, pc, tag, dc) 201 bus_space_tag_t memt; 202 pci_chipset_tag_t pc; 203 pcitag_t tag; 204 struct tga_devconfig *dc; 205 { 206 const struct tga_conf *tgac; 207 struct rasops_info *rip; 208 int cookie; 209 bus_size_t pcisize; 210 int i; 211 212 dc->dc_memt = memt; 213 214 dc->dc_pcitag = tag; 215 216 DPRINTF("tga_getdevconfig: Getting map info\n"); 217 /* XXX magic number */ 218 if (pci_mapreg_info(pc, tag, 0x10, 219 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 220 &dc->dc_pcipaddr, &pcisize, NULL)) 221 return; 222 223 DPRINTF("tga_getdevconfig: preparing to map\n"); 224 if (bus_space_map(memt, dc->dc_pcipaddr, pcisize, 225 BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_memh)) 226 return; 227 #ifdef __OpenBSD__ 228 dc->dc_vaddr = dc->dc_memh; 229 #else 230 dc->dc_vaddr = (vaddr_t) bus_space_vaddr(memt, dc->dc_memh); 231 #endif 232 DPRINTF("tga_getdevconfig: mapped\n"); 233 234 #ifdef __alpha__ 235 dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */ 236 #endif 237 DPRINTF("tga_getdevconfig: allocating subregion\n"); 238 bus_space_subregion(dc->dc_memt, dc->dc_memh, 239 TGA_MEM_CREGS, TGA_CREGS_SIZE, 240 &dc->dc_regs); 241 242 DPRINTF("tga_getdevconfig: going to identify\n"); 243 dc->dc_tga_type = tga_identify(dc); 244 245 DPRINTF("tga_getdevconfig: preparing to get config\n"); 246 tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type); 247 if (tgac == NULL) 248 return; 249 250 #if 0 251 /* XXX on the Alpha, pcisize = 4 * cspace_size. */ 252 if (tgac->tgac_cspace_size != pcisize) /* sanity */ 253 panic("tga_getdevconfig: memory size mismatch?"); 254 #endif 255 256 DPRINTF("tga_getdevconfig: get revno\n"); 257 switch (TGARREG(dc, TGA_REG_GREV) & 0xff) { 258 case 0x01: 259 case 0x02: 260 case 0x03: 261 case 0x04: 262 dc->dc_tga2 = 0; 263 break; 264 case 0x20: 265 case 0x21: 266 case 0x22: 267 dc->dc_tga2 = 1; 268 break; 269 default: 270 panic("tga_getdevconfig: TGA Revision not recognized"); 271 } 272 273 if (dc->dc_tga2) { 274 tga2_init(dc); 275 } 276 277 i = TGARREG(dc, TGA_REG_VHCR) & 0x1ff; 278 DPRINTF("tga_getdevconfig: TGA_REG_VHCR & 0x1ff = %d\n", i); 279 switch (i) { /* XXX */ 280 case 0: 281 dc->dc_wid = 8192; 282 break; 283 284 case 1: 285 dc->dc_wid = 8196; 286 break; 287 288 default: 289 dc->dc_wid = (TGARREG(dc, TGA_REG_VHCR) & 0x1ff) * 4; /* XXX */ 290 break; 291 } 292 293 DPRINTF("tga_getdevconfig: dc->dc_wid = %d\n", dc->dc_wid); 294 /* 295 * XXX XXX Turning off "odd" shouldn't be necessary, 296 * XXX XXX but I can't make X work with the weird size. 297 */ 298 DPRINTF("tga_getdevconfig: beginning magic incantation\n"); 299 if ((TGARREG(dc, TGA_REG_VHCR) & 0x00000001) != 0 && /* XXX */ 300 (TGARREG(dc, TGA_REG_VHCR) & 0x80000000) != 0) { /* XXX */ 301 TGAWREG(dc, TGA_REG_VHCR, 302 (TGARREG(dc, TGA_REG_VHCR) & ~0x80000001)); 303 dc->dc_wid -= 4; 304 } 305 306 dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8); 307 dc->dc_ht = (TGARREG(dc, TGA_REG_VVCR) & 0x7ff); /* XXX */ 308 DPRINTF("tga_getdevconfig: rowbytes = %d, tgac_phys_depth = %d\n" 309 " dc_wid = %d, dc_ht = %d\n", 310 dc->dc_rowbytes, dc->dc_tgaconf->tgac_phys_depth, 311 dc->dc_wid, dc->dc_ht); 312 313 /* XXX this seems to be what DEC does */ 314 DPRINTF("tga_getdevconfig: more magic\n"); 315 TGAWREG(dc, TGA_REG_CCBR, 0); 316 TGAWREG(dc, TGA_REG_VVBR, 1); 317 dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] + 318 1 * tgac->tgac_vvbr_units; 319 dc->dc_blanked = 1; 320 tga_unblank(dc); 321 322 DPRINTF("tga_getdevconfig: dc_videobase = 0x%016llx\n" 323 " dc_vaddr = 0x%016llx\n" 324 " tgac_dbuf[0] = %d\n" 325 " tgac_vvbr_units = %d\n", 326 dc->dc_videobase, dc->dc_vaddr, tgac->tgac_dbuf[0], 327 tgac->tgac_vvbr_units); 328 329 /* 330 * Set all bits in the pixel mask, to enable writes to all pixels. 331 * It seems that the console firmware clears some of them 332 * under some circumstances, which causes cute vertical stripes. 333 */ 334 DPRINTF("tga_getdevconfig: set pixel mask\n"); 335 TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff); 336 337 /* clear the screen */ 338 DPRINTF("tga_getdevconfig: clear screen\n"); 339 for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t)) 340 *(u_int32_t *)(dc->dc_videobase + i) = 0; 341 342 DPRINTF("tga_getdevconfig: raster ops\n"); 343 /* Initialize rasops descriptor */ 344 rip = &dc->dc_rinfo; 345 rip->ri_flg = RI_CENTER; 346 rip->ri_depth = tgac->tgac_phys_depth; 347 rip->ri_bits = (void *)dc->dc_videobase; 348 rip->ri_width = dc->dc_wid; 349 rip->ri_height = dc->dc_ht; 350 rip->ri_stride = dc->dc_rowbytes; 351 rip->ri_hw = dc; 352 353 if (tgac->tgac_phys_depth == 32) { 354 rip->ri_rnum = 8; 355 rip->ri_gnum = 8; 356 rip->ri_bnum = 8; 357 rip->ri_rpos = 16; 358 rip->ri_gpos = 8; 359 rip->ri_bpos = 0; 360 } 361 362 DPRINTF("tga_getdevconfig: wsfont_init\n"); 363 wsfont_init(); 364 if (rip->ri_width > 80*12) 365 /* High res screen, choose a big font */ 366 cookie = wsfont_find(NULL, 12, 0, 0); 367 else 368 /* lower res, choose a 8 pixel wide font */ 369 cookie = wsfont_find(NULL, 8, 0, 0); 370 if (cookie <= 0) 371 cookie = wsfont_find(NULL, 0, 0, 0); 372 if (cookie <= 0) { 373 printf("tga: no appropriate fonts.\n"); 374 return; 375 } 376 377 /* the accelerated tga_putchar() needs LSbit left */ 378 if (wsfont_lock(cookie, &rip->ri_font, 379 WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0) { 380 printf("tga: couldn't lock font\n"); 381 return; 382 } 383 rip->ri_wsfcookie = cookie; 384 /* fill screen size */ 385 rasops_init(rip, rip->ri_height / rip->ri_font->fontheight, 386 rip->ri_width / rip->ri_font->fontwidth); 387 388 /* add our accelerated functions */ 389 /* XXX shouldn't have to do this; rasops should leave non-NULL 390 * XXX entries alone. 391 */ 392 rip->ri_ops.copyrows = tga_copyrows; 393 rip->ri_ops.eraserows = tga_eraserows; 394 rip->ri_ops.erasecols = tga_erasecols; 395 rip->ri_ops.copycols = tga_copycols; 396 rip->ri_ops.putchar = tga_putchar; 397 398 tga_stdscreen.nrows = rip->ri_rows; 399 tga_stdscreen.ncols = rip->ri_cols; 400 tga_stdscreen.textops = &rip->ri_ops; 401 tga_stdscreen.capabilities = rip->ri_caps; 402 403 dc->dc_intrenabled = 0; 404 } 405 406 void 407 tgaattach(parent, self, aux) 408 struct device *parent, *self; 409 void *aux; 410 { 411 struct pci_attach_args *pa = aux; 412 struct tga_softc *sc = (struct tga_softc *)self; 413 struct wsemuldisplaydev_attach_args aa; 414 pci_intr_handle_t intrh; 415 const char *intrstr; 416 u_int8_t rev; 417 int console; 418 419 #if defined(__alpha__) 420 console = (pa->pa_tag == tga_console_dc.dc_pcitag); 421 #else 422 console = 0; 423 #endif 424 if (console) { 425 sc->sc_dc = &tga_console_dc; 426 sc->nscreens = 1; 427 } else { 428 sc->sc_dc = malloc(sizeof(struct tga_devconfig), M_DEVBUF, 429 M_NOWAIT | M_ZERO); 430 if (sc->sc_dc == NULL) 431 return; 432 tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag, 433 sc->sc_dc); 434 } 435 if (sc->sc_dc->dc_vaddr == 0) { 436 printf(": can't map mem space\n"); 437 return; 438 } 439 440 /* XXX say what's going on. */ 441 intrstr = NULL; 442 if (pci_intr_map(pa, &intrh)) { 443 printf(": can't map interrupt"); 444 return; 445 } 446 intrstr = pci_intr_string(pa->pa_pc, intrh); 447 sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr, 448 sc->sc_dc, sc->sc_dev.dv_xname); 449 if (sc->sc_intr == NULL) { 450 printf(": can't establish interrupt"); 451 if (intrstr != NULL) 452 printf("at %s", intrstr); 453 printf("\n"); 454 return; 455 } 456 457 rev = PCI_REVISION(pa->pa_class); 458 switch (rev) { 459 case 0x1: 460 case 0x2: 461 case 0x3: 462 printf(": DC21030 step %c", 'A' + rev - 1); 463 break; 464 case 0x20: 465 printf(": TGA2 abstract software model"); 466 break; 467 case 0x21: 468 case 0x22: 469 printf(": TGA2 pass %d", rev - 0x20); 470 break; 471 472 default: 473 printf("unknown stepping (0x%x)", rev); 474 break; 475 } 476 printf(", "); 477 478 /* 479 * Get RAMDAC function vectors and call the RAMDAC functions 480 * to allocate its private storage and pass that back to us. 481 */ 482 483 DPRINTF("tgaattach: Get RAMDAC functions\n"); 484 sc->sc_dc->dc_ramdac_funcs = sc->sc_dc->dc_tgaconf->ramdac_funcs(); 485 if (!sc->sc_dc->dc_tga2) { 486 DPRINTF("tgaattach: !sc->sc_dc->dc_tga2\n"); 487 DPRINTF("tgaattach: sc->sc_dc->dc_tgaconf->ramdac_funcs %s " 488 "bt485_funcs\n", 489 (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs) 490 ? "==" : "!="); 491 if (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs) 492 sc->sc_dc->dc_ramdac_cookie = 493 sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc, 494 tga_sched_update, tga_ramdac_wr, tga_ramdac_rd); 495 else 496 sc->sc_dc->dc_ramdac_cookie = 497 sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc, 498 tga_sched_update, tga_bt463_wr, tga_bt463_rd); 499 } else { 500 DPRINTF("tgaattach: sc->sc_dc->dc_tga2\n"); 501 sc->sc_dc->dc_ramdac_cookie = 502 sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc, 503 tga_sched_update, tga2_ramdac_wr, tga2_ramdac_rd); 504 505 /* XXX this is a bit of a hack, setting the dotclock here */ 506 if (sc->sc_dc->dc_tgaconf->ramdac_funcs != bt485_funcs) 507 (*sc->sc_dc->dc_ramdac_funcs->ramdac_set_dotclock) 508 (sc->sc_dc->dc_ramdac_cookie, 509 tga_getdotclock(sc->sc_dc)); 510 } 511 DPRINTF("tgaattach: sc->sc_dc->dc_ramdac_cookie = 0x%016llx\n", 512 sc->sc_dc->dc_ramdac_cookie); 513 /* 514 * Initialize the RAMDAC. Initialization includes disabling 515 * cursor, setting a sane colormap, etc. 516 */ 517 DPRINTF("tgaattach: Initializing RAMDAC.\n"); 518 (*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie); 519 TGAWREG(sc->sc_dc, TGA_REG_SISR, 0x00000001); /* XXX */ 520 521 if (sc->sc_dc->dc_tgaconf == NULL) { 522 printf("unknown board configuration\n"); 523 return; 524 } 525 printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name); 526 printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname, 527 sc->sc_dc->dc_wid, sc->sc_dc->dc_ht, 528 sc->sc_dc->dc_tgaconf->tgac_phys_depth, 529 sc->sc_dc->dc_ramdac_funcs->ramdac_name); 530 531 if (intrstr != NULL) 532 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, 533 intrstr); 534 535 aa.console = console; 536 aa.scrdata = &tga_screenlist; 537 aa.accessops = &tga_accessops; 538 aa.accesscookie = sc; 539 aa.defaultscreens = 0; 540 541 config_found(self, &aa, wsemuldisplaydevprint); 542 543 #ifdef __NetBSD__ 544 config_interrupts(self, tga_config_interrupts); 545 #else 546 tga_config_interrupts(self); 547 #endif 548 } 549 550 void 551 tga_config_interrupts(d) 552 struct device *d; 553 { 554 struct tga_softc *sc = (struct tga_softc *)d; 555 sc->sc_dc->dc_intrenabled = 1; 556 } 557 558 559 int 560 tga_ioctl(v, cmd, data, flag, p) 561 void *v; 562 u_long cmd; 563 caddr_t data; 564 int flag; 565 struct proc *p; 566 { 567 struct tga_softc *sc = v; 568 struct tga_devconfig *dc = sc->sc_dc; 569 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; 570 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; 571 572 switch (cmd) { 573 case WSDISPLAYIO_GTYPE: 574 *(u_int *)data = WSDISPLAY_TYPE_TGA; 575 break; 576 577 case WSDISPLAYIO_SMODE: 578 sc->sc_mode = *(u_int *)data; 579 switch (sc->sc_mode) { 580 case WSDISPLAYIO_MODE_DUMBFB: 581 /* in dump fb mode start the framebuffer at 0 */ 582 TGAWREG(dc, TGA_REG_VVBR, 0); 583 break; 584 default: 585 /* XXX it this useful, except for not breaking Xtga? */ 586 TGAWREG(dc, TGA_REG_VVBR, 1); 587 break; 588 } 589 break; 590 591 case WSDISPLAYIO_GINFO: 592 #define wsd_fbip ((struct wsdisplay_fbinfo *)data) 593 wsd_fbip->height = sc->sc_dc->dc_ht; 594 wsd_fbip->width = sc->sc_dc->dc_wid; 595 wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth; 596 wsd_fbip->stride = sc->sc_dc->dc_rowbytes; 597 wsd_fbip->offset = 0; 598 wsd_fbip->cmsize = 1024; /* XXX ??? */ 599 #undef wsd_fbip 600 break; 601 602 case WSDISPLAYIO_LINEBYTES: 603 *(u_int *)data = sc->sc_dc->dc_rowbytes; 604 break; 605 606 case WSDISPLAYIO_GETCMAP: 607 return (*dcrf->ramdac_get_cmap)(dcrc, 608 (struct wsdisplay_cmap *)data); 609 case WSDISPLAYIO_PUTCMAP: 610 return (*dcrf->ramdac_set_cmap)(dcrc, 611 (struct wsdisplay_cmap *)data); 612 613 case WSDISPLAYIO_SVIDEO: 614 case WSDISPLAYIO_GVIDEO: 615 break; 616 617 case WSDISPLAYIO_GCURPOS: 618 return (*dcrf->ramdac_get_curpos)(dcrc, 619 (struct wsdisplay_curpos *)data); 620 621 case WSDISPLAYIO_SCURPOS: 622 return (*dcrf->ramdac_set_curpos)(dcrc, 623 (struct wsdisplay_curpos *)data); 624 625 case WSDISPLAYIO_GCURMAX: 626 return (*dcrf->ramdac_get_curmax)(dcrc, 627 (struct wsdisplay_curpos *)data); 628 629 case WSDISPLAYIO_GCURSOR: 630 return (*dcrf->ramdac_get_cursor)(dcrc, 631 (struct wsdisplay_cursor *)data); 632 633 case WSDISPLAYIO_SCURSOR: 634 return (*dcrf->ramdac_set_cursor)(dcrc, 635 (struct wsdisplay_cursor *)data); 636 637 default: 638 return (-1); 639 } 640 641 return (0); 642 } 643 644 int 645 tga_sched_update(v, f) 646 void *v; 647 void (*f)(void *); 648 { 649 struct tga_devconfig *dc = v; 650 651 if (dc->dc_intrenabled) { 652 /* Arrange for f to be called at the next end-of-frame interrupt */ 653 dc->dc_ramdac_intr = f; 654 TGAWREG(dc, TGA_REG_SISR, 0x00010000); 655 } else { 656 /* Spin until the end-of-frame, then call f */ 657 TGAWREG(dc, TGA_REG_SISR, 0x00010001); 658 TGAREGWB(dc, TGA_REG_SISR, 1); 659 while ((TGARREG(dc, TGA_REG_SISR) & 0x00000001) == 0) 660 ; 661 f(dc->dc_ramdac_cookie); 662 TGAWREG(dc, TGA_REG_SISR, 0x00000001); 663 TGAREGWB(dc, TGA_REG_SISR, 1); 664 } 665 666 return 0; 667 } 668 669 int 670 tga_intr(v) 671 void *v; 672 { 673 struct tga_devconfig *dc = v; 674 struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie; 675 676 u_int32_t reg; 677 678 reg = TGARREG(dc, TGA_REG_SISR); 679 if (( reg & 0x00010001) != 0x00010001) { 680 /* Odd. We never set any of the other interrupt enables. */ 681 if ((reg & 0x1f) != 0) { 682 /* Clear the mysterious pending interrupts. */ 683 TGAWREG(dc, TGA_REG_SISR, (reg & 0x1f)); 684 TGAREGWB(dc, TGA_REG_SISR, 1); 685 /* This was our interrupt, even if we're puzzled as to why 686 * we got it. Don't make the interrupt handler think it 687 * was a stray. 688 */ 689 return -1; 690 } else { 691 return 0; 692 } 693 } 694 /* if we have something to do, do it */ 695 if (dc->dc_ramdac_intr) { 696 dc->dc_ramdac_intr(dcrc); 697 dc->dc_ramdac_intr = NULL; 698 } 699 TGAWREG(dc, TGA_REG_SISR, 0x00000001); 700 TGAREGWB(dc, TGA_REG_SISR, 1); 701 return (1); 702 } 703 704 paddr_t 705 tga_mmap(v, offset, prot) 706 void *v; 707 off_t offset; 708 int prot; 709 { 710 struct tga_softc *sc = v; 711 struct tga_devconfig *dc = sc->sc_dc; 712 713 if (offset >= dc->dc_tgaconf->tgac_cspace_size || offset < 0) 714 return -1; 715 716 if (sc->sc_mode == WSDISPLAYIO_MODE_DUMBFB) { 717 /* 718 * The framebuffer starts at the upper half of tga mem 719 */ 720 offset += dc->dc_tgaconf->tgac_cspace_size / 2; 721 } 722 #if defined(__alpha__) || defined(__mips__) 723 return (sc->sc_dc->dc_paddr + offset); 724 #else 725 return (-1); 726 #endif 727 } 728 729 int 730 tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp) 731 void *v; 732 const struct wsscreen_descr *type; 733 void **cookiep; 734 int *curxp, *curyp; 735 uint32_t *attrp; 736 { 737 struct tga_softc *sc = v; 738 uint32_t defattr; 739 740 if (sc->nscreens > 0) 741 return (ENOMEM); 742 743 *cookiep = &sc->sc_dc->dc_rinfo; /* one and only for now */ 744 *curxp = 0; 745 *curyp = 0; 746 sc->sc_dc->dc_rinfo.ri_ops.pack_attr(&sc->sc_dc->dc_rinfo, 747 0, 0, 0, &defattr); 748 *attrp = defattr; 749 sc->nscreens++; 750 return (0); 751 } 752 753 void 754 tga_free_screen(v, cookie) 755 void *v; 756 void *cookie; 757 { 758 struct tga_softc *sc = v; 759 760 if (sc->sc_dc == &tga_console_dc) 761 panic("tga_free_screen: console"); 762 763 sc->nscreens--; 764 } 765 766 int 767 tga_show_screen(v, cookie, waitok, cb, cbarg) 768 void *v; 769 void *cookie; 770 int waitok; 771 void (*cb)(void *, int, int); 772 void *cbarg; 773 { 774 775 return (0); 776 } 777 778 int 779 tga_load_font(void *v, void *emulcookie, struct wsdisplay_font *font) 780 { 781 struct tga_softc *sc = v; 782 struct tga_devconfig *dc = sc->sc_dc; 783 struct rasops_info *ri = &dc->dc_rinfo; 784 int wsfcookie; 785 struct wsdisplay_font *wsf; 786 const char *name; 787 788 /* 789 * We can't use rasops_load_font() directly, as we need to make 790 * sure that, when switching fonts, the font bits are set up in 791 * the correct bit order. 792 */ 793 794 if (font->data != NULL) 795 return rasops_load_font(ri, emulcookie, font); 796 797 /* allow an empty font name to revert to the initial font choice */ 798 name = font->name; 799 if (*name == '\0') 800 name = NULL; 801 802 wsfcookie = wsfont_find(name, ri->ri_font->fontwidth, 803 ri->ri_font->fontheight, 0); 804 if (wsfcookie < 0) { 805 wsfcookie = wsfont_find(name, 0, 0, 0); 806 if (wsfcookie < 0) 807 return ENOENT; 808 else 809 return EINVAL; 810 } 811 if (wsfont_lock(wsfcookie, &wsf, 812 WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0) 813 return EINVAL; 814 815 /* if (ri->ri_wsfcookie >= 0) */ 816 wsfont_unlock(ri->ri_wsfcookie); 817 ri->ri_wsfcookie = wsfcookie; 818 ri->ri_font = wsf; 819 ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride; 820 821 return 0; 822 } 823 824 int 825 tga_list_font(void *v, struct wsdisplay_font *font) 826 { 827 struct tga_softc *sc = v; 828 struct tga_devconfig *dc = sc->sc_dc; 829 struct rasops_info *ri = &dc->dc_rinfo; 830 831 return rasops_list_font(ri, font); 832 } 833 834 int 835 tga_cnattach(iot, memt, pc, bus, device, function) 836 bus_space_tag_t iot, memt; 837 pci_chipset_tag_t pc; 838 int bus, device, function; 839 { 840 struct tga_devconfig *dcp = &tga_console_dc; 841 uint32_t defattr; 842 843 tga_getdevconfig(memt, pc, 844 pci_make_tag(pc, bus, device, function), dcp); 845 846 /* sanity checks */ 847 if (dcp->dc_vaddr == 0) 848 panic("tga_console(%d, %d): can't map mem space", 849 device, function); 850 if (dcp->dc_tgaconf == NULL) 851 panic("tga_console(%d, %d): unknown board configuration", 852 device, function); 853 854 /* 855 * Initialize the RAMDAC but DO NOT allocate any private storage. 856 * Initialization includes disabling cursor, setting a sane 857 * colormap, etc. It will be reinitialized in tgaattach(). 858 */ 859 if (dcp->dc_tga2) { 860 if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs) 861 bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr, 862 tga2_ramdac_rd); 863 else 864 ibm561_cninit(dcp, tga_sched_update, tga2_ramdac_wr, 865 tga2_ramdac_rd, tga_getdotclock(dcp)); 866 } else { 867 if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs) 868 bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr, 869 tga_ramdac_rd); 870 else { 871 bt463_cninit(dcp, tga_sched_update, tga_bt463_wr, 872 tga_bt463_rd); 873 } 874 } 875 dcp->dc_rinfo.ri_ops.pack_attr(&dcp->dc_rinfo, 0, 0, 0, &defattr); 876 wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rinfo, 0, 0, defattr); 877 878 return(0); 879 } 880 881 /* 882 * Functions to blank and unblank the display. 883 */ 884 void 885 tga_burner(v, on, flags) 886 void *v; 887 u_int on, flags; 888 { 889 struct tga_softc *sc = v; 890 891 if (on) { 892 tga_unblank(sc->sc_dc); 893 } else { 894 tga_blank(sc->sc_dc); 895 } 896 } 897 898 void 899 tga_blank(dc) 900 struct tga_devconfig *dc; 901 { 902 903 if (!dc->dc_blanked) { 904 dc->dc_blanked = 1; 905 /* XXX */ 906 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | VVR_BLANK); 907 } 908 } 909 910 void 911 tga_unblank(dc) 912 struct tga_devconfig *dc; 913 { 914 915 if (dc->dc_blanked) { 916 dc->dc_blanked = 0; 917 /* XXX */ 918 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~VVR_BLANK); 919 } 920 } 921 922 /* 923 * Functions to manipulate the built-in cursor handing hardware. 924 */ 925 int 926 tga_builtin_set_cursor(dc, cursorp) 927 struct tga_devconfig *dc; 928 struct wsdisplay_cursor *cursorp; 929 { 930 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; 931 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; 932 u_int count, v; 933 int error; 934 935 v = cursorp->which; 936 if (v & WSDISPLAY_CURSOR_DOCMAP) { 937 error = dcrf->ramdac_check_curcmap(dcrc, cursorp); 938 if (error) 939 return (error); 940 } 941 if (v & WSDISPLAY_CURSOR_DOSHAPE) { 942 if ((u_int)cursorp->size.x != 64 || 943 (u_int)cursorp->size.y > 64) 944 return (EINVAL); 945 } 946 if (v & WSDISPLAY_CURSOR_DOHOT) /* not supported */ 947 return EINVAL; 948 949 /* parameters are OK; do it */ 950 if (v & WSDISPLAY_CURSOR_DOCUR) { 951 if (cursorp->enable) 952 /* XXX */ 953 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 0x04); 954 else 955 /* XXX */ 956 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~0x04); 957 } 958 if (v & WSDISPLAY_CURSOR_DOPOS) { 959 TGAWREG(dc, TGA_REG_CXYR, 960 ((cursorp->pos.y & 0xfff) << 12) | (cursorp->pos.x & 0xfff)); 961 } 962 if (v & WSDISPLAY_CURSOR_DOCMAP) { 963 /* can't fail. */ 964 dcrf->ramdac_set_curcmap(dcrc, cursorp); 965 } 966 if (v & WSDISPLAY_CURSOR_DOSHAPE) { 967 /* The cursor is 2 bits deep, and there is no mask */ 968 count = (cursorp->size.y * 64 * 2) / NBBY; 969 TGAWREG(dc, TGA_REG_CCBR, 970 (TGARREG(dc, TGA_REG_CCBR) & ~0xfc00) | (cursorp->size.y << 10)); 971 if ((error = copyin(cursorp->image,(char *)(dc->dc_vaddr + 972 (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), count)) != 0) 973 return (error); 974 } 975 return (0); 976 } 977 978 int 979 tga_builtin_get_cursor(dc, cursorp) 980 struct tga_devconfig *dc; 981 struct wsdisplay_cursor *cursorp; 982 { 983 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; 984 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; 985 int error; 986 u_int count; 987 988 cursorp->which = WSDISPLAY_CURSOR_DOALL & 989 ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP); 990 cursorp->enable = (TGARREG(dc, TGA_REG_VVVR) & 0x04) != 0; 991 cursorp->pos.x = TGARREG(dc, TGA_REG_CXYR) & 0xfff; 992 cursorp->pos.y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff; 993 cursorp->size.x = 64; 994 cursorp->size.y = (TGARREG(dc, TGA_REG_CCBR) >> 10) & 0x3f; 995 996 if (cursorp->image != NULL) { 997 count = (cursorp->size.y * 64 * 2) / NBBY; 998 error = copyout((char *)(dc->dc_vaddr + 999 (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), 1000 cursorp->image, count); 1001 if (error) 1002 return (error); 1003 /* No mask */ 1004 } 1005 error = dcrf->ramdac_get_curcmap(dcrc, cursorp); 1006 return (error); 1007 } 1008 1009 int 1010 tga_builtin_set_curpos(dc, curposp) 1011 struct tga_devconfig *dc; 1012 struct wsdisplay_curpos *curposp; 1013 { 1014 1015 TGAWREG(dc, TGA_REG_CXYR, 1016 ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff)); 1017 return (0); 1018 } 1019 1020 int 1021 tga_builtin_get_curpos(dc, curposp) 1022 struct tga_devconfig *dc; 1023 struct wsdisplay_curpos *curposp; 1024 { 1025 1026 curposp->x = TGARREG(dc, TGA_REG_CXYR) & 0xfff; 1027 curposp->y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff; 1028 return (0); 1029 } 1030 1031 int 1032 tga_builtin_get_curmax(dc, curposp) 1033 struct tga_devconfig *dc; 1034 struct wsdisplay_curpos *curposp; 1035 { 1036 1037 curposp->x = curposp->y = 64; 1038 return (0); 1039 } 1040 1041 /* 1042 * Copy columns (characters) in a row (line). 1043 */ 1044 int 1045 tga_copycols(id, row, srccol, dstcol, ncols) 1046 void *id; 1047 int row, srccol, dstcol, ncols; 1048 { 1049 struct rasops_info *ri = id; 1050 int y, srcx, dstx, nx; 1051 1052 y = ri->ri_font->fontheight * row; 1053 srcx = ri->ri_font->fontwidth * srccol; 1054 dstx = ri->ri_font->fontwidth * dstcol; 1055 nx = ri->ri_font->fontwidth * ncols; 1056 1057 tga_rop(ri, dstx, y, nx, ri->ri_font->fontheight, ri, srcx, y); 1058 1059 return 0; 1060 } 1061 1062 /* 1063 * Copy rows (lines). 1064 */ 1065 int 1066 tga_copyrows(id, srcrow, dstrow, nrows) 1067 void *id; 1068 int srcrow, dstrow, nrows; 1069 { 1070 struct rasops_info *ri = id; 1071 int srcy, dsty, ny; 1072 1073 srcy = ri->ri_font->fontheight * srcrow; 1074 dsty = ri->ri_font->fontheight * dstrow; 1075 ny = ri->ri_font->fontheight * nrows; 1076 1077 tga_rop(ri, 0, dsty, ri->ri_emuwidth, ny, ri, 0, srcy); 1078 1079 return 0; 1080 } 1081 1082 /* 1083 * Generic TGA raster op. 1084 * This covers all possible raster ops, and 1085 * clips the sizes and all of that. 1086 */ 1087 int 1088 tga_rop(dst, dx, dy, w, h, src, sx, sy) 1089 struct rasops_info *dst; 1090 int dx, dy, w, h; 1091 struct rasops_info *src; 1092 int sx, sy; 1093 { 1094 if (dst == NULL || src == NULL) 1095 return -1; 1096 1097 /* Clip against src */ 1098 if (sx < 0) { 1099 w += sx; 1100 sx = 0; 1101 } 1102 if (sy < 0) { 1103 h += sy; 1104 sy = 0; 1105 } 1106 if (sx + w > src->ri_emuwidth) 1107 w = src->ri_emuwidth - sx; 1108 if (sy + h > src->ri_emuheight) 1109 h = src->ri_emuheight - sy; 1110 1111 /* Clip against dst. We modify src regardless of using it, 1112 * since it really doesn't matter. 1113 */ 1114 if (dx < 0) { 1115 w += dx; 1116 sx -= dx; 1117 dx = 0; 1118 } 1119 if (dy < 0) { 1120 h += dy; 1121 sy -= dy; 1122 dy = 0; 1123 } 1124 if (dx + w > dst->ri_emuwidth) 1125 w = dst->ri_emuwidth - dx; 1126 if (dy + h > dst->ri_emuheight) 1127 h = dst->ri_emuheight - dy; 1128 if (w <= 0 || h <= 0) 1129 return 0; /* Vacuously true; */ 1130 1131 return tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy); 1132 } 1133 1134 1135 1136 /* 1137 * Video to Video raster ops. 1138 * This function deals with all raster ops that have a src and dst 1139 * that are on the card. 1140 */ 1141 int 1142 tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy) 1143 struct rasops_info *dst; 1144 int dx, dy, w, h; 1145 struct rasops_info *src; 1146 int sx, sy; 1147 { 1148 struct tga_devconfig *dc = (struct tga_devconfig *)dst->ri_hw; 1149 int srcb, dstb, tga_srcb, tga_dstb; 1150 int x, y, wb; 1151 int xstart, xend, xdir; 1152 int ystart, yend, ydir, yinc; 1153 int xleft, lastx, lastleft; 1154 int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units; 1155 1156 /* 1157 * I don't yet want to deal with unaligned guys, really. And we don't 1158 * deal with copies from one card to another. 1159 */ 1160 if (dx % 8 != 0 || sx % 8 != 0 || src != dst) { 1161 /* XXX Punt! */ 1162 /* XXX should never happen, since it's only being used to 1163 * XXX copy 8-pixel-wide characters. 1164 */ 1165 return -1; 1166 } 1167 1168 wb = w * (dst->ri_depth / 8); 1169 if (sy >= dy) { 1170 ystart = 0; 1171 yend = h; 1172 ydir = 1; 1173 } else { 1174 ystart = h; 1175 yend = 0; 1176 ydir = -1; 1177 } 1178 if (sx >= dx) { /* moving to the left */ 1179 xstart = 0; 1180 xend = w * (dst->ri_depth / 8) - 4; 1181 xdir = 1; 1182 } else { /* moving to the right */ 1183 xstart = wb - ( wb >= 4*64 ? 4*64 : wb >= 64 ? 64 : 4 ); 1184 xend = 0; 1185 xdir = -1; 1186 } 1187 #define XINC4 4 1188 #define XINC64 64 1189 #define XINC256 (64*4) 1190 yinc = ydir * dst->ri_stride; 1191 ystart *= dst->ri_stride; 1192 yend *= dst->ri_stride; 1193 1194 srcb = sy * src->ri_stride + sx * (src->ri_depth/8); 1195 dstb = dy * dst->ri_stride + dx * (dst->ri_depth/8); 1196 tga_srcb = offset + (sy + src->ri_yorigin) * src->ri_stride + 1197 (sx + src->ri_xorigin) * (src->ri_depth/8); 1198 tga_dstb = offset + (dy + dst->ri_yorigin) * dst->ri_stride + 1199 (dx + dst->ri_xorigin) * (dst->ri_depth/8); 1200 1201 TGAWALREG(dc, TGA_REG_GMOR, 3, 0x0007); /* Copy mode */ 1202 TGAWALREG(dc, TGA_REG_GOPR, 3, 0x0003); /* SRC */ 1203 1204 /* 1205 * we have 3 sizes of pixels to move in X direction: 1206 * 4 * 64 (unrolled TGA ops) 1207 * 64 (single TGA op) 1208 * 4 (CPU, using long word) 1209 */ 1210 1211 if (xdir == 1) { /* move to the left */ 1212 1213 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { 1214 1215 /* 4*64 byte chunks */ 1216 for (xleft = wb, x = xstart; 1217 x <= xend && xleft >= 4*64; 1218 x += XINC256, xleft -= XINC256) { 1219 1220 /* XXX XXX Eight writes to different addresses should fill 1221 * XXX XXX up the write buffers on 21064 and 21164 chips, 1222 * XXX XXX but later CPUs might have larger write buffers which 1223 * XXX XXX require further unrolling of this loop, or the 1224 * XXX XXX insertion of memory barriers. 1225 */ 1226 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64); 1227 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64); 1228 TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 1 * 64); 1229 TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 1 * 64); 1230 TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 2 * 64); 1231 TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 2 * 64); 1232 TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 3 * 64); 1233 TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 3 * 64); 1234 } 1235 1236 /* 64 byte chunks */ 1237 for ( ; x <= xend && xleft >= 64; 1238 x += XINC64, xleft -= XINC64) { 1239 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64); 1240 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64); 1241 } 1242 lastx = x; lastleft = xleft; /* remember for CPU loop */ 1243 1244 } 1245 TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */ 1246 TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */ 1247 1248 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { 1249 /* 4 byte granularity */ 1250 for (x = lastx, xleft = lastleft; 1251 x <= xend && xleft >= 4; 1252 x += XINC4, xleft -= XINC4) { 1253 *(uint32_t *)(dst->ri_bits + dstb + y + x) = 1254 *(uint32_t *)(dst->ri_bits + srcb + y + x); 1255 } 1256 } 1257 } 1258 else { /* above move to the left, below move to the right */ 1259 1260 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { 1261 1262 /* 4*64 byte chunks */ 1263 for (xleft = wb, x = xstart; 1264 x >= xend && xleft >= 4*64; 1265 x -= XINC256, xleft -= XINC256) { 1266 1267 /* XXX XXX Eight writes to different addresses should fill 1268 * XXX XXX up the write buffers on 21064 and 21164 chips, 1269 * XXX XXX but later CPUs might have larger write buffers which 1270 * XXX XXX require further unrolling of this loop, or the 1271 * XXX XXX insertion of memory barriers. 1272 */ 1273 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 3 * 64); 1274 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 3 * 64); 1275 TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 2 * 64); 1276 TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 2 * 64); 1277 TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 1 * 64); 1278 TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 1 * 64); 1279 TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 0 * 64); 1280 TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 0 * 64); 1281 } 1282 1283 if (xleft) x += XINC256 - XINC64; 1284 1285 /* 64 byte chunks */ 1286 for ( ; x >= xend && xleft >= 64; 1287 x -= XINC64, xleft -= XINC64) { 1288 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64); 1289 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64); 1290 } 1291 if (xleft) x += XINC64 - XINC4; 1292 lastx = x; lastleft = xleft; /* remember for CPU loop */ 1293 } 1294 TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */ 1295 TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */ 1296 1297 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { 1298 /* 4 byte granularity */ 1299 for (x = lastx, xleft = lastleft; 1300 x >= xend && xleft >= 4; 1301 x -= XINC4, xleft -= XINC4) { 1302 *(uint32_t *)(dst->ri_bits + dstb + y + x) = 1303 *(uint32_t *)(dst->ri_bits + srcb + y + x); 1304 } 1305 } 1306 } 1307 return 0; 1308 } 1309 1310 1311 int 1312 tga_putchar(c, row, col, uc, attr) 1313 void *c; 1314 int row, col; 1315 u_int uc; 1316 uint32_t attr; 1317 { 1318 struct rasops_info *ri = c; 1319 struct tga_devconfig *dc = ri->ri_hw; 1320 int fs, height, width; 1321 int fg, bg, ul; 1322 u_char *fr; 1323 int32_t *rp; 1324 1325 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 1326 1327 height = ri->ri_font->fontheight; 1328 width = ri->ri_font->fontwidth; 1329 1330 uc -= ri->ri_font->firstchar; 1331 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; 1332 fs = ri->ri_font->stride; 1333 1334 /* Set foreground and background color. XXX memoize this somehow? 1335 * The rasops code has already expanded the color entry to 32 bits 1336 * for us, even for 8-bit displays, so we don't have to do anything. 1337 */ 1338 ri->ri_ops.unpack_attr(c, attr, &fg, &bg, &ul); 1339 TGAWREG(dc, TGA_REG_GFGR, ri->ri_devcmap[fg]); 1340 TGAWREG(dc, TGA_REG_GBGR, ri->ri_devcmap[bg]); 1341 1342 /* Set raster operation to "copy"... */ 1343 if (ri->ri_depth == 8) 1344 TGAWREG(dc, TGA_REG_GOPR, 0x3); 1345 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */ 1346 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8)); 1347 1348 /* Set which pixels we're drawing (of a possible 32). */ 1349 TGAWREG(dc, TGA_REG_GPXR_P, (1 << width) - 1); 1350 1351 /* Set drawing mode to opaque stipple. */ 1352 TGAWREG(dc, TGA_REG_GMOR, 0x1); 1353 1354 /* Insert write barrier before actually sending data */ 1355 /* XXX Abuses the fact that there is only one write barrier on Alphas */ 1356 TGAREGWB(dc, TGA_REG_GMOR, 1); 1357 1358 while (height--) { 1359 /* The actual stipple write */ 1360 *rp = fr[0] | (fr[1] << 8) | (fr[2] << 16) | (fr[3] << 24); 1361 1362 fr += fs; 1363 rp = (int32_t *)((caddr_t)rp + ri->ri_stride); 1364 } 1365 1366 /* Do underline */ 1367 if (ul) { 1368 rp = (int32_t *)((caddr_t)rp - (ri->ri_stride << 1)); 1369 *rp = 0xffffffff; 1370 } 1371 1372 /* Set graphics mode back to normal. */ 1373 TGAWREG(dc, TGA_REG_GMOR, 0); 1374 TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff); 1375 1376 return 0; 1377 } 1378 1379 int 1380 tga_eraserows(c, row, num, attr) 1381 void *c; 1382 int row, num; 1383 uint32_t attr; 1384 { 1385 struct rasops_info *ri = c; 1386 struct tga_devconfig *dc = ri->ri_hw; 1387 int32_t color, lines, pixels; 1388 int fg, bg; 1389 int32_t *rp; 1390 1391 ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL); 1392 color = ri->ri_devcmap[bg]; 1393 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale); 1394 lines = num * ri->ri_font->fontheight; 1395 pixels = ri->ri_emuwidth - 1; 1396 1397 /* Set fill color in block-color registers */ 1398 TGAWREG(dc, TGA_REG_GBCR0, color); 1399 TGAWREG(dc, TGA_REG_GBCR1, color); 1400 if (ri->ri_depth != 8) { 1401 TGAWREG(dc, TGA_REG_GBCR2, color); 1402 TGAWREG(dc, TGA_REG_GBCR3, color); 1403 TGAWREG(dc, TGA_REG_GBCR4, color); 1404 TGAWREG(dc, TGA_REG_GBCR5, color); 1405 TGAWREG(dc, TGA_REG_GBCR6, color); 1406 TGAWREG(dc, TGA_REG_GBCR7, color); 1407 } 1408 1409 /* Set raster operation to "copy"... */ 1410 if (ri->ri_depth == 8) 1411 TGAWREG(dc, TGA_REG_GOPR, 0x3); 1412 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */ 1413 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8)); 1414 1415 /* Set which pixels we're drawing (of a possible 32). */ 1416 TGAWREG(dc, TGA_REG_GDAR, 0xffffffff); 1417 1418 /* Set drawing mode to block fill. */ 1419 TGAWREG(dc, TGA_REG_GMOR, 0x2d); 1420 1421 /* Insert write barrier before actually sending data */ 1422 /* XXX Abuses the fact that there is only one write barrier on Alphas */ 1423 TGAREGWB(dc, TGA_REG_GMOR, 1); 1424 1425 while (lines--) { 1426 *rp = pixels; 1427 rp = (int32_t *)((caddr_t)rp + ri->ri_stride); 1428 } 1429 1430 /* Set graphics mode back to normal. */ 1431 TGAWREG(dc, TGA_REG_GMOR, 0); 1432 1433 return 0; 1434 } 1435 1436 int 1437 tga_erasecols(c, row, col, num, attr) 1438 void *c; 1439 int row, col, num; 1440 uint32_t attr; 1441 { 1442 struct rasops_info *ri = c; 1443 struct tga_devconfig *dc = ri->ri_hw; 1444 int32_t color, lines, pixels; 1445 int fg, bg; 1446 int32_t *rp; 1447 1448 ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL); 1449 color = ri->ri_devcmap[bg]; 1450 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 1451 lines = ri->ri_font->fontheight; 1452 pixels = (num * ri->ri_font->fontwidth) - 1; 1453 1454 /* Set fill color in block-color registers */ 1455 TGAWREG(dc, TGA_REG_GBCR0, color); 1456 TGAWREG(dc, TGA_REG_GBCR1, color); 1457 if (ri->ri_depth != 8) { 1458 TGAWREG(dc, TGA_REG_GBCR2, color); 1459 TGAWREG(dc, TGA_REG_GBCR3, color); 1460 TGAWREG(dc, TGA_REG_GBCR4, color); 1461 TGAWREG(dc, TGA_REG_GBCR5, color); 1462 TGAWREG(dc, TGA_REG_GBCR6, color); 1463 TGAWREG(dc, TGA_REG_GBCR7, color); 1464 } 1465 1466 /* Set raster operation to "copy"... */ 1467 if (ri->ri_depth == 8) 1468 TGAWREG(dc, TGA_REG_GOPR, 0x3); 1469 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */ 1470 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8)); 1471 1472 /* Set which pixels we're drawing (of a possible 32). */ 1473 TGAWREG(dc, TGA_REG_GDAR, 0xffffffff); 1474 1475 /* Set drawing mode to block fill. */ 1476 TGAWREG(dc, TGA_REG_GMOR, 0x2d); 1477 1478 /* Insert write barrier before actually sending data */ 1479 /* XXX Abuses the fact that there is only one write barrier on Alphas */ 1480 TGAREGWB(dc, TGA_REG_GMOR, 1); 1481 1482 while (lines--) { 1483 *rp = pixels; 1484 rp = (int32_t *)((caddr_t)rp + ri->ri_stride); 1485 } 1486 1487 /* Set graphics mode back to normal. */ 1488 TGAWREG(dc, TGA_REG_GMOR, 0); 1489 1490 return 0; 1491 } 1492 1493 1494 void 1495 tga_ramdac_wr(v, btreg, val) 1496 void *v; 1497 u_int btreg; 1498 u_int8_t val; 1499 { 1500 struct tga_devconfig *dc = v; 1501 1502 if (btreg > BT485_REG_MAX) 1503 panic("tga_ramdac_wr: reg %d out of range", btreg); 1504 1505 TGAWREG(dc, TGA_REG_EPDR, (btreg << 9) | (0 << 8 ) | val); /* XXX */ 1506 TGAREGWB(dc, TGA_REG_EPDR, 1); 1507 } 1508 1509 void 1510 tga2_ramdac_wr(v, btreg, val) 1511 void *v; 1512 u_int btreg; 1513 u_int8_t val; 1514 { 1515 struct tga_devconfig *dc = v; 1516 bus_space_handle_t ramdac; 1517 1518 if (btreg > BT485_REG_MAX) 1519 panic("tga_ramdac_wr: reg %d out of range", btreg); 1520 1521 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC + 1522 (0xe << 12) + (btreg << 8), 4, &ramdac); 1523 bus_space_write_4(dc->dc_memt, ramdac, 0, val & 0xff); 1524 bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE); 1525 } 1526 1527 u_int8_t 1528 tga_bt463_rd(v, btreg) 1529 void *v; 1530 u_int btreg; 1531 { 1532 struct tga_devconfig *dc = v; 1533 tga_reg_t rdval; 1534 1535 /* 1536 * Strobe CE# (high->low->high) since status and data are latched on 1537 * the falling and rising edges (respectively) of this active-low signal. 1538 */ 1539 1540 TGAREGWB(dc, TGA_REG_EPSR, 1); 1541 TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1); 1542 TGAREGWB(dc, TGA_REG_EPSR, 1); 1543 TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 0); 1544 1545 TGAREGRB(dc, TGA_REG_EPSR, 1); 1546 1547 rdval = TGARREG(dc, TGA_REG_EPDR); 1548 TGAREGWB(dc, TGA_REG_EPSR, 1); 1549 TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1); 1550 1551 return (rdval >> 16) & 0xff; 1552 } 1553 1554 void 1555 tga_bt463_wr(v, btreg, val) 1556 void *v; 1557 u_int btreg; 1558 u_int8_t val; 1559 { 1560 struct tga_devconfig *dc = v; 1561 1562 /* 1563 * In spite of the 21030 documentation, to set the MPU bus bits for 1564 * a write, you set them in the upper bits of EPDR, not EPSR. 1565 */ 1566 1567 /* 1568 * Strobe CE# (high->low->high) since status and data are latched on 1569 * the falling and rising edges of this active-low signal. 1570 */ 1571 1572 TGAREGWB(dc, TGA_REG_EPDR, 1); 1573 TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val); 1574 TGAREGWB(dc, TGA_REG_EPDR, 1); 1575 TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x000 | val); 1576 TGAREGWB(dc, TGA_REG_EPDR, 1); 1577 TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val); 1578 1579 } 1580 1581 u_int8_t 1582 tga_ramdac_rd(v, btreg) 1583 void *v; 1584 u_int btreg; 1585 { 1586 struct tga_devconfig *dc = v; 1587 tga_reg_t rdval; 1588 1589 if (btreg > BT485_REG_MAX) 1590 panic("tga_ramdac_rd: reg %d out of range", btreg); 1591 1592 TGAWREG(dc, TGA_REG_EPSR, (btreg << 1) | 0x1); /* XXX */ 1593 TGAREGWB(dc, TGA_REG_EPSR, 1); 1594 1595 rdval = TGARREG(dc, TGA_REG_EPDR); 1596 return (rdval >> 16) & 0xff; /* XXX */ 1597 } 1598 1599 u_int8_t 1600 tga2_ramdac_rd(v, btreg) 1601 void *v; 1602 u_int btreg; 1603 { 1604 struct tga_devconfig *dc = v; 1605 bus_space_handle_t ramdac; 1606 u_int8_t retval; 1607 1608 if (btreg > BT485_REG_MAX) 1609 panic("tga_ramdac_rd: reg %d out of range", btreg); 1610 1611 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC + 1612 (0xe << 12) + (btreg << 8), 4, &ramdac); 1613 retval = bus_space_read_4(dc->dc_memt, ramdac, 0) & 0xff; 1614 bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_READ); 1615 return retval; 1616 } 1617 1618 #include <dev/ic/decmonitors.c> 1619 void tga2_ics9110_wr( 1620 struct tga_devconfig *dc, 1621 int dotclock 1622 ); 1623 1624 struct monitor *tga_getmonitor(struct tga_devconfig *dc); 1625 1626 void 1627 tga2_init(dc) 1628 struct tga_devconfig *dc; 1629 { 1630 struct monitor *m = tga_getmonitor(dc); 1631 1632 1633 /* Deal with the dot clocks. 1634 */ 1635 if (dc->dc_tga_type == TGA_TYPE_POWERSTORM_4D20) { 1636 /* Set this up as a reference clock for the 1637 * ibm561's PLL. 1638 */ 1639 tga2_ics9110_wr(dc, 14300000); 1640 /* XXX Can't set up the dotclock properly, until such time 1641 * as the RAMDAC is configured. 1642 */ 1643 } else { 1644 /* otherwise the ics9110 is our clock. */ 1645 tga2_ics9110_wr(dc, m->dotclock); 1646 } 1647 #if 0 1648 TGAWREG(dc, TGA_REG_VHCR, 1649 ((m->hbp / 4) << 21) | 1650 ((m->hsync / 4) << 14) | 1651 (((m->hfp - 4) / 4) << 9) | 1652 ((m->cols + 4) / 4)); 1653 #else 1654 TGAWREG(dc, TGA_REG_VHCR, 1655 ((m->hbp / 4) << 21) | 1656 ((m->hsync / 4) << 14) | 1657 (((m->hfp) / 4) << 9) | 1658 ((m->cols) / 4)); 1659 #endif 1660 TGAWREG(dc, TGA_REG_VVCR, 1661 (m->vbp << 22) | 1662 (m->vsync << 16) | 1663 (m->vfp << 11) | 1664 (m->rows)); 1665 TGAWREG(dc, TGA_REG_VVBR, 1); 1666 TGAREGRWB(dc, TGA_REG_VHCR, 3); 1667 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 1); 1668 TGAREGRWB(dc, TGA_REG_VVVR, 1); 1669 TGAWREG(dc, TGA_REG_GPMR, 0xffffffff); 1670 TGAREGRWB(dc, TGA_REG_GPMR, 1); 1671 } 1672 1673 void 1674 tga2_ics9110_wr(dc, dotclock) 1675 struct tga_devconfig *dc; 1676 int dotclock; 1677 { 1678 bus_space_handle_t clock; 1679 u_int32_t valU; 1680 int N, M, R, V, X; 1681 int i; 1682 1683 switch (dotclock) { 1684 case 130808000: 1685 N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break; 1686 case 119840000: 1687 N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break; 1688 case 108180000: 1689 N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break; 1690 case 103994000: 1691 N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break; 1692 case 175000000: 1693 N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break; 1694 case 75000000: 1695 N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break; 1696 case 74000000: 1697 N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break; 1698 case 69000000: 1699 N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break; 1700 case 65000000: 1701 N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break; 1702 case 50000000: 1703 N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break; 1704 case 40000000: 1705 N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break; 1706 case 31500000: 1707 N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break; 1708 case 25175000: 1709 N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break; 1710 case 135000000: 1711 N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break; 1712 case 110000000: 1713 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break; 1714 case 202500000: 1715 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break; 1716 case 14300000: /* this one is just a ref clock */ 1717 N = 0x03; M = 0x03; V = 0x1; X = 0x1; R = 0x3; break; 1718 default: 1719 panic("unrecognized clock rate %d", dotclock); 1720 } 1721 1722 /* XXX -- hard coded, bad */ 1723 valU = N | ( M << 7 ) | (V << 14); 1724 valU |= (X << 15) | (R << 17); 1725 valU |= 0x17 << 19; 1726 1727 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV + 1728 TGA2_MEM_CLOCK + (0xe << 12), 4, &clock); /* XXX */ 1729 1730 for (i = 24; i > 0; i--) { 1731 u_int32_t writeval; 1732 1733 writeval = valU & 0x1; 1734 if (i == 1) 1735 writeval |= 0x2; 1736 valU >>= 1; 1737 bus_space_write_4(dc->dc_memt, clock, 0, writeval); 1738 bus_space_barrier(dc->dc_memt, clock, 0, 4, BUS_SPACE_BARRIER_WRITE); 1739 } 1740 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV + 1741 TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11) + (0x1 << 11), 4, 1742 &clock); /* XXX */ 1743 bus_space_write_4(dc->dc_memt, clock, 0, 0x0); 1744 bus_space_barrier(dc->dc_memt, clock, 0, 0, BUS_SPACE_BARRIER_WRITE); 1745 } 1746 1747 struct monitor * 1748 tga_getmonitor(dc) 1749 struct tga_devconfig *dc; 1750 { 1751 return &decmonitors[(~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f]; 1752 } 1753 1754 unsigned 1755 tga_getdotclock(dc) 1756 struct tga_devconfig *dc; 1757 { 1758 return tga_getmonitor(dc)->dotclock; 1759 } 1760