1 /* $NetBSD: grfabs_et.c,v 1.25 2006/03/29 18:05:57 thomas Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Leo Weppelman. 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 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Leo Weppelman. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Most of the lower-level et4000 stuff was derived from: 35 * .../amiga/dev/grf_et.c 36 * 37 * Which was copyrighted by: 38 * Copyright (c) 1996 Tobias Abt 39 * Copyright (c) 1995 Ezra Story 40 * Copyright (c) 1995 Kari Mettinen 41 * Copyright (c) 1994 Markus Wild 42 * Copyright (c) 1994 Lutz Vieweg 43 * 44 * Thanks guys! 45 * 46 */ 47 48 #include <sys/cdefs.h> 49 __KERNEL_RCSID(0, "$NetBSD: grfabs_et.c,v 1.25 2006/03/29 18:05:57 thomas Exp $"); 50 51 #include <sys/param.h> 52 #include <sys/queue.h> 53 #include <sys/malloc.h> 54 #include <sys/device.h> 55 #include <sys/systm.h> 56 57 #include <uvm/uvm_extern.h> 58 59 /* 60 * For PCI probing... 61 */ 62 #include <dev/pci/pcireg.h> 63 #include <dev/pci/pcivar.h> 64 #include <dev/pci/pcidevs.h> 65 66 #include <machine/iomap.h> 67 #include <machine/video.h> 68 #include <machine/mfp.h> 69 #include <machine/cpu.h> 70 #include <atari/atari/device.h> 71 #include <atari/dev/grfioctl.h> 72 #include <atari/dev/grfabs_reg.h> 73 #include <atari/dev/grfabs_et.h> 74 #include <atari/dev/grf_etreg.h> 75 76 #define SAVEBUF_SIZE (32*1024 + sizeof(save_area_t)) 77 78 /* 79 * Allow a 16Kb io-region and a 4MB frame buffer to be mapped. This 80 * is more or less required by the XFree server. 81 */ 82 #define REG_MAPPABLE (16 * 1024) 83 #define FRAME_MAPPABLE (4 * 1024 * 1024) 84 #define VGA_MAPPABLE (128 * 1024) 85 #define VGA_BASE 0xa0000 86 87 /* 88 * Linear memory base, near the end of the pci area 89 */ 90 #define PCI_LINMEMBASE 0x0e000000 91 92 /* 93 * Function decls 94 */ 95 static void init_view __P((view_t *, bmap_t *, dmode_t *, box_t *)); 96 static colormap_t *alloc_colormap __P((dmode_t *)); 97 static void et_display_view __P((view_t *)); 98 static view_t *et_alloc_view __P((dmode_t *, dimen_t *, u_char)); 99 static void et_free_view __P((view_t *)); 100 static void et_loadmode __P((struct grfvideo_mode *, et_sv_reg_t *)); 101 static void et_remove_view __P((view_t *)); 102 static void et_save_view __P((view_t *)); 103 static int et_use_colormap __P((view_t *, colormap_t *)); 104 105 /* 106 * Our function switch table 107 */ 108 struct grfabs_sw et_vid_sw = { 109 et_display_view, 110 et_alloc_view, 111 et_free_view, 112 et_remove_view, 113 et_save_view, 114 et_use_colormap 115 }; 116 117 static struct grfvideo_mode hw_modes[] = { 118 { 119 0, "", 22450000, /* num, descr, pix-clock */ 120 640, 400, 4, /* width, height, depth */ 121 632/8, 672/8, 688/8, 808/8, 768/8,/* HBS, HBE, HSS, HSE, HT */ 122 399, 450, 408, 413, 449 /* VBS, VBE, VSS, VSE, VT */ 123 }, 124 { 125 0, "", 25175000, /* num, descr, pix-clock */ 126 640, 480, 4, /* width, height, depth */ 127 632/8, 672/8, 688/8, 752/8, 752/8,/* HBS, HBE, HSS, HSE, HT */ 128 481, 522, 490, 498, 522 /* VBS, VBE, VSS, VSE, VT */ 129 } 130 }; 131 132 static dmode_t vid_modes[] = { 133 { { NULL, NULL }, 134 "640x400", { 640, 400 }, 1, (void*)&hw_modes[0], &et_vid_sw }, 135 { { NULL, NULL }, 136 "640x480", { 640, 480 }, 1, (void*)&hw_modes[1], &et_vid_sw }, 137 { { NULL, NULL }, NULL, } 138 }; 139 140 #define ET_NUMCLOCKS 32 141 142 static u_int et_clockfreqs[ET_NUMCLOCKS] = { 143 6293750, 7080500, 7875000, 8125000, 144 9000000, 9375000, 10000000, 11225000, 145 12587500, 14161000, 15750000, 16250000, 146 18000000, 18750000, 20000000, 22450000, 147 25175000, 28322000, 31500000, 32500000, 148 36000000, 37500000, 40000000, 44900000, 149 50350000, 56644000, 63000000, 65000000, 150 72000000, 75000000, 80000000, 89800000 151 }; 152 153 static bmap_t con_bm; /* XXX */ 154 155 struct grfabs_et_priv { 156 pcitag_t pci_tag; 157 volatile caddr_t regkva; 158 volatile caddr_t memkva; 159 u_int linbase; 160 int regsz; 161 int memsz; 162 int board_type; 163 } et_priv; 164 165 /* 166 * Board types: 167 */ 168 #define BT_ET4000 1 169 #define BT_ET6000 2 170 171 /* 172 * XXX: called from ite console init routine. 173 * Initialize list of posible video modes. 174 */ 175 void 176 et_probe_video(modelp) 177 MODES *modelp; 178 { 179 dmode_t *dm; 180 int i; 181 182 for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) { 183 LIST_INSERT_HEAD(modelp, dm, link); 184 } 185 } 186 187 static void 188 et_display_view(v) 189 view_t *v; 190 { 191 dmode_t *dm = v->mode; 192 bmap_t *bm = v->bitmap; 193 int sv_size; 194 u_short *src, *dst; 195 save_area_t *sa; 196 197 if (dm->current_view && (dm->current_view != v)) { 198 /* 199 * Mark current view for this mode as no longer displayed 200 */ 201 dm->current_view->flags &= ~VF_DISPLAY; 202 } 203 dm->current_view = v; 204 v->flags |= VF_DISPLAY; 205 206 if ((sa = (save_area_t*)v->save_area) == NULL) 207 return; /* XXX: Can't happen.... */ 208 209 /* 210 * Restore register settings and turn the plane pointer 211 * to the card-memory 212 */ 213 et_hwrest(&sa->sv_regs); 214 bm->plane = et_priv.memkva; 215 216 et_use_colormap(v, v->colormap); 217 218 /* 219 * Copy the backing store to card-memory 220 */ 221 sv_size = sa->fb_size; 222 src = sa->sv_fb; 223 dst = (u_short *)bm->plane; 224 while (sv_size--) 225 *dst++ = *src++; 226 } 227 228 void 229 et_remove_view(v) 230 view_t *v; 231 { 232 dmode_t *mode = v->mode; 233 234 if (mode->current_view == v) { 235 #if 0 236 if (v->flags & VF_DISPLAY) 237 panic("Cannot shutdown display"); /* XXX */ 238 #endif 239 mode->current_view = NULL; 240 } 241 v->flags &= ~VF_DISPLAY; 242 } 243 244 void 245 et_save_view(v) 246 view_t *v; 247 { 248 bmap_t *bm = v->bitmap; 249 u_char font_height; 250 int sv_size; 251 u_short *src, *dst; 252 save_area_t *sa; 253 254 if (!atari_realconfig) 255 return; 256 257 if (RGfx(et_priv.regkva, GCT_ID_MISC) & 1) { 258 #if 0 /* XXX: Can't use printf here.... */ 259 printf("et_save_view: Don't know how to save" 260 " a graphics mode\n"); 261 #endif 262 return; 263 } 264 if (v->save_area == NULL) 265 v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_NOWAIT); 266 267 /* 268 * Calculate the size of the copy 269 */ 270 font_height = RCrt(et_priv.regkva, CRT_ID_MAX_ROW_ADDRESS) & 0x1f; 271 sv_size = bm->bytes_per_row * (bm->rows / (font_height + 1)); 272 sv_size = min(SAVEBUF_SIZE, sv_size); 273 274 /* 275 * Save all we need to know.... 276 */ 277 sa = (save_area_t *)v->save_area; 278 et_hwsave(&sa->sv_regs); 279 sa->fb_size = sv_size; 280 src = (u_short *)bm->plane; 281 dst = sa->sv_fb; 282 while (sv_size--) 283 *dst++ = *src++; 284 bm->plane = (u_char *)sa->sv_fb; 285 } 286 287 void 288 et_free_view(v) 289 view_t *v; 290 { 291 if(v) { 292 et_remove_view(v); 293 if (v->colormap != &gra_con_cmap) 294 free(v->colormap, M_DEVBUF); 295 if (v->save_area != NULL) 296 free(v->save_area, M_DEVBUF); 297 if (v != &gra_con_view) { 298 free(v->bitmap, M_DEVBUF); 299 free(v, M_DEVBUF); 300 } 301 } 302 } 303 304 static int 305 et_use_colormap(v, cm) 306 view_t *v; 307 colormap_t *cm; 308 { 309 return (0); /* XXX: Nothing here for now... */ 310 } 311 312 static view_t * 313 et_alloc_view(mode, dim, depth) 314 dmode_t *mode; 315 dimen_t *dim; 316 u_char depth; 317 { 318 view_t *v; 319 bmap_t *bm; 320 box_t box; 321 save_area_t *sa; 322 323 if (!atari_realconfig) { 324 v = &gra_con_view; 325 bm = &con_bm; 326 } 327 else { 328 v = malloc(sizeof(*v), M_DEVBUF, M_WAITOK); 329 bm = malloc(sizeof(*bm), M_DEVBUF, M_WAITOK); 330 } 331 v->bitmap = bm; 332 333 /* 334 * Initialize the bitmap 335 */ 336 bm->plane = et_priv.memkva; 337 bm->vga_address = (caddr_t)kvtop(et_priv.memkva); 338 bm->vga_base = VGA_BASE; 339 bm->hw_address = (caddr_t)(PCI_MEM_PHYS | et_priv.linbase); 340 bm->lin_base = et_priv.linbase; 341 bm->regs = et_priv.regkva; 342 bm->hw_regs = (caddr_t)kvtop(et_priv.regkva); 343 bm->reg_size = REG_MAPPABLE; 344 bm->phys_mappable = FRAME_MAPPABLE; 345 bm->vga_mappable = VGA_MAPPABLE; 346 347 bm->bytes_per_row = (mode->size.width * depth) / NBBY; 348 bm->rows = mode->size.height; 349 bm->depth = depth; 350 351 /* 352 * Allocate a save_area. 353 * Note: If atari_realconfig is false, no save area is (can be) 354 * allocated. This means that the plane is the video memory, 355 * which is what's wanted in this case. 356 */ 357 if (atari_realconfig) { 358 v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK); 359 sa = (save_area_t*)v->save_area; 360 sa->fb_size = 0; 361 bm->plane = (u_char *)sa->sv_fb; 362 et_loadmode(mode->data, &sa->sv_regs); 363 } 364 else v->save_area = NULL; 365 366 v->colormap = alloc_colormap(mode); 367 if (v->colormap) { 368 INIT_BOX(&box,0,0,mode->size.width,mode->size.height); 369 init_view(v, bm, mode, &box); 370 return (v); 371 } 372 if (v != &gra_con_view) { 373 free(v, M_DEVBUF); 374 free(bm, M_DEVBUF); 375 } 376 return (NULL); 377 } 378 379 static void 380 init_view(v, bm, mode, dbox) 381 view_t *v; 382 bmap_t *bm; 383 dmode_t *mode; 384 box_t *dbox; 385 { 386 v->bitmap = bm; 387 v->mode = mode; 388 v->flags = 0; 389 bcopy(dbox, &v->display, sizeof(box_t)); 390 } 391 392 /* XXX: No more than a stub... */ 393 static colormap_t * 394 alloc_colormap(dm) 395 dmode_t *dm; 396 { 397 colormap_t *cm; 398 int i; 399 400 cm = &gra_con_cmap; 401 cm->entry = gra_con_colors; 402 403 cm->first = 0; 404 cm->size = 2; 405 406 for (i = 0; i < 2; i++) 407 cm->entry[i] = gra_def_color16[i % 16]; 408 return (cm); 409 } 410 411 /* 412 * Go look for a VGA card on the PCI-bus. This search is a 413 * stripped down version of the PCI-probe. It only looks on 414 * bus0 for et4000/et6000 cards. The first card found is used. 415 */ 416 int 417 et_probe_card() 418 { 419 pci_chipset_tag_t pc = NULL; /* XXX */ 420 pcitag_t tag; 421 int device, found, id, maxndevs; 422 423 found = 0; 424 tag = 0; 425 id = 0; 426 maxndevs = pci_bus_maxdevs(pc, 0); 427 428 for (device = 0; !found && (device < maxndevs); device++) { 429 430 tag = pci_make_tag(pc, 0, device, 0); 431 id = pci_conf_read(pc, tag, PCI_ID_REG); 432 if (id == 0 || id == 0xffffffff) 433 continue; 434 switch (PCI_PRODUCT(id)) { 435 case PCI_PRODUCT_TSENG_ET6000: 436 case PCI_PRODUCT_TSENG_ET4000_W32P_A: 437 case PCI_PRODUCT_TSENG_ET4000_W32P_B: 438 case PCI_PRODUCT_TSENG_ET4000_W32P_C: 439 case PCI_PRODUCT_TSENG_ET4000_W32P_D: 440 found = 1; 441 break; 442 default: 443 break; 444 } 445 } 446 if (!found) 447 return (0); 448 449 if (PCI_PRODUCT(id) == PCI_PRODUCT_TSENG_ET6000) 450 et_priv.board_type = BT_ET6000; 451 else { 452 #ifdef ET4000_HAS_2MB_MEM 453 volatile u_char *ba; 454 #endif 455 456 et_priv.board_type = BT_ET4000; 457 458 #ifdef ET4000_HAS_2MB_MEM 459 /* set KEY to access the tseng private registers */ 460 ba = (volatile caddr_t)pci_io_addr; 461 vgaw(ba, GREG_HERCULESCOMPAT, 0x03); 462 vgaw(ba, GREG_DISPMODECONTROL, 0xa0); 463 464 /* enable memory interleave */ 465 WCrt(ba, CRT_ID_RASCAS_CONFIG, 0xa0); 466 WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x89); 467 #endif 468 } 469 470 et_priv.pci_tag = tag; 471 472 /* 473 * The things below are setup in atari_init.c 474 */ 475 et_priv.regkva = (volatile caddr_t)pci_io_addr; 476 et_priv.memkva = (volatile caddr_t)pci_mem_addr; 477 et_priv.linbase = PCI_LINMEMBASE; /* XXX pci_conf_read??? */ 478 et_priv.memsz = PCI_VGA_SIZE; 479 et_priv.regsz = PCI_IO_SIZE; 480 481 if (!atari_realconfig) { 482 et_loadmode(&hw_modes[0], NULL); 483 return (1); 484 } 485 486 return (1); 487 } 488 489 static void 490 et_loadmode(mode, regs) 491 struct grfvideo_mode *mode; 492 et_sv_reg_t *regs; 493 { 494 unsigned short HDE, VDE; 495 int lace, dblscan; 496 int uplim, lowlim; 497 int i; 498 unsigned char clock, tmp; 499 volatile u_char *ba; 500 et_sv_reg_t loc_regs; 501 502 if (regs == NULL) 503 regs = &loc_regs; 504 505 ba = et_priv.regkva; 506 HDE = mode->disp_width / 8 - 1; 507 VDE = mode->disp_height - 1; 508 509 /* figure out whether lace or dblscan is needed */ 510 511 uplim = mode->disp_height + (mode->disp_height / 4); 512 lowlim = mode->disp_height - (mode->disp_height / 4); 513 lace = (((mode->vtotal * 2) > lowlim) 514 && ((mode->vtotal * 2) < uplim)) ? 1 : 0; 515 dblscan = (((mode->vtotal / 2) > lowlim) 516 && ((mode->vtotal / 2) < uplim)) ? 1 : 0; 517 518 /* adjustments */ 519 if (lace) 520 VDE /= 2; 521 522 regs->misc_output = 0x23; /* Page 0, Color mode */ 523 regs->seg_sel = 0x00; 524 regs->state_ctl = 0x00; 525 526 regs->seq[SEQ_ID_RESET] = 0x03; /* reset off */ 527 regs->seq[SEQ_ID_CLOCKING_MODE] = 0x21; /* Turn off screen */ 528 regs->seq[SEQ_ID_MAP_MASK] = 0xff; /* CPU writes all planes*/ 529 regs->seq[SEQ_ID_CHAR_MAP_SELECT] = 0x00; /* Char. generator 0 */ 530 regs->seq[SEQ_ID_MEMORY_MODE] = 0x0e; /* Seq. Memory mode */ 531 532 /* 533 * Set the clock... 534 */ 535 for(clock = ET_NUMCLOCKS-1; clock > 0; clock--) { 536 if (et_clockfreqs[clock] <= mode->pixel_clock) 537 break; 538 } 539 regs->misc_output |= (clock & 3) << 2; 540 regs->aux_mode = 0xb4 | ((clock & 8) << 3); 541 regs->compat_6845 = (clock & 4) ? 0x0a : 0x08; 542 543 /* 544 * The display parameters... 545 */ 546 regs->crt[CRT_ID_HOR_TOTAL] = mode->htotal; 547 regs->crt[CRT_ID_HOR_DISP_ENA_END] = ((HDE >= mode->hblank_start) 548 ? mode->hblank_stop - 1 549 : HDE); 550 regs->crt[CRT_ID_START_HOR_BLANK] = mode->hblank_start; 551 regs->crt[CRT_ID_END_HOR_BLANK] = (mode->hblank_stop & 0x1f) | 0x80; 552 regs->crt[CRT_ID_START_HOR_RETR] = mode->hsync_start; 553 regs->crt[CRT_ID_END_HOR_RETR] = (mode->hsync_stop & 0x1f) 554 | ((mode->hblank_stop & 0x20) 555 ? 0x80 : 0x00); 556 regs->crt[CRT_ID_VER_TOTAL] = mode->vtotal; 557 regs->crt[CRT_ID_START_VER_RETR] = mode->vsync_start; 558 regs->crt[CRT_ID_END_VER_RETR] = (mode->vsync_stop & 0x0f) | 0x30; 559 regs->crt[CRT_ID_VER_DISP_ENA_END] = VDE; 560 regs->crt[CRT_ID_START_VER_BLANK] = mode->vblank_start; 561 regs->crt[CRT_ID_END_VER_BLANK] = mode->vblank_stop; 562 regs->crt[CRT_ID_MODE_CONTROL] = 0xab; 563 regs->crt[CRT_ID_START_ADDR_HIGH] = 0x00; 564 regs->crt[CRT_ID_START_ADDR_LOW] = 0x00; 565 regs->crt[CRT_ID_LINE_COMPARE] = 0xff; 566 regs->crt[CRT_ID_UNDERLINE_LOC] = 0x00; 567 regs->crt[CRT_ID_PRESET_ROW_SCAN] = 0x00; 568 regs->crt[CRT_ID_OFFSET] = mode->disp_width/16; 569 regs->crt[CRT_ID_MAX_ROW_ADDRESS] = 570 0x40 | 571 (dblscan ? 0x80 : 0x00) | 572 ((mode->vblank_start & 0x200) ? 0x20 : 0x00); 573 regs->crt[CRT_ID_OVERFLOW] = 574 0x10 | 575 ((mode->vtotal & 0x100) ? 0x01 : 0x00) | 576 ((VDE & 0x100) ? 0x02 : 0x00) | 577 ((mode->vsync_start & 0x100) ? 0x04 : 0x00) | 578 ((mode->vblank_start & 0x100) ? 0x08 : 0x00) | 579 ((mode->vtotal & 0x200) ? 0x20 : 0x00) | 580 ((VDE & 0x200) ? 0x40 : 0x00) | 581 ((mode->vsync_start & 0x200) ? 0x80 : 0x00); 582 regs->overfl_high = 583 0x10 | 584 ((mode->vblank_start & 0x400) ? 0x01 : 0x00) | 585 ((mode->vtotal & 0x400) ? 0x02 : 0x00) | 586 ((VDE & 0x400) ? 0x04 : 0x00) | 587 ((mode->vsync_start & 0x400) ? 0x08 : 0x00) | 588 (lace ? 0x80 : 0x00); 589 regs->hor_overfl = 590 ((mode->htotal & 0x100) ? 0x01 : 0x00) | 591 ((mode->hblank_start & 0x100) ? 0x04 : 0x00) | 592 ((mode->hsync_start & 0x100) ? 0x10 : 0x00); 593 594 regs->grf[GCT_ID_SET_RESET] = 0x00; 595 regs->grf[GCT_ID_ENABLE_SET_RESET] = 0x00; 596 regs->grf[GCT_ID_COLOR_COMPARE] = 0x00; 597 regs->grf[GCT_ID_DATA_ROTATE] = 0x00; 598 regs->grf[GCT_ID_READ_MAP_SELECT] = 0x00; 599 regs->grf[GCT_ID_GRAPHICS_MODE] = mode->depth == 1 ? 0x00: 0x40; 600 regs->grf[GCT_ID_MISC] = 0x01; 601 regs->grf[GCT_ID_COLOR_XCARE] = 0x0f; 602 regs->grf[GCT_ID_BITMASK] = 0xff; 603 604 for (i = 0; i < 0x10; i++) 605 regs->attr[i] = i; 606 regs->attr[ACT_ID_ATTR_MODE_CNTL] = 0x01; 607 regs->attr[ACT_ID_OVERSCAN_COLOR] = 0x00; 608 regs->attr[ACT_ID_COLOR_PLANE_ENA] = 0x0f; 609 regs->attr[ACT_ID_HOR_PEL_PANNING] = 0x00; 610 regs->attr[ACT_ID_COLOR_SELECT] = 0x00; 611 regs->attr[ACT_ID_MISCELLANEOUS] = 0x00; 612 613 /* 614 * XXX: This works for depth == 4. I need some better docs 615 * to fix the other modes.... 616 */ 617 /* 618 * What we need would be probe functions for RAMDAC/clock chip 619 */ 620 vgar(ba, VDAC_ADDRESS); /* clear old state */ 621 vgar(ba, VDAC_MASK); 622 vgar(ba, VDAC_MASK); 623 vgar(ba, VDAC_MASK); 624 vgar(ba, VDAC_MASK); 625 626 vgaw(ba, VDAC_MASK, 0); /* set to palette */ 627 vgar(ba, VDAC_ADDRESS); /* clear state */ 628 629 vgaw(ba, VDAC_MASK, 0xff); 630 /* 631 * End of depth stuff 632 */ 633 634 /* 635 * Compute Hsync & Vsync polarity 636 * Note: This seems to be some kind of a black art :-( 637 */ 638 tmp = regs->misc_output & 0x3f; 639 #if 1 /* This is according to my BW monitor & Xfree... */ 640 if (VDE < 400) 641 tmp |= 0x40; /* -hsync +vsync */ 642 else if (VDE < 480) 643 tmp |= 0xc0; /* -hsync -vsync */ 644 #else /* This is according to my color monitor.... */ 645 if (VDE < 400) 646 tmp |= 0x00; /* +hsync +vsync */ 647 else if (VDE < 480) 648 tmp |= 0x80; /* +hsync -vsync */ 649 #endif 650 /* I'm unable to try the rest.... */ 651 regs->misc_output = tmp; 652 653 if(regs == &loc_regs) 654 et_hwrest(regs); 655 } 656 657 void 658 et_hwsave(et_regs) 659 et_sv_reg_t *et_regs; 660 { 661 volatile u_char *ba; 662 int i, s; 663 664 ba = et_priv.regkva; 665 666 s = splhigh(); 667 668 /* 669 * General VGA registers 670 */ 671 et_regs->misc_output = vgar(ba, GREG_MISC_OUTPUT_R); 672 for(i = 0; i < 25; i++) 673 et_regs->crt[i] = RCrt(ba, i); 674 for(i = 0; i < 21; i++) 675 et_regs->attr[i] = RAttr(ba, i | 0x20); 676 for(i = 0; i < 9; i++) 677 et_regs->grf[i] = RGfx(ba, i); 678 for(i = 0; i < 5; i++) 679 et_regs->seq[i] = RSeq(ba, i); 680 681 /* 682 * ET4000 extensions 683 */ 684 et_regs->ext_start = RCrt(ba, CTR_ID_EXT_START); 685 et_regs->compat_6845 = RCrt(ba, CRT_ID_6845_COMPAT); 686 et_regs->overfl_high = RCrt(ba, CRT_ID_OVERFLOW_HIGH); 687 et_regs->hor_overfl = RCrt(ba, CRT_ID_HOR_OVERFLOW); 688 et_regs->state_ctl = RSeq(ba, SEQ_ID_STATE_CONTROL); 689 et_regs->aux_mode = RSeq(ba, SEQ_ID_AUXILIARY_MODE); 690 et_regs->seg_sel = vgar(ba, GREG_SEGMENTSELECT); 691 692 splx(s); 693 } 694 695 void 696 et_hwrest(et_regs) 697 et_sv_reg_t *et_regs; 698 { 699 volatile u_char *ba; 700 int i, s; 701 702 ba = et_priv.regkva; 703 704 s = splhigh(); 705 706 vgaw(ba, GREG_SEGMENTSELECT, 0); 707 vgaw(ba, GREG_MISC_OUTPUT_W, et_regs->misc_output); 708 709 /* 710 * General VGA registers 711 */ 712 WSeq(ba, SEQ_ID_RESET, 0x01); 713 for(i = 1; i < 5; i++) 714 WSeq(ba, i, et_regs->seq[i]); 715 WSeq(ba, SEQ_ID_RESET, 0x03); 716 717 /* 718 * Make sure we're allowed to write all crt-registers 719 */ 720 WCrt(ba, CRT_ID_END_VER_RETR, 721 et_regs->crt[CRT_ID_END_VER_RETR] & 0x7f); 722 for(i = 0; i < 25; i++) 723 WCrt(ba, i, et_regs->crt[i]); 724 for(i = 0; i < 9; i++) 725 WGfx(ba, i, et_regs->grf[i]); 726 for(i = 0; i < 21; i++) 727 WAttr(ba, i | 0x20, et_regs->attr[i]); 728 729 /* 730 * ET4000 extensions 731 */ 732 WSeq(ba, SEQ_ID_STATE_CONTROL, et_regs->state_ctl); 733 WSeq(ba, SEQ_ID_AUXILIARY_MODE, et_regs->aux_mode); 734 WCrt(ba, CTR_ID_EXT_START, et_regs->ext_start); 735 WCrt(ba, CRT_ID_6845_COMPAT, et_regs->compat_6845); 736 WCrt(ba, CRT_ID_OVERFLOW_HIGH, et_regs->overfl_high); 737 WCrt(ba, CRT_ID_HOR_OVERFLOW, et_regs->hor_overfl); 738 vgaw(ba, GREG_SEGMENTSELECT, et_regs->seg_sel); 739 740 i = et_regs->seq[SEQ_ID_CLOCKING_MODE] & ~0x20; 741 WSeq(ba, SEQ_ID_CLOCKING_MODE, i); 742 743 splx(s); 744 } 745