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