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