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