vgaHW.c revision 4642e01f
1 2/* 3 * 4 * Copyright 1991-1999 by The XFree86 Project, Inc. 5 * 6 * Loosely based on code bearing the following copyright: 7 * 8 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 9 * 10 */ 11 12#define _NEED_SYSI86 13 14#ifdef HAVE_XORG_CONFIG_H 15#include <xorg-config.h> 16#endif 17 18#include <stdlib.h> 19#include <string.h> 20#include <unistd.h> 21 22#include <X11/X.h> 23#include "misc.h" 24 25#include "xf86.h" 26#include "xf86_OSproc.h" 27#include "vgaHW.h" 28 29#include "compiler.h" 30 31#include "xf86cmap.h" 32 33#include "Pci.h" 34 35#ifndef SAVE_FONT1 36#define SAVE_FONT1 1 37#endif 38 39/* 40 * These used to be OS-specific, which made this module have an undesirable 41 * OS dependency. Define them by default for all platforms. 42 */ 43#ifndef NEED_SAVED_CMAP 44#define NEED_SAVED_CMAP 45#endif 46#ifndef SAVE_TEXT 47#define SAVE_TEXT 1 48#endif 49#ifndef SAVE_FONT2 50#define SAVE_FONT2 1 51#endif 52 53/* bytes per plane to save for text */ 54#define TEXT_AMOUNT 16384 55 56/* bytes per plane to save for font data */ 57#define FONT_AMOUNT (8*8192) 58 59#if 0 60/* Override all of these for now */ 61#undef SAVE_FONT1 62#define SAVE_FONT1 1 63#undef SAVE_FONT2 64#define SAVE_FONT2 1 65#undef SAVE_TEST 66#define SAVE_TEST 1 67#undef FONT_AMOUNT 68#define FONT_AMOUNT 65536 69#undef TEXT_AMOUNT 70#define TEXT_AMOUNT 65536 71#endif 72 73/* DAC indices for white and black */ 74#define WHITE_VALUE 0x3F 75#define BLACK_VALUE 0x00 76#define OVERSCAN_VALUE 0x01 77 78 79/* Use a private definition of this here */ 80#undef VGAHWPTR 81#define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr 82#define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p))) 83 84static int vgaHWPrivateIndex = -1; 85 86#define DAC_TEST_MASK 0x3F 87 88#ifdef NEED_SAVED_CMAP 89/* This default colourmap is used only when it can't be read from the VGA */ 90 91static CARD8 defaultDAC[768] = 92{ 93 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42, 94 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42, 95 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63, 96 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63, 97 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11, 98 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24, 99 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40, 100 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63, 101 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63, 102 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 103 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 104 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0, 105 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 106 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 107 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63, 108 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 109 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 110 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31, 111 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 112 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 113 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63, 114 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 115 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 116 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45, 117 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 118 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 119 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28, 120 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 121 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 122 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0, 123 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 124 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 125 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28, 126 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 127 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 128 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14, 129 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 130 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 131 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28, 132 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 133 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 134 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20, 135 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 136 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 137 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16, 138 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 139 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 140 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0, 141 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 142 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 143 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16, 144 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 145 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 146 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8, 147 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 148 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 149 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16, 150 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 151 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 152 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11, 153 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 154 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157}; 158#endif /* NEED_SAVED_CMAP */ 159 160/* 161 * Standard VGA versions of the register access functions. 162 */ 163static void 164stdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 165{ 166 outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index); 167 outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET, value); 168} 169 170static CARD8 171stdReadCrtc(vgaHWPtr hwp, CARD8 index) 172{ 173 outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index); 174 return inb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET); 175} 176 177static void 178stdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value) 179{ 180 outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index); 181 outb(hwp->PIOOffset + VGA_GRAPH_DATA, value); 182} 183 184static CARD8 185stdReadGr(vgaHWPtr hwp, CARD8 index) 186{ 187 outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index); 188 return inb(hwp->PIOOffset + VGA_GRAPH_DATA); 189} 190 191static void 192stdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value) 193{ 194 outb(hwp->PIOOffset + VGA_SEQ_INDEX, index); 195 outb(hwp->PIOOffset + VGA_SEQ_DATA, value); 196} 197 198static CARD8 199stdReadSeq(vgaHWPtr hwp, CARD8 index) 200{ 201 outb(hwp->PIOOffset + VGA_SEQ_INDEX, index); 202 return inb(hwp->PIOOffset + VGA_SEQ_DATA); 203} 204 205static CARD8 206stdReadST00(vgaHWPtr hwp) 207{ 208 return inb(hwp->PIOOffset + VGA_IN_STAT_0); 209} 210 211static CARD8 212stdReadST01(vgaHWPtr hwp) 213{ 214 return inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 215} 216 217static CARD8 218stdReadFCR(vgaHWPtr hwp) 219{ 220 return inb(hwp->PIOOffset + VGA_FEATURE_R); 221} 222 223static void 224stdWriteFCR(vgaHWPtr hwp, CARD8 value) 225{ 226 outb(hwp->IOBase + hwp->PIOOffset + VGA_FEATURE_W_OFFSET,value); 227} 228 229static void 230stdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value) 231{ 232 if (hwp->paletteEnabled) 233 index &= ~0x20; 234 else 235 index |= 0x20; 236 237 (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 238 outb(hwp->PIOOffset + VGA_ATTR_INDEX, index); 239 outb(hwp->PIOOffset + VGA_ATTR_DATA_W, value); 240} 241 242static CARD8 243stdReadAttr(vgaHWPtr hwp, CARD8 index) 244{ 245 if (hwp->paletteEnabled) 246 index &= ~0x20; 247 else 248 index |= 0x20; 249 250 (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 251 outb(hwp->PIOOffset + VGA_ATTR_INDEX, index); 252 return inb(hwp->PIOOffset + VGA_ATTR_DATA_R); 253} 254 255static void 256stdWriteMiscOut(vgaHWPtr hwp, CARD8 value) 257{ 258 outb(hwp->PIOOffset + VGA_MISC_OUT_W, value); 259} 260 261static CARD8 262stdReadMiscOut(vgaHWPtr hwp) 263{ 264 return inb(hwp->PIOOffset + VGA_MISC_OUT_R); 265} 266 267static void 268stdEnablePalette(vgaHWPtr hwp) 269{ 270 (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 271 outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x00); 272 hwp->paletteEnabled = TRUE; 273} 274 275static void 276stdDisablePalette(vgaHWPtr hwp) 277{ 278 (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 279 outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x20); 280 hwp->paletteEnabled = FALSE; 281} 282 283static void 284stdWriteDacMask(vgaHWPtr hwp, CARD8 value) 285{ 286 outb(hwp->PIOOffset + VGA_DAC_MASK, value); 287} 288 289static CARD8 290stdReadDacMask(vgaHWPtr hwp) 291{ 292 return inb(hwp->PIOOffset + VGA_DAC_MASK); 293} 294 295static void 296stdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value) 297{ 298 outb(hwp->PIOOffset + VGA_DAC_READ_ADDR, value); 299} 300 301static void 302stdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value) 303{ 304 outb(hwp->PIOOffset + VGA_DAC_WRITE_ADDR, value); 305} 306 307static void 308stdWriteDacData(vgaHWPtr hwp, CARD8 value) 309{ 310 outb(hwp->PIOOffset + VGA_DAC_DATA, value); 311} 312 313static CARD8 314stdReadDacData(vgaHWPtr hwp) 315{ 316 return inb(hwp->PIOOffset + VGA_DAC_DATA); 317} 318 319static CARD8 320stdReadEnable(vgaHWPtr hwp) 321{ 322 return inb(hwp->PIOOffset + VGA_ENABLE); 323} 324 325static void 326stdWriteEnable(vgaHWPtr hwp, CARD8 value) 327{ 328 outb(hwp->PIOOffset + VGA_ENABLE, value); 329} 330 331void 332vgaHWSetStdFuncs(vgaHWPtr hwp) 333{ 334 hwp->writeCrtc = stdWriteCrtc; 335 hwp->readCrtc = stdReadCrtc; 336 hwp->writeGr = stdWriteGr; 337 hwp->readGr = stdReadGr; 338 hwp->readST00 = stdReadST00; 339 hwp->readST01 = stdReadST01; 340 hwp->readFCR = stdReadFCR; 341 hwp->writeFCR = stdWriteFCR; 342 hwp->writeAttr = stdWriteAttr; 343 hwp->readAttr = stdReadAttr; 344 hwp->writeSeq = stdWriteSeq; 345 hwp->readSeq = stdReadSeq; 346 hwp->writeMiscOut = stdWriteMiscOut; 347 hwp->readMiscOut = stdReadMiscOut; 348 hwp->enablePalette = stdEnablePalette; 349 hwp->disablePalette = stdDisablePalette; 350 hwp->writeDacMask = stdWriteDacMask; 351 hwp->readDacMask = stdReadDacMask; 352 hwp->writeDacWriteAddr = stdWriteDacWriteAddr; 353 hwp->writeDacReadAddr = stdWriteDacReadAddr; 354 hwp->writeDacData = stdWriteDacData; 355 hwp->readDacData = stdReadDacData; 356 hwp->PIOOffset = 0; 357 hwp->readEnable = stdReadEnable; 358 hwp->writeEnable = stdWriteEnable; 359} 360 361/* 362 * MMIO versions of the register access functions. These require 363 * hwp->MemBase to be set in such a way that when the standard VGA port 364 * adderss is added the correct memory address results. 365 */ 366 367#define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p))) 368#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v)) 369 370static void 371mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 372{ 373 moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 374 moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value); 375} 376 377static CARD8 378mmioReadCrtc(vgaHWPtr hwp, CARD8 index) 379{ 380 moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 381 return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET); 382} 383 384static void 385mmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value) 386{ 387 moutb(VGA_GRAPH_INDEX, index); 388 moutb(VGA_GRAPH_DATA, value); 389} 390 391static CARD8 392mmioReadGr(vgaHWPtr hwp, CARD8 index) 393{ 394 moutb(VGA_GRAPH_INDEX, index); 395 return minb(VGA_GRAPH_DATA); 396} 397 398static void 399mmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value) 400{ 401 moutb(VGA_SEQ_INDEX, index); 402 moutb(VGA_SEQ_DATA, value); 403} 404 405static CARD8 406mmioReadSeq(vgaHWPtr hwp, CARD8 index) 407{ 408 moutb(VGA_SEQ_INDEX, index); 409 return minb(VGA_SEQ_DATA); 410} 411 412static CARD8 413mmioReadST00(vgaHWPtr hwp) 414{ 415 return minb(VGA_IN_STAT_0); 416} 417 418static CARD8 419mmioReadST01(vgaHWPtr hwp) 420{ 421 return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 422} 423 424static CARD8 425mmioReadFCR(vgaHWPtr hwp) 426{ 427 return minb(VGA_FEATURE_R); 428} 429 430static void 431mmioWriteFCR(vgaHWPtr hwp, CARD8 value) 432{ 433 moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET,value); 434} 435 436static void 437mmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value) 438{ 439 if (hwp->paletteEnabled) 440 index &= ~0x20; 441 else 442 index |= 0x20; 443 444 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 445 moutb(VGA_ATTR_INDEX, index); 446 moutb(VGA_ATTR_DATA_W, value); 447} 448 449static CARD8 450mmioReadAttr(vgaHWPtr hwp, CARD8 index) 451{ 452 if (hwp->paletteEnabled) 453 index &= ~0x20; 454 else 455 index |= 0x20; 456 457 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 458 moutb(VGA_ATTR_INDEX, index); 459 return minb(VGA_ATTR_DATA_R); 460} 461 462static void 463mmioWriteMiscOut(vgaHWPtr hwp, CARD8 value) 464{ 465 moutb(VGA_MISC_OUT_W, value); 466} 467 468static CARD8 469mmioReadMiscOut(vgaHWPtr hwp) 470{ 471 return minb(VGA_MISC_OUT_R); 472} 473 474static void 475mmioEnablePalette(vgaHWPtr hwp) 476{ 477 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 478 moutb(VGA_ATTR_INDEX, 0x00); 479 hwp->paletteEnabled = TRUE; 480} 481 482static void 483mmioDisablePalette(vgaHWPtr hwp) 484{ 485 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 486 moutb(VGA_ATTR_INDEX, 0x20); 487 hwp->paletteEnabled = FALSE; 488} 489 490static void 491mmioWriteDacMask(vgaHWPtr hwp, CARD8 value) 492{ 493 moutb(VGA_DAC_MASK, value); 494} 495 496static CARD8 497mmioReadDacMask(vgaHWPtr hwp) 498{ 499 return minb(VGA_DAC_MASK); 500} 501 502static void 503mmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value) 504{ 505 moutb(VGA_DAC_READ_ADDR, value); 506} 507 508static void 509mmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value) 510{ 511 moutb(VGA_DAC_WRITE_ADDR, value); 512} 513 514static void 515mmioWriteDacData(vgaHWPtr hwp, CARD8 value) 516{ 517 moutb(VGA_DAC_DATA, value); 518} 519 520static CARD8 521mmioReadDacData(vgaHWPtr hwp) 522{ 523 return minb(VGA_DAC_DATA); 524} 525 526static CARD8 527mmioReadEnable(vgaHWPtr hwp) 528{ 529 return minb(VGA_ENABLE); 530} 531 532static void 533mmioWriteEnable(vgaHWPtr hwp, CARD8 value) 534{ 535 moutb(VGA_ENABLE, value); 536} 537 538void 539vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset) 540{ 541 hwp->writeCrtc = mmioWriteCrtc; 542 hwp->readCrtc = mmioReadCrtc; 543 hwp->writeGr = mmioWriteGr; 544 hwp->readGr = mmioReadGr; 545 hwp->readST00 = mmioReadST00; 546 hwp->readST01 = mmioReadST01; 547 hwp->readFCR = mmioReadFCR; 548 hwp->writeFCR = mmioWriteFCR; 549 hwp->writeAttr = mmioWriteAttr; 550 hwp->readAttr = mmioReadAttr; 551 hwp->writeSeq = mmioWriteSeq; 552 hwp->readSeq = mmioReadSeq; 553 hwp->writeMiscOut = mmioWriteMiscOut; 554 hwp->readMiscOut = mmioReadMiscOut; 555 hwp->enablePalette = mmioEnablePalette; 556 hwp->disablePalette = mmioDisablePalette; 557 hwp->writeDacMask = mmioWriteDacMask; 558 hwp->readDacMask = mmioReadDacMask; 559 hwp->writeDacWriteAddr = mmioWriteDacWriteAddr; 560 hwp->writeDacReadAddr = mmioWriteDacReadAddr; 561 hwp->writeDacData = mmioWriteDacData; 562 hwp->readDacData = mmioReadDacData; 563 hwp->MMIOBase = base; 564 hwp->MMIOOffset = offset; 565 hwp->readEnable = mmioReadEnable; 566 hwp->writeEnable = mmioWriteEnable; 567} 568 569/* 570 * vgaHWProtect -- 571 * Protect VGA registers and memory from corruption during loads. 572 */ 573 574void 575vgaHWProtect(ScrnInfoPtr pScrn, Bool on) 576{ 577 vgaHWPtr hwp = VGAHWPTR(pScrn); 578 579 unsigned char tmp; 580 581 if (pScrn->vtSema) { 582 if (on) { 583 /* 584 * Turn off screen and disable sequencer. 585 */ 586 tmp = hwp->readSeq(hwp, 0x01); 587 588 vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */ 589 hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */ 590 591 hwp->enablePalette(hwp); 592 } else { 593 /* 594 * Reenable sequencer, then turn on screen. 595 */ 596 597 tmp = hwp->readSeq(hwp, 0x01); 598 599 hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */ 600 vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */ 601 602 hwp->disablePalette(hwp); 603 } 604 } 605} 606 607vgaHWProtectProc *vgaHWProtectWeak(void) { 608 return vgaHWProtect; 609} 610 611/* 612 * vgaHWBlankScreen -- blank the screen. 613 */ 614 615void 616vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on) 617{ 618 vgaHWPtr hwp = VGAHWPTR(pScrn); 619 unsigned char scrn; 620 621 scrn = hwp->readSeq(hwp, 0x01); 622 623 if (on) { 624 scrn &= ~0x20; /* enable screen */ 625 } else { 626 scrn |= 0x20; /* blank screen */ 627 } 628 629 vgaHWSeqReset(hwp, TRUE); 630 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 631 vgaHWSeqReset(hwp, FALSE); 632} 633 634vgaHWBlankScreenProc *vgaHWBlankScreenWeak(void) { 635 return vgaHWBlankScreen; 636} 637 638/* 639 * vgaHWSaveScreen -- blank the screen. 640 */ 641 642Bool 643vgaHWSaveScreen(ScreenPtr pScreen, int mode) 644{ 645 ScrnInfoPtr pScrn = NULL; 646 Bool on; 647 648 if (pScreen != NULL) 649 pScrn = xf86Screens[pScreen->myNum]; 650 651 on = xf86IsUnblank(mode); 652 653#if 0 654 if (on) 655 SetTimeSinceLastInputEvent(); 656#endif 657 658 if ((pScrn != NULL) && pScrn->vtSema) { 659 vgaHWBlankScreen(pScrn, on); 660 } 661 return (TRUE); 662} 663 664 665/* 666 * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode 667 * 668 * This generic VGA function can only set the Off and On modes. If the 669 * Standby and Suspend modes are to be supported, a chip specific replacement 670 * for this function must be written. 671 */ 672 673void 674vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) 675{ 676 unsigned char seq1 = 0, crtc17 = 0; 677 vgaHWPtr hwp = VGAHWPTR(pScrn); 678 679 if (!pScrn->vtSema) return; 680 681 switch (PowerManagementMode) { 682 case DPMSModeOn: 683 /* Screen: On; HSync: On, VSync: On */ 684 seq1 = 0x00; 685 crtc17 = 0x80; 686 break; 687 case DPMSModeStandby: 688 /* Screen: Off; HSync: Off, VSync: On -- Not Supported */ 689 seq1 = 0x20; 690 crtc17 = 0x80; 691 break; 692 case DPMSModeSuspend: 693 /* Screen: Off; HSync: On, VSync: Off -- Not Supported */ 694 seq1 = 0x20; 695 crtc17 = 0x80; 696 break; 697 case DPMSModeOff: 698 /* Screen: Off; HSync: Off, VSync: Off */ 699 seq1 = 0x20; 700 crtc17 = 0x00; 701 break; 702 } 703 hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */ 704 seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20; 705 hwp->writeSeq(hwp, 0x01, seq1); 706 crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80; 707 usleep(10000); 708 hwp->writeCrtc(hwp, 0x17, crtc17); 709 hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */ 710} 711 712 713/* 714 * vgaHWSeqReset 715 * perform a sequencer reset. 716 */ 717 718void 719vgaHWSeqReset(vgaHWPtr hwp, Bool start) 720{ 721 if (start) 722 hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */ 723 else 724 hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */ 725} 726 727 728void 729vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) 730{ 731#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 732 vgaHWPtr hwp = VGAHWPTR(scrninfp); 733 int savedIOBase; 734 unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4; 735 Bool doMap = FALSE; 736 737 /* If nothing to do, return now */ 738 if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo) 739 return; 740 741 if (hwp->Base == NULL) { 742 doMap = TRUE; 743 if (!vgaHWMapMem(scrninfp)) { 744 xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, 745 "vgaHWRestoreFonts: vgaHWMapMem() failed\n"); 746 return; 747 } 748 } 749 750 /* save the registers that are needed here */ 751 miscOut = hwp->readMiscOut(hwp); 752 attr10 = hwp->readAttr(hwp, 0x10); 753 gr1 = hwp->readGr(hwp, 0x01); 754 gr3 = hwp->readGr(hwp, 0x03); 755 gr4 = hwp->readGr(hwp, 0x04); 756 gr5 = hwp->readGr(hwp, 0x05); 757 gr6 = hwp->readGr(hwp, 0x06); 758 gr8 = hwp->readGr(hwp, 0x08); 759 seq2 = hwp->readSeq(hwp, 0x02); 760 seq4 = hwp->readSeq(hwp, 0x04); 761 762 /* save hwp->IOBase and temporarily set it for colour mode */ 763 savedIOBase = hwp->IOBase; 764 hwp->IOBase = VGA_IOBASE_COLOR; 765 766 /* Force into colour mode */ 767 hwp->writeMiscOut(hwp, miscOut | 0x01); 768 769 vgaHWBlankScreen(scrninfp, FALSE); 770 771 /* 772 * here we temporarily switch to 16 colour planar mode, to simply 773 * copy the font-info and saved text. 774 * 775 * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! 776 */ 777#if 0 778 hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ 779#endif 780 781 hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ 782 hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ 783 hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ 784 785 if (scrninfp->depth == 4) { 786 /* GJA */ 787 hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */ 788 hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */ 789 hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */ 790 } 791 792#if SAVE_FONT1 793 if (hwp->FontInfo1) { 794 hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ 795 hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ 796 slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT); 797 } 798#endif 799 800#if SAVE_FONT2 801 if (hwp->FontInfo2) { 802 hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ 803 hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ 804 slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT); 805 } 806#endif 807 808#if SAVE_TEXT 809 if (hwp->TextInfo) { 810 hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ 811 hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ 812 slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT); 813 hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ 814 hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ 815 slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT, 816 hwp->Base, TEXT_AMOUNT); 817 } 818#endif 819 820 vgaHWBlankScreen(scrninfp, TRUE); 821 822 /* restore the registers that were changed */ 823 hwp->writeMiscOut(hwp, miscOut); 824 hwp->writeAttr(hwp, 0x10, attr10); 825 hwp->writeGr(hwp, 0x01, gr1); 826 hwp->writeGr(hwp, 0x03, gr3); 827 hwp->writeGr(hwp, 0x04, gr4); 828 hwp->writeGr(hwp, 0x05, gr5); 829 hwp->writeGr(hwp, 0x06, gr6); 830 hwp->writeGr(hwp, 0x08, gr8); 831 hwp->writeSeq(hwp, 0x02, seq2); 832 hwp->writeSeq(hwp, 0x04, seq4); 833 hwp->IOBase = savedIOBase; 834 835 if (doMap) 836 vgaHWUnmapMem(scrninfp); 837 838#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */ 839} 840 841 842void 843vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore) 844{ 845 vgaHWPtr hwp = VGAHWPTR(scrninfp); 846 int i; 847 848 if (restore->MiscOutReg & 0x01) 849 hwp->IOBase = VGA_IOBASE_COLOR; 850 else 851 hwp->IOBase = VGA_IOBASE_MONO; 852 853 hwp->writeMiscOut(hwp, restore->MiscOutReg); 854 855 for (i = 1; i < restore->numSequencer; i++) 856 hwp->writeSeq(hwp, i, restore->Sequencer[i]); 857 858 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */ 859 hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80); 860 861 for (i = 0; i < restore->numCRTC; i++) 862 hwp->writeCrtc(hwp, i, restore->CRTC[i]); 863 864 for (i = 0; i < restore->numGraphics; i++) 865 hwp->writeGr(hwp, i, restore->Graphics[i]); 866 867 hwp->enablePalette(hwp); 868 for (i = 0; i < restore->numAttribute; i++) 869 hwp->writeAttr(hwp, i, restore->Attribute[i]); 870 hwp->disablePalette(hwp); 871} 872 873 874void 875vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore) 876{ 877 vgaHWPtr hwp = VGAHWPTR(scrninfp); 878 int i; 879 880#if 0 881 hwp->enablePalette(hwp); 882#endif 883 884 hwp->writeDacMask(hwp, 0xFF); 885 hwp->writeDacWriteAddr(hwp, 0x00); 886 for (i = 0; i < 768; i++) { 887 hwp->writeDacData(hwp, restore->DAC[i]); 888 DACDelay(hwp); 889 } 890 891 hwp->disablePalette(hwp); 892} 893 894 895/* 896 * vgaHWRestore -- 897 * restore the VGA state 898 */ 899 900void 901vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags) 902{ 903 if (flags & VGA_SR_MODE) 904 vgaHWRestoreMode(scrninfp, restore); 905 906 if (flags & VGA_SR_FONTS) 907 vgaHWRestoreFonts(scrninfp, restore); 908 909 if (flags & VGA_SR_CMAP) 910 vgaHWRestoreColormap(scrninfp, restore); 911} 912 913void 914vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) 915{ 916#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 917 vgaHWPtr hwp = VGAHWPTR(scrninfp); 918 int savedIOBase; 919 unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4; 920 Bool doMap = FALSE; 921 922 if (hwp->Base == NULL) { 923 doMap = TRUE; 924 if (!vgaHWMapMem(scrninfp)) { 925 xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, 926 "vgaHWSaveFonts: vgaHWMapMem() failed\n"); 927 return; 928 } 929 } 930 931 /* If in graphics mode, don't save anything */ 932 attr10 = hwp->readAttr(hwp, 0x10); 933 if (attr10 & 0x01) 934 return; 935 936 /* save the registers that are needed here */ 937 miscOut = hwp->readMiscOut(hwp); 938 gr4 = hwp->readGr(hwp, 0x04); 939 gr5 = hwp->readGr(hwp, 0x05); 940 gr6 = hwp->readGr(hwp, 0x06); 941 seq2 = hwp->readSeq(hwp, 0x02); 942 seq4 = hwp->readSeq(hwp, 0x04); 943 944 /* save hwp->IOBase and temporarily set it for colour mode */ 945 savedIOBase = hwp->IOBase; 946 hwp->IOBase = VGA_IOBASE_COLOR; 947 948 /* Force into colour mode */ 949 hwp->writeMiscOut(hwp, miscOut | 0x01); 950 951 vgaHWBlankScreen(scrninfp, FALSE); 952 953 /* 954 * get the character sets, and text screen if required 955 */ 956 /* 957 * Here we temporarily switch to 16 colour planar mode, to simply 958 * copy the font-info 959 * 960 * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! 961 */ 962#if 0 963 hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ 964#endif 965 966 hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ 967 hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ 968 hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ 969 970#if SAVE_FONT1 971 if (hwp->FontInfo1 || (hwp->FontInfo1 = xalloc(FONT_AMOUNT))) { 972 hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ 973 hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ 974 slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT); 975 } 976#endif /* SAVE_FONT1 */ 977#if SAVE_FONT2 978 if (hwp->FontInfo2 || (hwp->FontInfo2 = xalloc(FONT_AMOUNT))) { 979 hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ 980 hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ 981 slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT); 982 } 983#endif /* SAVE_FONT2 */ 984#if SAVE_TEXT 985 if (hwp->TextInfo || (hwp->TextInfo = xalloc(2 * TEXT_AMOUNT))) { 986 hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ 987 hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ 988 slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT); 989 hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ 990 hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ 991 slowbcopy_frombus(hwp->Base, 992 (unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT); 993 } 994#endif /* SAVE_TEXT */ 995 996 /* Restore clobbered registers */ 997 hwp->writeAttr(hwp, 0x10, attr10); 998 hwp->writeSeq(hwp, 0x02, seq2); 999 hwp->writeSeq(hwp, 0x04, seq4); 1000 hwp->writeGr(hwp, 0x04, gr4); 1001 hwp->writeGr(hwp, 0x05, gr5); 1002 hwp->writeGr(hwp, 0x06, gr6); 1003 hwp->writeMiscOut(hwp, miscOut); 1004 hwp->IOBase = savedIOBase; 1005 1006 vgaHWBlankScreen(scrninfp, TRUE); 1007 1008 if (doMap) 1009 vgaHWUnmapMem(scrninfp); 1010 1011#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */ 1012} 1013 1014void 1015vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save) 1016{ 1017 vgaHWPtr hwp = VGAHWPTR(scrninfp); 1018 int i; 1019 1020 save->MiscOutReg = hwp->readMiscOut(hwp); 1021 if (save->MiscOutReg & 0x01) 1022 hwp->IOBase = VGA_IOBASE_COLOR; 1023 else 1024 hwp->IOBase = VGA_IOBASE_MONO; 1025 1026 for (i = 0; i < save->numCRTC; i++) { 1027 save->CRTC[i] = hwp->readCrtc(hwp, i); 1028#ifdef DEBUG 1029 ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]); 1030#endif 1031 } 1032 1033 hwp->enablePalette(hwp); 1034 for (i = 0; i < save->numAttribute; i++) { 1035 save->Attribute[i] = hwp->readAttr(hwp, i); 1036#ifdef DEBUG 1037 ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]); 1038#endif 1039 } 1040 hwp->disablePalette(hwp); 1041 1042 for (i = 0; i < save->numGraphics; i++) { 1043 save->Graphics[i] = hwp->readGr(hwp, i); 1044#ifdef DEBUG 1045 ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]); 1046#endif 1047 } 1048 1049 for (i = 1; i < save->numSequencer; i++) { 1050 save->Sequencer[i] = hwp->readSeq(hwp, i); 1051#ifdef DEBUG 1052 ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]); 1053#endif 1054 } 1055} 1056 1057 1058void 1059vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save) 1060{ 1061 vgaHWPtr hwp = VGAHWPTR(scrninfp); 1062 Bool readError = FALSE; 1063 int i; 1064 1065#ifdef NEED_SAVED_CMAP 1066 /* 1067 * Some ET4000 chips from 1991 have a HW bug that prevents the reading 1068 * of the color lookup table. Mask rev 9042EAI is known to have this bug. 1069 * 1070 * If the colourmap is not readable, we set the saved map to a default 1071 * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA 1072 * Cards" 2nd ed). 1073 */ 1074 1075 /* Only save it once */ 1076 if (hwp->cmapSaved) 1077 return; 1078 1079#if 0 1080 hwp->enablePalette(hwp); 1081#endif 1082 1083 hwp->writeDacMask(hwp, 0xFF); 1084 1085 /* 1086 * check if we can read the lookup table 1087 */ 1088 hwp->writeDacReadAddr(hwp, 0x00); 1089 for (i = 0; i < 6; i++) { 1090 save->DAC[i] = hwp->readDacData(hwp); 1091#ifdef DEBUG 1092 switch (i % 3) { 1093 case 0: 1094 ErrorF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]); 1095 break; 1096 case 1: 1097 ErrorF("0x%02x, ", save->DAC[i]); 1098 break; 1099 case 2: 1100 ErrorF("0x%02x\n", save->DAC[i]); 1101 } 1102#endif 1103 } 1104 1105 /* 1106 * Check if we can read the palette - 1107 * use foreground color to prevent flashing. 1108 */ 1109 hwp->writeDacWriteAddr(hwp, 0x01); 1110 for (i = 3; i < 6; i++) 1111 hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK); 1112 hwp->writeDacReadAddr(hwp, 0x01); 1113 for (i = 3; i < 6; i++) { 1114 if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK)) 1115 readError = TRUE; 1116 } 1117 hwp->writeDacWriteAddr(hwp, 0x01); 1118 for (i = 3; i < 6; i++) 1119 hwp->writeDacData(hwp, save->DAC[i]); 1120 1121 if (readError) { 1122 /* 1123 * save the default lookup table 1124 */ 1125 memmove(save->DAC, defaultDAC, 768); 1126 xf86DrvMsg(scrninfp->scrnIndex, X_WARNING, 1127 "Cannot read colourmap from VGA. Will restore with default\n"); 1128 } else { 1129 /* save the colourmap */ 1130 hwp->writeDacReadAddr(hwp, 0x02); 1131 for (i = 6; i < 768; i++) { 1132 save->DAC[i] = hwp->readDacData(hwp); 1133 DACDelay(hwp); 1134#ifdef DEBUG 1135 switch (i % 3) { 1136 case 0: 1137 ErrorF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]); 1138 break; 1139 case 1: 1140 ErrorF("0x%02x, ", save->DAC[i]); 1141 break; 1142 case 2: 1143 ErrorF("0x%02x\n", save->DAC[i]); 1144 } 1145#endif 1146 } 1147 } 1148 1149 hwp->disablePalette(hwp); 1150 hwp->cmapSaved = TRUE; 1151#endif 1152} 1153 1154/* 1155 * vgaHWSave -- 1156 * save the current VGA state 1157 */ 1158 1159void 1160vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags) 1161{ 1162 if (save == NULL) 1163 return; 1164 1165 if (flags & VGA_SR_CMAP) 1166 vgaHWSaveColormap(scrninfp, save); 1167 1168 if (flags & VGA_SR_MODE) 1169 vgaHWSaveMode(scrninfp, save); 1170 1171 if (flags & VGA_SR_FONTS) 1172 vgaHWSaveFonts(scrninfp, save); 1173} 1174 1175 1176/* 1177 * vgaHWInit -- 1178 * Handle the initialization, etc. of a screen. 1179 * Return FALSE on failure. 1180 */ 1181 1182Bool 1183vgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode) 1184{ 1185 unsigned int i; 1186 vgaHWPtr hwp; 1187 vgaRegPtr regp; 1188 int depth = scrninfp->depth; 1189 1190 /* 1191 * make sure the vgaHWRec is allocated 1192 */ 1193 if (!vgaHWGetHWRec(scrninfp)) 1194 return FALSE; 1195 hwp = VGAHWPTR(scrninfp); 1196 regp = &hwp->ModeReg; 1197 1198 /* 1199 * compute correct Hsync & Vsync polarity 1200 */ 1201 if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) 1202 && (mode->Flags & (V_PVSYNC | V_NVSYNC))) 1203 { 1204 regp->MiscOutReg = 0x23; 1205 if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40; 1206 if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80; 1207 } 1208 else 1209 { 1210 int VDisplay = mode->VDisplay; 1211 if (mode->Flags & V_DBLSCAN) 1212 VDisplay *= 2; 1213 if (mode->VScan > 1) 1214 VDisplay *= mode->VScan; 1215 if (VDisplay < 400) 1216 regp->MiscOutReg = 0xA3; /* +hsync -vsync */ 1217 else if (VDisplay < 480) 1218 regp->MiscOutReg = 0x63; /* -hsync +vsync */ 1219 else if (VDisplay < 768) 1220 regp->MiscOutReg = 0xE3; /* -hsync -vsync */ 1221 else 1222 regp->MiscOutReg = 0x23; /* +hsync +vsync */ 1223 } 1224 1225 regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2; 1226 1227 /* 1228 * Time Sequencer 1229 */ 1230 if (depth == 4) 1231 regp->Sequencer[0] = 0x02; 1232 else 1233 regp->Sequencer[0] = 0x00; 1234 if (mode->Flags & V_CLKDIV2) 1235 regp->Sequencer[1] = 0x09; 1236 else 1237 regp->Sequencer[1] = 0x01; 1238 if (depth == 1) 1239 regp->Sequencer[2] = 1 << BIT_PLANE; 1240 else 1241 regp->Sequencer[2] = 0x0F; 1242 regp->Sequencer[3] = 0x00; /* Font select */ 1243 if (depth < 8) 1244 regp->Sequencer[4] = 0x06; /* Misc */ 1245 else 1246 regp->Sequencer[4] = 0x0E; /* Misc */ 1247 1248 /* 1249 * CRTC Controller 1250 */ 1251 regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5; 1252 regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1; 1253 regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1; 1254 regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80; 1255 i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F); 1256 if (i < 0x80) 1257 regp->CRTC[3] |= i; 1258 regp->CRTC[4] = (mode->CrtcHSyncStart >> 3); 1259 regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2) 1260 | (((mode->CrtcHSyncEnd >> 3)) & 0x1F); 1261 regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF; 1262 regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8) 1263 | (((mode->CrtcVDisplay - 1) & 0x100) >> 7) 1264 | ((mode->CrtcVSyncStart & 0x100) >> 6) 1265 | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5) 1266 | 0x10 1267 | (((mode->CrtcVTotal - 2) & 0x200) >> 4) 1268 | (((mode->CrtcVDisplay - 1) & 0x200) >> 3) 1269 | ((mode->CrtcVSyncStart & 0x200) >> 2); 1270 regp->CRTC[8] = 0x00; 1271 regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40; 1272 if (mode->Flags & V_DBLSCAN) 1273 regp->CRTC[9] |= 0x80; 1274 if (mode->VScan >= 32) 1275 regp->CRTC[9] |= 0x1F; 1276 else if (mode->VScan > 1) 1277 regp->CRTC[9] |= mode->VScan - 1; 1278 regp->CRTC[10] = 0x00; 1279 regp->CRTC[11] = 0x00; 1280 regp->CRTC[12] = 0x00; 1281 regp->CRTC[13] = 0x00; 1282 regp->CRTC[14] = 0x00; 1283 regp->CRTC[15] = 0x00; 1284 regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF; 1285 regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20; 1286 regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF; 1287 regp->CRTC[19] = scrninfp->displayWidth >> 4; /* just a guess */ 1288 regp->CRTC[20] = 0x00; 1289 regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF; 1290 regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; 1291 if (depth < 8) 1292 regp->CRTC[23] = 0xE3; 1293 else 1294 regp->CRTC[23] = 0xC3; 1295 regp->CRTC[24] = 0xFF; 1296 1297 vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO); 1298 vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO); 1299 1300 /* 1301 * Theory resumes here.... 1302 */ 1303 1304 /* 1305 * Graphics Display Controller 1306 */ 1307 regp->Graphics[0] = 0x00; 1308 regp->Graphics[1] = 0x00; 1309 regp->Graphics[2] = 0x00; 1310 regp->Graphics[3] = 0x00; 1311 if (depth == 1) { 1312 regp->Graphics[4] = BIT_PLANE; 1313 regp->Graphics[5] = 0x00; 1314 } else { 1315 regp->Graphics[4] = 0x00; 1316 if (depth == 4) 1317 regp->Graphics[5] = 0x02; 1318 else 1319 regp->Graphics[5] = 0x40; 1320 } 1321 regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */ 1322 regp->Graphics[7] = 0x0F; 1323 regp->Graphics[8] = 0xFF; 1324 1325 if (depth == 1) { 1326 /* Initialise the Mono map according to which bit-plane gets used */ 1327 1328 Bool flipPixels = xf86GetFlipPixels(); 1329 1330 for (i=0; i<16; i++) 1331 if (((i & (1 << BIT_PLANE)) != 0) != flipPixels) 1332 regp->Attribute[i] = WHITE_VALUE; 1333 else 1334 regp->Attribute[i] = BLACK_VALUE; 1335 1336 regp->Attribute[16] = 0x01; /* -VGA2- */ /* wrong for the ET4000 */ 1337 if (!hwp->ShowOverscan) 1338 regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */ 1339 } else { 1340 regp->Attribute[0] = 0x00; /* standard colormap translation */ 1341 regp->Attribute[1] = 0x01; 1342 regp->Attribute[2] = 0x02; 1343 regp->Attribute[3] = 0x03; 1344 regp->Attribute[4] = 0x04; 1345 regp->Attribute[5] = 0x05; 1346 regp->Attribute[6] = 0x06; 1347 regp->Attribute[7] = 0x07; 1348 regp->Attribute[8] = 0x08; 1349 regp->Attribute[9] = 0x09; 1350 regp->Attribute[10] = 0x0A; 1351 regp->Attribute[11] = 0x0B; 1352 regp->Attribute[12] = 0x0C; 1353 regp->Attribute[13] = 0x0D; 1354 regp->Attribute[14] = 0x0E; 1355 regp->Attribute[15] = 0x0F; 1356 if (depth == 4) 1357 regp->Attribute[16] = 0x81; /* wrong for the ET4000 */ 1358 else 1359 regp->Attribute[16] = 0x41; /* wrong for the ET4000 */ 1360 /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */ 1361 } 1362 regp->Attribute[18] = 0x0F; 1363 regp->Attribute[19] = 0x00; 1364 regp->Attribute[20] = 0x00; 1365 1366 return(TRUE); 1367} 1368 1369 /* 1370 * OK, so much for theory. Now, let's deal with the >real< world... 1371 * 1372 * The above CRTC settings are precise in theory, except that many, if not 1373 * most, VGA clones fail to reset the blanking signal when the character or 1374 * line counter reaches [HV]Total. In this case, the signal is only 1375 * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as 1376 * the case may be) at the start of the >next< scanline or frame, which 1377 * means only part of the screen shows. This affects how null overscans 1378 * are to be implemented on such adapters. 1379 * 1380 * Henceforth, VGA cores that implement this broken, but unfortunately 1381 * common, behaviour are to be designated as KGA's, in honour of Koen 1382 * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion 1383 * a series of events that led to the discovery of this problem. 1384 * 1385 * Some VGA's are KGA's only in the horizontal, or only in the vertical, 1386 * some in both, others in neither. Don't let anyone tell you there is 1387 * such a thing as a VGA "standard"... And, thank the Creator for the fact 1388 * that Hilbert spaces are not yet implemented in this industry. 1389 * 1390 * The following implements a trick suggested by David Dawes. This sets 1391 * [HV]BlankEnd to zero if the blanking interval does not already contain a 1392 * 0-point, and decrements it by one otherwise. In the latter case, this 1393 * will produce a left and/or top overscan which the colourmap code will 1394 * (still) need to ensure is as close to black as possible. This will make 1395 * the behaviour consistent across all chipsets, while allowing all 1396 * chipsets to display the entire screen. Non-KGA drivers can ignore the 1397 * following in their own copy of this code. 1398 * 1399 * -- TSI @ UQV, 1998.08.21 1400 */ 1401 1402CARD32 1403vgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 1404 unsigned int Flags) 1405{ 1406 int nExtBits = (nBits < 6) ? 0 : nBits - 6; 1407 CARD32 ExtBits; 1408 CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6; 1409 1410 regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) 1411 | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F); 1412 regp->CRTC[5] = (regp->CRTC[5] & ~0x80) 1413 | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2); 1414 ExtBits = ((mode->CrtcHBlankEnd >> 3) - 1) & ExtBitMask; 1415 1416 /* First the horizontal case */ 1417 if ((Flags & KGA_FIX_OVERSCAN) 1418 && ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3))) 1419 { 1420 int i = (regp->CRTC[3] & 0x1F) 1421 | ((regp->CRTC[5] & 0x80) >> 2) 1422 | ExtBits; 1423 if (Flags & KGA_ENABLE_ON_ZERO) { 1424 if ((i-- > (((mode->CrtcHBlankStart >> 3) - 1) 1425 & (0x3F | ExtBitMask))) 1426 && (mode->CrtcHBlankEnd == mode->CrtcHTotal)) 1427 i = 0; 1428 } else if (Flags & KGA_BE_TOT_DEC) 1429 i--; 1430 regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F); 1431 regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80); 1432 ExtBits = i & ExtBitMask; 1433 } 1434 return ExtBits >> 6; 1435} 1436 1437 /* 1438 * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of 1439 * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the 1440 * very first scanline in a double- or multi-scanned mode. This last case 1441 * needs further investigation. 1442 */ 1443CARD32 1444vgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 1445 unsigned int Flags) 1446{ 1447 CARD32 ExtBits; 1448 CARD32 nExtBits = (nBits < 8) ? 0 : (nBits - 8); 1449 CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 8; 1450 /* If width is not known nBits should be 0. In this 1451 * case BitMask is set to 0 so we can check for it. */ 1452 CARD32 BitMask = (nBits < 7) ? 0 : ((1 << nExtBits) - 1); 1453 int VBlankStart = (mode->CrtcVBlankStart - 1) & 0xFF; 1454 regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; 1455 ExtBits = (mode->CrtcVBlankEnd - 1) & ExtBitMask; 1456 1457 if ((Flags & KGA_FIX_OVERSCAN) 1458 && (mode->CrtcVBlankEnd == mode->CrtcVTotal)) 1459 /* Null top overscan */ 1460 { 1461 int i = regp->CRTC[22] | ExtBits; 1462 if (Flags & KGA_ENABLE_ON_ZERO) { 1463 if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask))) 1464 || ((i > VBlankStart) && /* 8-bit case */ 1465 ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */ 1466 !(regp->CRTC[9] & 0x9F)) /* 1 scanline/row */ 1467 i = 0; 1468 else 1469 i = (i - 1); 1470 } else if (Flags & KGA_BE_TOT_DEC) 1471 i = (i - 1); 1472 1473 regp->CRTC[22] = i & 0xFF; 1474 ExtBits = i & 0xFF00; 1475 } 1476 return ExtBits >> 8; 1477} 1478 1479/* 1480 * these are some more hardware specific helpers, formerly in vga.c 1481 */ 1482static void 1483vgaHWGetHWRecPrivate(void) 1484{ 1485 if (vgaHWPrivateIndex < 0) 1486 vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); 1487 return; 1488} 1489 1490 1491static void 1492vgaHWFreeRegs(vgaRegPtr regp) 1493{ 1494 if (regp->CRTC) 1495 xfree (regp->CRTC); 1496 1497 regp->CRTC = 1498 regp->Sequencer = 1499 regp->Graphics = 1500 regp->Attribute = NULL; 1501 1502 regp->numCRTC = 1503 regp->numSequencer = 1504 regp->numGraphics = 1505 regp->numAttribute = 0; 1506} 1507 1508 1509 1510static Bool 1511vgaHWAllocRegs(vgaRegPtr regp) 1512{ 1513 unsigned char *buf; 1514 1515 if ((regp->numCRTC + regp->numSequencer + regp->numGraphics + 1516 regp->numAttribute) == 0) 1517 return FALSE; 1518 1519 buf = xcalloc(regp->numCRTC + 1520 regp->numSequencer + 1521 regp->numGraphics + 1522 regp->numAttribute, 1); 1523 if (!buf) 1524 return FALSE; 1525 1526 regp->CRTC = buf; 1527 regp->Sequencer = regp->CRTC + regp->numCRTC; 1528 regp->Graphics = regp->Sequencer + regp->numSequencer; 1529 regp->Attribute = regp->Graphics + regp->numGraphics; 1530 1531 return TRUE; 1532} 1533 1534 1535Bool 1536vgaHWAllocDefaultRegs(vgaRegPtr regp) 1537{ 1538 regp->numCRTC = VGA_NUM_CRTC; 1539 regp->numSequencer = VGA_NUM_SEQ; 1540 regp->numGraphics = VGA_NUM_GFX; 1541 regp->numAttribute = VGA_NUM_ATTR; 1542 1543 return vgaHWAllocRegs(regp); 1544} 1545 1546 1547Bool 1548vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer, 1549 int numGraphics, int numAttribute) 1550{ 1551#define VGAHWMINNUM(regtype) \ 1552 ((newMode.num##regtype < regp->num##regtype) ? \ 1553 (newMode.num##regtype) : (regp->num##regtype)) 1554#define VGAHWCOPYREGSET(regtype) \ 1555 memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype)) 1556 1557 vgaRegRec newMode, newSaved; 1558 vgaRegPtr regp; 1559 1560 regp = &VGAHWPTR(scrp)->ModeReg; 1561 memcpy (&newMode, regp, sizeof(vgaRegRec)); 1562 1563 /* allocate space for new registers */ 1564 1565 regp = &newMode; 1566 regp->numCRTC = numCRTC; 1567 regp->numSequencer = numSequencer; 1568 regp->numGraphics = numGraphics; 1569 regp->numAttribute = numAttribute; 1570 if (!vgaHWAllocRegs(regp)) 1571 return FALSE; 1572 1573 regp = &VGAHWPTR(scrp)->SavedReg; 1574 memcpy (&newSaved, regp, sizeof(vgaRegRec)); 1575 1576 regp = &newSaved; 1577 regp->numCRTC = numCRTC; 1578 regp->numSequencer = numSequencer; 1579 regp->numGraphics = numGraphics; 1580 regp->numAttribute = numAttribute; 1581 if (!vgaHWAllocRegs(regp)) { 1582 vgaHWFreeRegs(&newMode); 1583 return FALSE; 1584 } 1585 1586 /* allocations succeeded, copy register data into new space */ 1587 1588 regp = &VGAHWPTR(scrp)->ModeReg; 1589 VGAHWCOPYREGSET(CRTC); 1590 VGAHWCOPYREGSET(Sequencer); 1591 VGAHWCOPYREGSET(Graphics); 1592 VGAHWCOPYREGSET(Attribute); 1593 1594 regp = &VGAHWPTR(scrp)->SavedReg; 1595 VGAHWCOPYREGSET(CRTC); 1596 VGAHWCOPYREGSET(Sequencer); 1597 VGAHWCOPYREGSET(Graphics); 1598 VGAHWCOPYREGSET(Attribute); 1599 1600 /* free old register arrays */ 1601 1602 regp = &VGAHWPTR(scrp)->ModeReg; 1603 vgaHWFreeRegs(regp); 1604 memcpy(regp, &newMode, sizeof(vgaRegRec)); 1605 1606 regp = &VGAHWPTR(scrp)->SavedReg; 1607 vgaHWFreeRegs(regp); 1608 memcpy(regp, &newSaved, sizeof(vgaRegRec)); 1609 1610 return TRUE; 1611 1612#undef VGAHWMINNUM 1613#undef VGAHWCOPYREGSET 1614} 1615 1616 1617Bool 1618vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src) 1619{ 1620 vgaHWFreeRegs(dst); 1621 1622 memcpy(dst, src, sizeof(vgaRegRec)); 1623 1624 if (!vgaHWAllocRegs(dst)) 1625 return FALSE; 1626 1627 memcpy(dst->CRTC, src->CRTC, src->numCRTC); 1628 memcpy(dst->Sequencer, src->Sequencer, src->numSequencer); 1629 memcpy(dst->Graphics, src->Graphics, src->numGraphics); 1630 memcpy(dst->Attribute, src->Attribute, src->numAttribute); 1631 1632 return TRUE; 1633} 1634 1635 1636Bool 1637vgaHWGetHWRec(ScrnInfoPtr scrp) 1638{ 1639 vgaRegPtr regp; 1640 vgaHWPtr hwp; 1641 int i; 1642 1643 /* 1644 * Let's make sure that the private exists and allocate one. 1645 */ 1646 vgaHWGetHWRecPrivate(); 1647 /* 1648 * New privates are always set to NULL, so we can check if the allocation 1649 * has already been done. 1650 */ 1651 if (VGAHWPTR(scrp)) 1652 return TRUE; 1653 hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1); 1654 regp = &VGAHWPTR(scrp)->ModeReg; 1655 1656 if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) || 1657 (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) { 1658 xfree(hwp); 1659 return FALSE; 1660 } 1661 1662 if (scrp->bitsPerPixel == 1) { 1663 rgb blackColour = scrp->display->blackColour, 1664 whiteColour = scrp->display->whiteColour; 1665 1666 if (blackColour.red > 0x3F) blackColour.red = 0x3F; 1667 if (blackColour.green > 0x3F) blackColour.green = 0x3F; 1668 if (blackColour.blue > 0x3F) blackColour.blue = 0x3F; 1669 1670 if (whiteColour.red > 0x3F) whiteColour.red = 0x3F; 1671 if (whiteColour.green > 0x3F) whiteColour.green = 0x3F; 1672 if (whiteColour.blue > 0x3F) whiteColour.blue = 0x3F; 1673 1674 if ((blackColour.red == whiteColour.red ) && 1675 (blackColour.green == whiteColour.green) && 1676 (blackColour.blue == whiteColour.blue )) { 1677 blackColour.red ^= 0x3F; 1678 blackColour.green ^= 0x3F; 1679 blackColour.blue ^= 0x3F; 1680 } 1681 1682 /* 1683 * initialize default colormap for monochrome 1684 */ 1685 for (i=0; i<3; i++) regp->DAC[i] = 0x00; 1686 for (i=3; i<768; i++) regp->DAC[i] = 0x3F; 1687 i = BLACK_VALUE * 3; 1688 regp->DAC[i++] = blackColour.red; 1689 regp->DAC[i++] = blackColour.green; 1690 regp->DAC[i] = blackColour.blue; 1691 i = WHITE_VALUE * 3; 1692 regp->DAC[i++] = whiteColour.red; 1693 regp->DAC[i++] = whiteColour.green; 1694 regp->DAC[i] = whiteColour.blue; 1695 i = OVERSCAN_VALUE * 3; 1696 regp->DAC[i++] = 0x00; 1697 regp->DAC[i++] = 0x00; 1698 regp->DAC[i] = 0x00; 1699 } else { 1700 /* Set all colours to black */ 1701 for (i=0; i<768; i++) regp->DAC[i] = 0x00; 1702 /* ... and the overscan */ 1703 if (scrp->depth >= 4) 1704 regp->Attribute[OVERSCAN] = 0xFF; 1705 } 1706 if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) { 1707 xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan"); 1708 xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n"); 1709 regp->DAC[765] = 0x3F; 1710 regp->DAC[766] = 0x00; 1711 regp->DAC[767] = 0x3F; 1712 regp->Attribute[OVERSCAN] = 0xFF; 1713 hwp->ShowOverscan = TRUE; 1714 } else 1715 hwp->ShowOverscan = FALSE; 1716 1717 hwp->paletteEnabled = FALSE; 1718 hwp->cmapSaved = FALSE; 1719 hwp->MapSize = 0; 1720 hwp->pScrn = scrp; 1721 1722 /* Initialise the function pointers with the standard VGA versions */ 1723 vgaHWSetStdFuncs(hwp); 1724 1725 hwp->PIOOffset = scrp->domainIOBase; 1726 hwp->dev = xf86GetPciInfoForEntity(scrp->entityList[0]); 1727 1728 return TRUE; 1729} 1730 1731 1732void 1733vgaHWFreeHWRec(ScrnInfoPtr scrp) 1734{ 1735 if (vgaHWPrivateIndex >= 0) { 1736 vgaHWPtr hwp = VGAHWPTR(scrp); 1737 1738 if (!hwp) 1739 return; 1740 1741 xfree(hwp->FontInfo1); 1742 xfree(hwp->FontInfo2); 1743 xfree(hwp->TextInfo); 1744 1745 vgaHWFreeRegs (&hwp->ModeReg); 1746 vgaHWFreeRegs (&hwp->SavedReg); 1747 1748 xfree(hwp); 1749 VGAHWPTRLVAL(scrp) = NULL; 1750 } 1751} 1752 1753 1754Bool 1755vgaHWMapMem(ScrnInfoPtr scrp) 1756{ 1757 vgaHWPtr hwp = VGAHWPTR(scrp); 1758 int scr_index = scrp->scrnIndex; 1759 1760 if (hwp->Base) 1761 return TRUE; 1762 1763 /* If not set, initialise with the defaults */ 1764 if (hwp->MapSize == 0) 1765 hwp->MapSize = VGA_DEFAULT_MEM_SIZE; 1766 if (hwp->MapPhys == 0) 1767 hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR; 1768 1769 /* 1770 * Map as VIDMEM_MMIO_32BIT because WC 1771 * is bad when there is page flipping. 1772 * XXX This is not correct but we do it 1773 * for now. 1774 */ 1775#ifdef DEBUG 1776 ErrorF("Mapping VGAMem\n"); 1777#endif 1778 hwp->Base = xf86MapDomainMemory(scr_index, VIDMEM_MMIO_32BIT, hwp->dev, 1779 hwp->MapPhys, hwp->MapSize); 1780 return hwp->Base != NULL; 1781} 1782 1783 1784void 1785vgaHWUnmapMem(ScrnInfoPtr scrp) 1786{ 1787 vgaHWPtr hwp = VGAHWPTR(scrp); 1788 int scr_index = scrp->scrnIndex; 1789 1790 if (hwp->Base == NULL) 1791 return; 1792 1793#ifdef DEBUG 1794 ErrorF("Unmapping VGAMem\n"); 1795#endif 1796 xf86UnMapVidMem(scr_index, hwp->Base, hwp->MapSize); 1797 hwp->Base = NULL; 1798} 1799 1800int 1801vgaHWGetIndex() 1802{ 1803 return vgaHWPrivateIndex; 1804} 1805 1806 1807void 1808vgaHWGetIOBase(vgaHWPtr hwp) 1809{ 1810 hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ? 1811 VGA_IOBASE_COLOR : VGA_IOBASE_MONO; 1812 xf86DrvMsgVerb(hwp->pScrn->scrnIndex, X_INFO, 3, 1813 "vgaHWGetIOBase: hwp->IOBase is 0x%04x, hwp->PIOOffset is 0x%04lx\n", 1814 hwp->IOBase, hwp->PIOOffset); 1815} 1816 1817 1818void 1819vgaHWLock(vgaHWPtr hwp) 1820{ 1821 /* Protect CRTC[0-7] */ 1822 hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80); 1823} 1824 1825void 1826vgaHWUnlock(vgaHWPtr hwp) 1827{ 1828 /* Unprotect CRTC[0-7] */ 1829 hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80); 1830} 1831 1832 1833void 1834vgaHWEnable(vgaHWPtr hwp) 1835{ 1836 hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01); 1837} 1838 1839 1840void 1841vgaHWDisable(vgaHWPtr hwp) 1842{ 1843 hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01); 1844} 1845 1846 1847static void 1848vgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, 1849 VisualPtr pVisual) 1850{ 1851 vgaHWPtr hwp = VGAHWPTR(pScrn); 1852 int i, index; 1853 1854 for (i = 0; i < numColors; i++) { 1855 index = indices[i]; 1856 hwp->writeDacWriteAddr(hwp, index); 1857 DACDelay(hwp); 1858 hwp->writeDacData(hwp, colors[index].red); 1859 DACDelay(hwp); 1860 hwp->writeDacData(hwp, colors[index].green); 1861 DACDelay(hwp); 1862 hwp->writeDacData(hwp, colors[index].blue); 1863 DACDelay(hwp); 1864 } 1865 1866 /* This shouldn't be necessary, but we'll play safe. */ 1867 hwp->disablePalette(hwp); 1868} 1869 1870 1871static void 1872vgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan) 1873{ 1874 vgaHWPtr hwp = VGAHWPTR(pScrn); 1875 1876 if (overscan < 0 || overscan > 255) 1877 return; 1878 1879 hwp->enablePalette(hwp); 1880 hwp->writeAttr(hwp, OVERSCAN, overscan); 1881 1882#ifdef DEBUGOVERSCAN 1883 { 1884 int ov = hwp->readAttr(hwp, OVERSCAN); 1885 int red, green, blue; 1886 1887 hwp->writeDacReadAddr(hwp, ov); 1888 red = hwp->readDacData(hwp); 1889 green = hwp->readDacData(hwp); 1890 blue = hwp->readDacData(hwp); 1891 ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n", 1892 ov, red, green, blue); 1893 } 1894#endif 1895 1896 hwp->disablePalette(hwp); 1897} 1898 1899 1900Bool 1901vgaHWHandleColormaps(ScreenPtr pScreen) 1902{ 1903 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1904 1905 if (pScrn->depth > 1 && pScrn->depth <= 8) { 1906 return xf86HandleColormaps(pScreen, 1 << pScrn->depth, 1907 pScrn->rgbBits, vgaHWLoadPalette, 1908 pScrn->depth > 4 ? vgaHWSetOverscan : NULL, 1909 CMAP_RELOAD_ON_MODE_SWITCH); 1910 } 1911 return TRUE; 1912} 1913 1914/* ----------------------- DDC support ------------------------*/ 1915/* 1916 * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total 1917 * to read out EDID at a faster rate. Allowed maximum is 25kHz with 1918 * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen 1919 * readback, enable access to cr00-cr07. 1920 */ 1921 1922/* vertical timings */ 1923#define DISPLAY_END 0x04 1924#define BLANK_START DISPLAY_END 1925#define SYNC_START BLANK_START 1926#define SYNC_END 0x09 1927#define BLANK_END SYNC_END 1928#define V_TOTAL BLANK_END 1929/* this function doesn't have to be reentrant for our purposes */ 1930struct _vgaDdcSave { 1931 unsigned char cr03; 1932 unsigned char cr06; 1933 unsigned char cr07; 1934 unsigned char cr09; 1935 unsigned char cr10; 1936 unsigned char cr11; 1937 unsigned char cr12; 1938 unsigned char cr15; 1939 unsigned char cr16; 1940 unsigned char msr; 1941}; 1942 1943void 1944vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed) 1945{ 1946 vgaHWPtr hwp = VGAHWPTR(pScrn); 1947 unsigned char tmp; 1948 struct _vgaDdcSave* save; 1949 switch (speed) { 1950 case DDC_FAST: 1951 1952 if (hwp->ddc != NULL) break; 1953 hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave),1); 1954 save = (struct _vgaDdcSave *)hwp->ddc; 1955 /* Lightpen register disable - allow access to cr10 & 11; just in case */ 1956 save->cr03 = hwp->readCrtc(hwp, 0x03); 1957 hwp->writeCrtc(hwp,0x03,(save->cr03 |0x80)); 1958 save->cr12 = hwp->readCrtc(hwp, 0x12); 1959 hwp->writeCrtc(hwp,0x12,DISPLAY_END); 1960 save->cr15 = hwp->readCrtc(hwp, 0x15); 1961 hwp->writeCrtc(hwp,0x15,BLANK_START); 1962 save->cr10 = hwp->readCrtc(hwp, 0x10); 1963 hwp->writeCrtc(hwp,0x10,SYNC_START); 1964 save->cr11 = hwp->readCrtc(hwp, 0x11); 1965 /* unprotect group 1 registers; just in case ...*/ 1966 hwp->writeCrtc(hwp,0x11,((save->cr11 & 0x70) | SYNC_END)); 1967 save->cr16 = hwp->readCrtc(hwp, 0x16); 1968 hwp->writeCrtc(hwp,0x16,BLANK_END); 1969 save->cr06 = hwp->readCrtc(hwp, 0x06); 1970 hwp->writeCrtc(hwp,0x06,V_TOTAL); 1971 /* all values have less than 8 bit - mask out 9th and 10th bits */ 1972 save->cr09 = hwp->readCrtc(hwp, 0x09); 1973 hwp->writeCrtc(hwp,0x09,(save->cr09 &0xDF)); 1974 save->cr07 = hwp->readCrtc(hwp, 0x07); 1975 hwp->writeCrtc(hwp,0x07,(save->cr07 &0x10)); 1976 /* vsync polarity negativ & ensure a 25MHz clock */ 1977 save->msr = hwp->readMiscOut(hwp); 1978 hwp->writeMiscOut(hwp,((save->msr & 0xF3) | 0x80)); 1979 break; 1980 case DDC_SLOW: 1981 if (hwp->ddc == NULL) break; 1982 save = (struct _vgaDdcSave *)hwp->ddc; 1983 hwp->writeMiscOut(hwp,save->msr); 1984 hwp->writeCrtc(hwp,0x07,save->cr07); 1985 tmp = hwp->readCrtc(hwp, 0x09); 1986 hwp->writeCrtc(hwp,0x09,((save->cr09 & 0x20) | (tmp & 0xDF))); 1987 hwp->writeCrtc(hwp,0x06,save->cr06); 1988 hwp->writeCrtc(hwp,0x16,save->cr16); 1989 hwp->writeCrtc(hwp,0x11,save->cr11); 1990 hwp->writeCrtc(hwp,0x10,save->cr10); 1991 hwp->writeCrtc(hwp,0x15,save->cr15); 1992 hwp->writeCrtc(hwp,0x12,save->cr12); 1993 hwp->writeCrtc(hwp,0x03,save->cr03); 1994 xfree(save); 1995 hwp->ddc = NULL; 1996 break; 1997 default: 1998 break; 1999 } 2000} 2001 2002DDC1SetSpeedProc vgaHWddc1SetSpeedWeak(void) { return vgaHWddc1SetSpeed; } 2003 2004SaveScreenProcPtr vgaHWSaveScreenWeak(void) { return vgaHWSaveScreen; } 2005