First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / vgahw / vgaHW.c
blob36fd0099d2b71c2f4ad28129b68cd2ee38abc531
2 /*
4 * Copyright 1991-1999 by The XFree86 Project, Inc.
6 * Loosely based on code bearing the following copyright:
8 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
12 #define _NEED_SYSI86
14 #ifdef HAVE_XORG_CONFIG_H
15 #include <xorg-config.h>
16 #endif
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
22 #include <X11/X.h>
23 #include "misc.h"
25 #include "xf86.h"
26 #include "xf86_OSproc.h"
27 #include "vgaHW.h"
29 #include "compiler.h"
31 #include "xf86cmap.h"
33 #ifndef SAVE_FONT1
34 #define SAVE_FONT1 1
35 #endif
38 * These used to be OS-specific, which made this module have an undesirable
39 * OS dependency. Define them by default for all platforms.
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
51 /* bytes per plane to save for text */
52 #define TEXT_AMOUNT 16384
54 /* bytes per plane to save for font data */
55 #define FONT_AMOUNT (8*8192)
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
71 /* DAC indices for white and black */
72 #define WHITE_VALUE 0x3F
73 #define BLACK_VALUE 0x00
74 #define OVERSCAN_VALUE 0x01
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)))
82 static int vgaHWPrivateIndex = -1;
84 #define DAC_TEST_MASK 0x3F
86 #ifdef NEED_SAVED_CMAP
87 /* This default colourmap is used only when it can't be read from the VGA */
89 static CARD8 defaultDAC[768] =
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,
156 #endif /* NEED_SAVED_CMAP */
159 * Standard VGA versions of the register access functions.
161 static void
162 stdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
164 outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index);
165 outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET, value);
168 static CARD8
169 stdReadCrtc(vgaHWPtr hwp, CARD8 index)
171 outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index);
172 return inb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET);
175 static void
176 stdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
178 outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index);
179 outb(hwp->PIOOffset + VGA_GRAPH_DATA, value);
182 static CARD8
183 stdReadGr(vgaHWPtr hwp, CARD8 index)
185 outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index);
186 return inb(hwp->PIOOffset + VGA_GRAPH_DATA);
189 static void
190 stdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
192 outb(hwp->PIOOffset + VGA_SEQ_INDEX, index);
193 outb(hwp->PIOOffset + VGA_SEQ_DATA, value);
196 static CARD8
197 stdReadSeq(vgaHWPtr hwp, CARD8 index)
199 outb(hwp->PIOOffset + VGA_SEQ_INDEX, index);
200 return inb(hwp->PIOOffset + VGA_SEQ_DATA);
203 static CARD8
204 stdReadST00(vgaHWPtr hwp)
206 return inb(hwp->PIOOffset + VGA_IN_STAT_0);
209 static CARD8
210 stdReadST01(vgaHWPtr hwp)
212 return inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
215 static CARD8
216 stdReadFCR(vgaHWPtr hwp)
218 return inb(hwp->PIOOffset + VGA_FEATURE_R);
221 static void
222 stdWriteFCR(vgaHWPtr hwp, CARD8 value)
224 outb(hwp->IOBase + hwp->PIOOffset + VGA_FEATURE_W_OFFSET,value);
227 static void
228 stdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
230 if (hwp->paletteEnabled)
231 index &= ~0x20;
232 else
233 index |= 0x20;
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);
240 static CARD8
241 stdReadAttr(vgaHWPtr hwp, CARD8 index)
243 if (hwp->paletteEnabled)
244 index &= ~0x20;
245 else
246 index |= 0x20;
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);
253 static void
254 stdWriteMiscOut(vgaHWPtr hwp, CARD8 value)
256 outb(hwp->PIOOffset + VGA_MISC_OUT_W, value);
259 static CARD8
260 stdReadMiscOut(vgaHWPtr hwp)
262 return inb(hwp->PIOOffset + VGA_MISC_OUT_R);
265 static void
266 stdEnablePalette(vgaHWPtr hwp)
268 (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
269 outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x00);
270 hwp->paletteEnabled = TRUE;
273 static void
274 stdDisablePalette(vgaHWPtr hwp)
276 (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
277 outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x20);
278 hwp->paletteEnabled = FALSE;
281 static void
282 stdWriteDacMask(vgaHWPtr hwp, CARD8 value)
284 outb(hwp->PIOOffset + VGA_DAC_MASK, value);
287 static CARD8
288 stdReadDacMask(vgaHWPtr hwp)
290 return inb(hwp->PIOOffset + VGA_DAC_MASK);
293 static void
294 stdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
296 outb(hwp->PIOOffset + VGA_DAC_READ_ADDR, value);
299 static void
300 stdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
302 outb(hwp->PIOOffset + VGA_DAC_WRITE_ADDR, value);
305 static void
306 stdWriteDacData(vgaHWPtr hwp, CARD8 value)
308 outb(hwp->PIOOffset + VGA_DAC_DATA, value);
311 static CARD8
312 stdReadDacData(vgaHWPtr hwp)
314 return inb(hwp->PIOOffset + VGA_DAC_DATA);
317 static CARD8
318 stdReadEnable(vgaHWPtr hwp)
320 return inb(hwp->PIOOffset + VGA_ENABLE);
323 static void
324 stdWriteEnable(vgaHWPtr hwp, CARD8 value)
326 outb(hwp->PIOOffset + VGA_ENABLE, value);
329 void
330 vgaHWSetStdFuncs(vgaHWPtr hwp)
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;
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.
365 #define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p)))
366 #define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v))
368 static void
369 mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
371 moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
372 moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
375 static CARD8
376 mmioReadCrtc(vgaHWPtr hwp, CARD8 index)
378 moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
379 return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET);
382 static void
383 mmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
385 moutb(VGA_GRAPH_INDEX, index);
386 moutb(VGA_GRAPH_DATA, value);
389 static CARD8
390 mmioReadGr(vgaHWPtr hwp, CARD8 index)
392 moutb(VGA_GRAPH_INDEX, index);
393 return minb(VGA_GRAPH_DATA);
396 static void
397 mmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
399 moutb(VGA_SEQ_INDEX, index);
400 moutb(VGA_SEQ_DATA, value);
403 static CARD8
404 mmioReadSeq(vgaHWPtr hwp, CARD8 index)
406 moutb(VGA_SEQ_INDEX, index);
407 return minb(VGA_SEQ_DATA);
410 static CARD8
411 mmioReadST00(vgaHWPtr hwp)
413 return minb(VGA_IN_STAT_0);
416 static CARD8
417 mmioReadST01(vgaHWPtr hwp)
419 return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
422 static CARD8
423 mmioReadFCR(vgaHWPtr hwp)
425 return minb(VGA_FEATURE_R);
428 static void
429 mmioWriteFCR(vgaHWPtr hwp, CARD8 value)
431 moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET,value);
434 static void
435 mmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
437 if (hwp->paletteEnabled)
438 index &= ~0x20;
439 else
440 index |= 0x20;
442 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
443 moutb(VGA_ATTR_INDEX, index);
444 moutb(VGA_ATTR_DATA_W, value);
447 static CARD8
448 mmioReadAttr(vgaHWPtr hwp, CARD8 index)
450 if (hwp->paletteEnabled)
451 index &= ~0x20;
452 else
453 index |= 0x20;
455 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
456 moutb(VGA_ATTR_INDEX, index);
457 return minb(VGA_ATTR_DATA_R);
460 static void
461 mmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
463 moutb(VGA_MISC_OUT_W, value);
466 static CARD8
467 mmioReadMiscOut(vgaHWPtr hwp)
469 return minb(VGA_MISC_OUT_R);
472 static void
473 mmioEnablePalette(vgaHWPtr hwp)
475 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
476 moutb(VGA_ATTR_INDEX, 0x00);
477 hwp->paletteEnabled = TRUE;
480 static void
481 mmioDisablePalette(vgaHWPtr hwp)
483 (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
484 moutb(VGA_ATTR_INDEX, 0x20);
485 hwp->paletteEnabled = FALSE;
488 static void
489 mmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
491 moutb(VGA_DAC_MASK, value);
494 static CARD8
495 mmioReadDacMask(vgaHWPtr hwp)
497 return minb(VGA_DAC_MASK);
500 static void
501 mmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
503 moutb(VGA_DAC_READ_ADDR, value);
506 static void
507 mmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
509 moutb(VGA_DAC_WRITE_ADDR, value);
512 static void
513 mmioWriteDacData(vgaHWPtr hwp, CARD8 value)
515 moutb(VGA_DAC_DATA, value);
518 static CARD8
519 mmioReadDacData(vgaHWPtr hwp)
521 return minb(VGA_DAC_DATA);
524 static CARD8
525 mmioReadEnable(vgaHWPtr hwp)
527 return minb(VGA_ENABLE);
530 static void
531 mmioWriteEnable(vgaHWPtr hwp, CARD8 value)
533 moutb(VGA_ENABLE, value);
536 void
537 vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)
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;
568 * vgaHWProtect --
569 * Protect VGA registers and memory from corruption during loads.
572 void
573 vgaHWProtect(ScrnInfoPtr pScrn, Bool on)
575 vgaHWPtr hwp = VGAHWPTR(pScrn);
577 unsigned char tmp;
579 if (pScrn->vtSema) {
580 if (on) {
582 * Turn off screen and disable sequencer.
584 tmp = hwp->readSeq(hwp, 0x01);
586 vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */
587 hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
589 hwp->enablePalette(hwp);
590 } else {
592 * Reenable sequencer, then turn on screen.
595 tmp = hwp->readSeq(hwp, 0x01);
597 hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */
598 vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */
600 hwp->disablePalette(hwp);
605 vgaHWProtectProc *vgaHWProtectWeak(void) {
606 return vgaHWProtect;
610 * vgaHWBlankScreen -- blank the screen.
613 void
614 vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)
616 vgaHWPtr hwp = VGAHWPTR(pScrn);
617 unsigned char scrn;
619 scrn = hwp->readSeq(hwp, 0x01);
621 if (on) {
622 scrn &= ~0x20; /* enable screen */
623 } else {
624 scrn |= 0x20; /* blank screen */
627 vgaHWSeqReset(hwp, TRUE);
628 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
629 vgaHWSeqReset(hwp, FALSE);
632 vgaHWBlankScreenProc *vgaHWBlankScreenWeak(void) {
633 return vgaHWBlankScreen;
637 * vgaHWSaveScreen -- blank the screen.
640 Bool
641 vgaHWSaveScreen(ScreenPtr pScreen, int mode)
643 ScrnInfoPtr pScrn = NULL;
644 Bool on;
646 if (pScreen != NULL)
647 pScrn = xf86Screens[pScreen->myNum];
649 on = xf86IsUnblank(mode);
651 #if 0
652 if (on)
653 SetTimeSinceLastInputEvent();
654 #endif
656 if ((pScrn != NULL) && pScrn->vtSema) {
657 vgaHWBlankScreen(pScrn, on);
659 return (TRUE);
664 * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode
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.
671 void
672 vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
674 unsigned char seq1 = 0, crtc17 = 0;
675 vgaHWPtr hwp = VGAHWPTR(pScrn);
677 if (!pScrn->vtSema) return;
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;
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 */
712 * vgaHWSeqReset
713 * perform a sequencer reset.
716 void
717 vgaHWSeqReset(vgaHWPtr hwp, Bool start)
719 if (start)
720 hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
721 else
722 hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
726 void
727 vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
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;
735 /* If nothing to do, return now */
736 if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
737 return;
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;
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);
760 /* save hwp->IOBase and temporarily set it for colour mode */
761 savedIOBase = hwp->IOBase;
762 hwp->IOBase = VGA_IOBASE_COLOR;
764 /* Force into colour mode */
765 hwp->writeMiscOut(hwp, miscOut | 0x01);
767 vgaHWBlankScreen(scrninfp, FALSE);
770 * here we temporarily switch to 16 colour planar mode, to simply
771 * copy the font-info and saved text.
773 * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
775 #if 0
776 hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
777 #endif
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 */
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 */
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);
796 #endif
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);
804 #endif
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);
816 #endif
818 vgaHWBlankScreen(scrninfp, TRUE);
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;
833 if (doMap)
834 vgaHWUnmapMem(scrninfp);
836 #endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
840 void
841 vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
843 vgaHWPtr hwp = VGAHWPTR(scrninfp);
844 int i;
846 if (restore->MiscOutReg & 0x01)
847 hwp->IOBase = VGA_IOBASE_COLOR;
848 else
849 hwp->IOBase = VGA_IOBASE_MONO;
851 hwp->writeMiscOut(hwp, restore->MiscOutReg);
853 for (i = 1; i < restore->numSequencer; i++)
854 hwp->writeSeq(hwp, i, restore->Sequencer[i]);
856 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
857 hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
859 for (i = 0; i < restore->numCRTC; i++)
860 hwp->writeCrtc(hwp, i, restore->CRTC[i]);
862 for (i = 0; i < restore->numGraphics; i++)
863 hwp->writeGr(hwp, i, restore->Graphics[i]);
865 hwp->enablePalette(hwp);
866 for (i = 0; i < restore->numAttribute; i++)
867 hwp->writeAttr(hwp, i, restore->Attribute[i]);
868 hwp->disablePalette(hwp);
872 void
873 vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore)
875 vgaHWPtr hwp = VGAHWPTR(scrninfp);
876 int i;
878 #if 0
879 hwp->enablePalette(hwp);
880 #endif
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);
889 hwp->disablePalette(hwp);
894 * vgaHWRestore --
895 * restore the VGA state
898 void
899 vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags)
901 if (flags & VGA_SR_MODE)
902 vgaHWRestoreMode(scrninfp, restore);
904 if (flags & VGA_SR_FONTS)
905 vgaHWRestoreFonts(scrninfp, restore);
907 if (flags & VGA_SR_CMAP)
908 vgaHWRestoreColormap(scrninfp, restore);
911 void
912 vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
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;
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;
929 /* If in graphics mode, don't save anything */
930 attr10 = hwp->readAttr(hwp, 0x10);
931 if (attr10 & 0x01)
932 return;
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);
942 /* save hwp->IOBase and temporarily set it for colour mode */
943 savedIOBase = hwp->IOBase;
944 hwp->IOBase = VGA_IOBASE_COLOR;
946 /* Force into colour mode */
947 hwp->writeMiscOut(hwp, miscOut | 0x01);
949 vgaHWBlankScreen(scrninfp, FALSE);
952 * get the character sets, and text screen if required
955 * Here we temporarily switch to 16 colour planar mode, to simply
956 * copy the font-info
958 * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
960 #if 0
961 hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
962 #endif
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 */
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);
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);
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);
992 #endif /* SAVE_TEXT */
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;
1004 vgaHWBlankScreen(scrninfp, TRUE);
1006 if (doMap)
1007 vgaHWUnmapMem(scrninfp);
1009 #endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
1012 void
1013 vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
1015 vgaHWPtr hwp = VGAHWPTR(scrninfp);
1016 int i;
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;
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
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
1038 hwp->disablePalette(hwp);
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
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
1056 void
1057 vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
1059 vgaHWPtr hwp = VGAHWPTR(scrninfp);
1060 Bool readError = FALSE;
1061 int i;
1063 #ifdef NEED_SAVED_CMAP
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.
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).
1073 /* Only save it once */
1074 if (hwp->cmapSaved)
1075 return;
1077 #if 0
1078 hwp->enablePalette(hwp);
1079 #endif
1081 hwp->writeDacMask(hwp, 0xFF);
1084 * check if we can read the lookup table
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]);
1100 #endif
1104 * Check if we can read the palette -
1105 * use foreground color to prevent flashing.
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;
1115 hwp->writeDacWriteAddr(hwp, 0x01);
1116 for (i = 3; i < 6; i++)
1117 hwp->writeDacData(hwp, save->DAC[i]);
1119 if (readError) {
1121 * save the default lookup table
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]);
1143 #endif
1147 hwp->disablePalette(hwp);
1148 hwp->cmapSaved = TRUE;
1149 #endif
1153 * vgaHWSave --
1154 * save the current VGA state
1157 void
1158 vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags)
1160 if (save == NULL)
1161 return;
1163 if (flags & VGA_SR_CMAP)
1164 vgaHWSaveColormap(scrninfp, save);
1166 if (flags & VGA_SR_MODE)
1167 vgaHWSaveMode(scrninfp, save);
1169 if (flags & VGA_SR_FONTS)
1170 vgaHWSaveFonts(scrninfp, save);
1175 * vgaHWInit --
1176 * Handle the initialization, etc. of a screen.
1177 * Return FALSE on failure.
1180 Bool
1181 vgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode)
1183 unsigned int i;
1184 vgaHWPtr hwp;
1185 vgaRegPtr regp;
1186 int depth = scrninfp->depth;
1189 * make sure the vgaHWRec is allocated
1191 if (!vgaHWGetHWRec(scrninfp))
1192 return FALSE;
1193 hwp = VGAHWPTR(scrninfp);
1194 regp = &hwp->ModeReg;
1197 * compute correct Hsync & Vsync polarity
1199 if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
1200 && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
1202 regp->MiscOutReg = 0x23;
1203 if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
1204 if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
1206 else
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 */
1223 regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
1226 * Time Sequencer
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 */
1247 * CRTC Controller
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;
1295 vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
1296 vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
1299 * Theory resumes here....
1303 * Graphics Display Controller
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;
1319 regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
1320 regp->Graphics[7] = 0x0F;
1321 regp->Graphics[8] = 0xFF;
1323 if (depth == 1) {
1324 /* Initialise the Mono map according to which bit-plane gets used */
1326 Bool flipPixels = xf86GetFlipPixels();
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;
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() */
1360 regp->Attribute[18] = 0x0F;
1361 regp->Attribute[19] = 0x00;
1362 regp->Attribute[20] = 0x00;
1364 return(TRUE);
1368 * OK, so much for theory. Now, let's deal with the >real< world...
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.
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.
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.
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.
1397 * -- TSI @ UQV, 1998.08.21
1400 CARD32
1401 vgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
1402 unsigned int Flags)
1404 int nExtBits = (nBits < 6) ? 0 : nBits - 6;
1405 CARD32 ExtBits;
1406 CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
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;
1414 /* First the horizontal case */
1415 if ((Flags & KGA_FIX_OVERSCAN)
1416 && ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3)))
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;
1432 return ExtBits >> 6;
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.
1441 CARD32
1442 vgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
1443 unsigned int Flags)
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;
1455 if ((Flags & KGA_FIX_OVERSCAN)
1456 && (mode->CrtcVBlankEnd == mode->CrtcVTotal))
1457 /* Null top overscan */
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);
1471 regp->CRTC[22] = i & 0xFF;
1472 ExtBits = i & 0xFF00;
1474 return ExtBits >> 8;
1478 * these are some more hardware specific helpers, formerly in vga.c
1480 static void
1481 vgaHWGetHWRecPrivate(void)
1483 if (vgaHWPrivateIndex < 0)
1484 vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
1485 return;
1489 static void
1490 vgaHWFreeRegs(vgaRegPtr regp)
1492 if (regp->CRTC)
1493 xfree (regp->CRTC);
1495 regp->CRTC =
1496 regp->Sequencer =
1497 regp->Graphics =
1498 regp->Attribute = NULL;
1500 regp->numCRTC =
1501 regp->numSequencer =
1502 regp->numGraphics =
1503 regp->numAttribute = 0;
1508 static Bool
1509 vgaHWAllocRegs(vgaRegPtr regp)
1511 unsigned char *buf;
1513 if ((regp->numCRTC + regp->numSequencer + regp->numGraphics +
1514 regp->numAttribute) == 0)
1515 return FALSE;
1517 buf = xcalloc(regp->numCRTC +
1518 regp->numSequencer +
1519 regp->numGraphics +
1520 regp->numAttribute, 1);
1521 if (!buf)
1522 return FALSE;
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;
1529 return TRUE;
1533 Bool
1534 vgaHWAllocDefaultRegs(vgaRegPtr regp)
1536 regp->numCRTC = VGA_NUM_CRTC;
1537 regp->numSequencer = VGA_NUM_SEQ;
1538 regp->numGraphics = VGA_NUM_GFX;
1539 regp->numAttribute = VGA_NUM_ATTR;
1541 return vgaHWAllocRegs(regp);
1545 Bool
1546 vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer,
1547 int numGraphics, int numAttribute)
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))
1555 vgaRegRec newMode, newSaved;
1556 vgaRegPtr regp;
1558 regp = &VGAHWPTR(scrp)->ModeReg;
1559 memcpy (&newMode, regp, sizeof(vgaRegRec));
1561 /* allocate space for new registers */
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;
1571 regp = &VGAHWPTR(scrp)->SavedReg;
1572 memcpy (&newSaved, regp, sizeof(vgaRegRec));
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;
1584 /* allocations succeeded, copy register data into new space */
1586 regp = &VGAHWPTR(scrp)->ModeReg;
1587 VGAHWCOPYREGSET(CRTC);
1588 VGAHWCOPYREGSET(Sequencer);
1589 VGAHWCOPYREGSET(Graphics);
1590 VGAHWCOPYREGSET(Attribute);
1592 regp = &VGAHWPTR(scrp)->SavedReg;
1593 VGAHWCOPYREGSET(CRTC);
1594 VGAHWCOPYREGSET(Sequencer);
1595 VGAHWCOPYREGSET(Graphics);
1596 VGAHWCOPYREGSET(Attribute);
1598 /* free old register arrays */
1600 regp = &VGAHWPTR(scrp)->ModeReg;
1601 vgaHWFreeRegs(regp);
1602 memcpy(regp, &newMode, sizeof(vgaRegRec));
1604 regp = &VGAHWPTR(scrp)->SavedReg;
1605 vgaHWFreeRegs(regp);
1606 memcpy(regp, &newSaved, sizeof(vgaRegRec));
1608 return TRUE;
1610 #undef VGAHWMINNUM
1611 #undef VGAHWCOPYREGSET
1615 Bool
1616 vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)
1618 vgaHWFreeRegs(dst);
1620 memcpy(dst, src, sizeof(vgaRegRec));
1622 if (!vgaHWAllocRegs(dst))
1623 return FALSE;
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);
1630 return TRUE;
1634 Bool
1635 vgaHWGetHWRec(ScrnInfoPtr scrp)
1637 vgaRegPtr regp;
1638 vgaHWPtr hwp;
1639 pciVideoPtr pvp;
1640 int i;
1643 * Let's make sure that the private exists and allocate one.
1645 vgaHWGetHWRecPrivate();
1647 * New privates are always set to NULL, so we can check if the allocation
1648 * has already been done.
1650 if (VGAHWPTR(scrp))
1651 return TRUE;
1652 hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1);
1653 regp = &VGAHWPTR(scrp)->ModeReg;
1655 if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) ||
1656 (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) {
1657 xfree(hwp);
1658 return FALSE;
1661 if (scrp->bitsPerPixel == 1) {
1662 rgb blackColour = scrp->display->blackColour,
1663 whiteColour = scrp->display->whiteColour;
1665 if (blackColour.red > 0x3F) blackColour.red = 0x3F;
1666 if (blackColour.green > 0x3F) blackColour.green = 0x3F;
1667 if (blackColour.blue > 0x3F) blackColour.blue = 0x3F;
1669 if (whiteColour.red > 0x3F) whiteColour.red = 0x3F;
1670 if (whiteColour.green > 0x3F) whiteColour.green = 0x3F;
1671 if (whiteColour.blue > 0x3F) whiteColour.blue = 0x3F;
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;
1682 * initialize default colormap for monochrome
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;
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;
1716 hwp->paletteEnabled = FALSE;
1717 hwp->cmapSaved = FALSE;
1718 hwp->MapSize = 0;
1719 hwp->pScrn = scrp;
1721 /* Initialise the function pointers with the standard VGA versions */
1722 vgaHWSetStdFuncs(hwp);
1724 hwp->PIOOffset = scrp->domainIOBase;
1725 if ((pvp = xf86GetPciInfoForEntity(scrp->entityList[0])))
1726 hwp->Tag = pciTag(pvp->bus, pvp->device, pvp->func);
1728 return TRUE;
1732 void
1733 vgaHWFreeHWRec(ScrnInfoPtr scrp)
1735 if (vgaHWPrivateIndex >= 0) {
1736 vgaHWPtr hwp = VGAHWPTR(scrp);
1738 if (!hwp)
1739 return;
1741 xfree(hwp->FontInfo1);
1742 xfree(hwp->FontInfo2);
1743 xfree(hwp->TextInfo);
1745 vgaHWFreeRegs (&hwp->ModeReg);
1746 vgaHWFreeRegs (&hwp->SavedReg);
1748 xfree(hwp);
1749 VGAHWPTRLVAL(scrp) = NULL;
1754 Bool
1755 vgaHWMapMem(ScrnInfoPtr scrp)
1757 vgaHWPtr hwp = VGAHWPTR(scrp);
1758 int scr_index = scrp->scrnIndex;
1760 if (hwp->Base)
1761 return TRUE;
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;
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.
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;
1784 void
1785 vgaHWUnmapMem(ScrnInfoPtr scrp)
1787 vgaHWPtr hwp = VGAHWPTR(scrp);
1788 int scr_index = scrp->scrnIndex;
1790 if (hwp->Base == NULL)
1791 return;
1793 #ifdef DEBUG
1794 ErrorF("Unmapping VGAMem\n");
1795 #endif
1796 xf86UnMapVidMem(scr_index, hwp->Base, hwp->MapSize);
1797 hwp->Base = NULL;
1801 vgaHWGetIndex()
1803 return vgaHWPrivateIndex;
1807 void
1808 vgaHWGetIOBase(vgaHWPtr hwp)
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);
1818 void
1819 vgaHWLock(vgaHWPtr hwp)
1821 /* Protect CRTC[0-7] */
1822 hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80);
1825 void
1826 vgaHWUnlock(vgaHWPtr hwp)
1828 /* Unprotect CRTC[0-7] */
1829 hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80);
1833 void
1834 vgaHWEnable(vgaHWPtr hwp)
1836 hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01);
1840 void
1841 vgaHWDisable(vgaHWPtr hwp)
1843 hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01);
1847 static void
1848 vgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
1849 VisualPtr pVisual)
1851 vgaHWPtr hwp = VGAHWPTR(pScrn);
1852 int i, index;
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);
1866 /* This shouldn't be necessary, but we'll play safe. */
1867 hwp->disablePalette(hwp);
1871 static void
1872 vgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan)
1874 vgaHWPtr hwp = VGAHWPTR(pScrn);
1876 if (overscan < 0 || overscan > 255)
1877 return;
1879 hwp->enablePalette(hwp);
1880 hwp->writeAttr(hwp, OVERSCAN, overscan);
1882 #ifdef DEBUGOVERSCAN
1884 int ov = hwp->readAttr(hwp, OVERSCAN);
1885 int red, green, blue;
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);
1894 #endif
1896 hwp->disablePalette(hwp);
1900 Bool
1901 vgaHWHandleColormaps(ScreenPtr pScreen)
1903 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
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);
1911 return TRUE;
1914 /* ----------------------- DDC support ------------------------*/
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.
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 */
1930 struct _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;
1943 void
1944 vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed)
1946 vgaHWPtr hwp = VGAHWPTR(pScrn);
1947 unsigned char tmp;
1948 struct _vgaDdcSave* save;
1949 switch (speed) {
1950 case DDC_FAST:
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;
2002 DDC1SetSpeedProc vgaHWddc1SetSpeedWeak(void) { return vgaHWddc1SetSpeed; }
2004 SaveScreenProcPtr vgaHWSaveScreenWeak(void) { return vgaHWSaveScreen; }