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.
14 #ifdef HAVE_XORG_CONFIG_H
15 #include <xorg-config.h>
26 #include "xf86_OSproc.h"
40 * These used to be OS-specific, which made this module have an undesirable
41 * OS dependency. Define them by default for all platforms.
43 #ifndef NEED_SAVED_CMAP
44 #define NEED_SAVED_CMAP
53 /* bytes per plane to save for text */
54 #define TEXT_AMOUNT 16384
56 /* bytes per plane to save for font data */
57 #define FONT_AMOUNT (8*8192)
60 /* Override all of these for now */
68 #define FONT_AMOUNT 65536
70 #define TEXT_AMOUNT 65536
73 /* DAC indices for white and black */
74 #define WHITE_VALUE 0x3F
75 #define BLACK_VALUE 0x00
76 #define OVERSCAN_VALUE 0x01
78 /* Use a private definition of this here */
80 #define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr
81 #define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p)))
83 static int vgaHWPrivateIndex
= -1;
85 #define DAC_TEST_MASK 0x3F
87 #ifdef NEED_SAVED_CMAP
88 /* This default colourmap is used only when it can't be read from the VGA */
90 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.
162 stdWriteCrtc(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
164 pci_io_write8(hwp
->io
, hwp
->IOBase
+ VGA_CRTC_INDEX_OFFSET
, index
);
165 pci_io_write8(hwp
->io
, hwp
->IOBase
+ VGA_CRTC_DATA_OFFSET
, value
);
169 stdReadCrtc(vgaHWPtr hwp
, CARD8 index
)
171 pci_io_write8(hwp
->io
, hwp
->IOBase
+ VGA_CRTC_INDEX_OFFSET
, index
);
172 return pci_io_read8(hwp
->io
, hwp
->IOBase
+ VGA_CRTC_DATA_OFFSET
);
176 stdWriteGr(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
178 pci_io_write8(hwp
->io
, VGA_GRAPH_INDEX
, index
);
179 pci_io_write8(hwp
->io
, VGA_GRAPH_DATA
, value
);
183 stdReadGr(vgaHWPtr hwp
, CARD8 index
)
185 pci_io_write8(hwp
->io
, VGA_GRAPH_INDEX
, index
);
186 return pci_io_read8(hwp
->io
, VGA_GRAPH_DATA
);
190 stdWriteSeq(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
192 pci_io_write8(hwp
->io
, VGA_SEQ_INDEX
, index
);
193 pci_io_write8(hwp
->io
, VGA_SEQ_DATA
, value
);
197 stdReadSeq(vgaHWPtr hwp
, CARD8 index
)
199 pci_io_write8(hwp
->io
, VGA_SEQ_INDEX
, index
);
200 return pci_io_read8(hwp
->io
, VGA_SEQ_DATA
);
204 stdReadST00(vgaHWPtr hwp
)
206 return pci_io_read8(hwp
->io
, VGA_IN_STAT_0
);
210 stdReadST01(vgaHWPtr hwp
)
212 return pci_io_read8(hwp
->io
, hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
216 stdReadFCR(vgaHWPtr hwp
)
218 return pci_io_read8(hwp
->io
, VGA_FEATURE_R
);
222 stdWriteFCR(vgaHWPtr hwp
, CARD8 value
)
224 pci_io_write8(hwp
->io
, hwp
->IOBase
+ VGA_FEATURE_W_OFFSET
, value
);
228 stdWriteAttr(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
230 if (hwp
->paletteEnabled
)
235 (void) pci_io_read8(hwp
->io
, hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
236 pci_io_write8(hwp
->io
, VGA_ATTR_INDEX
, index
);
237 pci_io_write8(hwp
->io
, VGA_ATTR_DATA_W
, value
);
241 stdReadAttr(vgaHWPtr hwp
, CARD8 index
)
243 if (hwp
->paletteEnabled
)
248 (void) pci_io_read8(hwp
->io
, hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
249 pci_io_write8(hwp
->io
, VGA_ATTR_INDEX
, index
);
250 return pci_io_read8(hwp
->io
, VGA_ATTR_DATA_R
);
254 stdWriteMiscOut(vgaHWPtr hwp
, CARD8 value
)
256 pci_io_write8(hwp
->io
, VGA_MISC_OUT_W
, value
);
260 stdReadMiscOut(vgaHWPtr hwp
)
262 return pci_io_read8(hwp
->io
, VGA_MISC_OUT_R
);
266 stdEnablePalette(vgaHWPtr hwp
)
268 (void) pci_io_read8(hwp
->io
, hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
269 pci_io_write8(hwp
->io
, VGA_ATTR_INDEX
, 0x00);
270 hwp
->paletteEnabled
= TRUE
;
274 stdDisablePalette(vgaHWPtr hwp
)
276 (void) pci_io_read8(hwp
->io
, hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
277 pci_io_write8(hwp
->io
, VGA_ATTR_INDEX
, 0x20);
278 hwp
->paletteEnabled
= FALSE
;
282 stdWriteDacMask(vgaHWPtr hwp
, CARD8 value
)
284 pci_io_write8(hwp
->io
, VGA_DAC_MASK
, value
);
288 stdReadDacMask(vgaHWPtr hwp
)
290 return pci_io_read8(hwp
->io
, VGA_DAC_MASK
);
294 stdWriteDacReadAddr(vgaHWPtr hwp
, CARD8 value
)
296 pci_io_write8(hwp
->io
, VGA_DAC_READ_ADDR
, value
);
300 stdWriteDacWriteAddr(vgaHWPtr hwp
, CARD8 value
)
302 pci_io_write8(hwp
->io
, VGA_DAC_WRITE_ADDR
, value
);
306 stdWriteDacData(vgaHWPtr hwp
, CARD8 value
)
308 pci_io_write8(hwp
->io
, VGA_DAC_DATA
, value
);
312 stdReadDacData(vgaHWPtr hwp
)
314 return pci_io_read8(hwp
->io
, VGA_DAC_DATA
);
318 stdReadEnable(vgaHWPtr hwp
)
320 return pci_io_read8(hwp
->io
, VGA_ENABLE
);
324 stdWriteEnable(vgaHWPtr hwp
, CARD8 value
)
326 pci_io_write8(hwp
->io
, VGA_ENABLE
, value
);
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
->readEnable
= stdReadEnable
;
355 hwp
->writeEnable
= stdWriteEnable
;
357 hwp
->io
= pci_legacy_open_io(hwp
->dev
, 0, 64 * 1024);
361 * MMIO versions of the register access functions. These require
362 * hwp->MemBase to be set in such a way that when the standard VGA port
363 * adderss is added the correct memory address results.
366 #define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p)))
367 #define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v))
370 mmioWriteCrtc(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
372 moutb(hwp
->IOBase
+ VGA_CRTC_INDEX_OFFSET
, index
);
373 moutb(hwp
->IOBase
+ VGA_CRTC_DATA_OFFSET
, value
);
377 mmioReadCrtc(vgaHWPtr hwp
, CARD8 index
)
379 moutb(hwp
->IOBase
+ VGA_CRTC_INDEX_OFFSET
, index
);
380 return minb(hwp
->IOBase
+ VGA_CRTC_DATA_OFFSET
);
384 mmioWriteGr(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
386 moutb(VGA_GRAPH_INDEX
, index
);
387 moutb(VGA_GRAPH_DATA
, value
);
391 mmioReadGr(vgaHWPtr hwp
, CARD8 index
)
393 moutb(VGA_GRAPH_INDEX
, index
);
394 return minb(VGA_GRAPH_DATA
);
398 mmioWriteSeq(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
400 moutb(VGA_SEQ_INDEX
, index
);
401 moutb(VGA_SEQ_DATA
, value
);
405 mmioReadSeq(vgaHWPtr hwp
, CARD8 index
)
407 moutb(VGA_SEQ_INDEX
, index
);
408 return minb(VGA_SEQ_DATA
);
412 mmioReadST00(vgaHWPtr hwp
)
414 return minb(VGA_IN_STAT_0
);
418 mmioReadST01(vgaHWPtr hwp
)
420 return minb(hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
424 mmioReadFCR(vgaHWPtr hwp
)
426 return minb(VGA_FEATURE_R
);
430 mmioWriteFCR(vgaHWPtr hwp
, CARD8 value
)
432 moutb(hwp
->IOBase
+ VGA_FEATURE_W_OFFSET
, value
);
436 mmioWriteAttr(vgaHWPtr hwp
, CARD8 index
, CARD8 value
)
438 if (hwp
->paletteEnabled
)
443 (void) minb(hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
444 moutb(VGA_ATTR_INDEX
, index
);
445 moutb(VGA_ATTR_DATA_W
, value
);
449 mmioReadAttr(vgaHWPtr hwp
, CARD8 index
)
451 if (hwp
->paletteEnabled
)
456 (void) minb(hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
457 moutb(VGA_ATTR_INDEX
, index
);
458 return minb(VGA_ATTR_DATA_R
);
462 mmioWriteMiscOut(vgaHWPtr hwp
, CARD8 value
)
464 moutb(VGA_MISC_OUT_W
, value
);
468 mmioReadMiscOut(vgaHWPtr hwp
)
470 return minb(VGA_MISC_OUT_R
);
474 mmioEnablePalette(vgaHWPtr hwp
)
476 (void) minb(hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
477 moutb(VGA_ATTR_INDEX
, 0x00);
478 hwp
->paletteEnabled
= TRUE
;
482 mmioDisablePalette(vgaHWPtr hwp
)
484 (void) minb(hwp
->IOBase
+ VGA_IN_STAT_1_OFFSET
);
485 moutb(VGA_ATTR_INDEX
, 0x20);
486 hwp
->paletteEnabled
= FALSE
;
490 mmioWriteDacMask(vgaHWPtr hwp
, CARD8 value
)
492 moutb(VGA_DAC_MASK
, value
);
496 mmioReadDacMask(vgaHWPtr hwp
)
498 return minb(VGA_DAC_MASK
);
502 mmioWriteDacReadAddr(vgaHWPtr hwp
, CARD8 value
)
504 moutb(VGA_DAC_READ_ADDR
, value
);
508 mmioWriteDacWriteAddr(vgaHWPtr hwp
, CARD8 value
)
510 moutb(VGA_DAC_WRITE_ADDR
, value
);
514 mmioWriteDacData(vgaHWPtr hwp
, CARD8 value
)
516 moutb(VGA_DAC_DATA
, value
);
520 mmioReadDacData(vgaHWPtr hwp
)
522 return minb(VGA_DAC_DATA
);
526 mmioReadEnable(vgaHWPtr hwp
)
528 return minb(VGA_ENABLE
);
532 mmioWriteEnable(vgaHWPtr hwp
, CARD8 value
)
534 moutb(VGA_ENABLE
, value
);
538 vgaHWSetMmioFuncs(vgaHWPtr hwp
, CARD8
*base
, int offset
)
540 hwp
->writeCrtc
= mmioWriteCrtc
;
541 hwp
->readCrtc
= mmioReadCrtc
;
542 hwp
->writeGr
= mmioWriteGr
;
543 hwp
->readGr
= mmioReadGr
;
544 hwp
->readST00
= mmioReadST00
;
545 hwp
->readST01
= mmioReadST01
;
546 hwp
->readFCR
= mmioReadFCR
;
547 hwp
->writeFCR
= mmioWriteFCR
;
548 hwp
->writeAttr
= mmioWriteAttr
;
549 hwp
->readAttr
= mmioReadAttr
;
550 hwp
->writeSeq
= mmioWriteSeq
;
551 hwp
->readSeq
= mmioReadSeq
;
552 hwp
->writeMiscOut
= mmioWriteMiscOut
;
553 hwp
->readMiscOut
= mmioReadMiscOut
;
554 hwp
->enablePalette
= mmioEnablePalette
;
555 hwp
->disablePalette
= mmioDisablePalette
;
556 hwp
->writeDacMask
= mmioWriteDacMask
;
557 hwp
->readDacMask
= mmioReadDacMask
;
558 hwp
->writeDacWriteAddr
= mmioWriteDacWriteAddr
;
559 hwp
->writeDacReadAddr
= mmioWriteDacReadAddr
;
560 hwp
->writeDacData
= mmioWriteDacData
;
561 hwp
->readDacData
= mmioReadDacData
;
562 hwp
->MMIOBase
= base
;
563 hwp
->MMIOOffset
= offset
;
564 hwp
->readEnable
= mmioReadEnable
;
565 hwp
->writeEnable
= mmioWriteEnable
;
570 * Protect VGA registers and memory from corruption during loads.
574 vgaHWProtect(ScrnInfoPtr pScrn
, Bool on
)
576 vgaHWPtr hwp
= VGAHWPTR(pScrn
);
583 * Turn off screen and disable sequencer.
585 tmp
= hwp
->readSeq(hwp
, 0x01);
587 vgaHWSeqReset(hwp
, TRUE
); /* start synchronous reset */
588 hwp
->writeSeq(hwp
, 0x01, tmp
| 0x20); /* disable the display */
590 hwp
->enablePalette(hwp
);
594 * Reenable sequencer, then turn on screen.
597 tmp
= hwp
->readSeq(hwp
, 0x01);
599 hwp
->writeSeq(hwp
, 0x01, tmp
& ~0x20); /* reenable display */
600 vgaHWSeqReset(hwp
, FALSE
); /* clear synchronousreset */
602 hwp
->disablePalette(hwp
);
608 vgaHWProtectWeak(void)
614 * vgaHWBlankScreen -- blank the screen.
618 vgaHWBlankScreen(ScrnInfoPtr pScrn
, Bool on
)
620 vgaHWPtr hwp
= VGAHWPTR(pScrn
);
623 scrn
= hwp
->readSeq(hwp
, 0x01);
626 scrn
&= ~0x20; /* enable screen */
629 scrn
|= 0x20; /* blank screen */
632 vgaHWSeqReset(hwp
, TRUE
);
633 hwp
->writeSeq(hwp
, 0x01, scrn
); /* change mode */
634 vgaHWSeqReset(hwp
, FALSE
);
637 vgaHWBlankScreenProc
*
638 vgaHWBlankScreenWeak(void)
640 return vgaHWBlankScreen
;
644 * vgaHWSaveScreen -- blank the screen.
648 vgaHWSaveScreen(ScreenPtr pScreen
, int mode
)
650 ScrnInfoPtr pScrn
= NULL
;
654 pScrn
= xf86ScreenToScrn(pScreen
);
656 on
= xf86IsUnblank(mode
);
660 SetTimeSinceLastInputEvent();
663 if ((pScrn
!= NULL
) && pScrn
->vtSema
) {
664 vgaHWBlankScreen(pScrn
, on
);
670 * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode
672 * This generic VGA function can only set the Off and On modes. If the
673 * Standby and Suspend modes are to be supported, a chip specific replacement
674 * for this function must be written.
678 vgaHWDPMSSet(ScrnInfoPtr pScrn
, int PowerManagementMode
, int flags
)
680 unsigned char seq1
= 0, crtc17
= 0;
681 vgaHWPtr hwp
= VGAHWPTR(pScrn
);
686 switch (PowerManagementMode
) {
688 /* Screen: On; HSync: On, VSync: On */
692 case DPMSModeStandby
:
693 /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
697 case DPMSModeSuspend
:
698 /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
703 /* Screen: Off; HSync: Off, VSync: Off */
708 hwp
->writeSeq(hwp
, 0x00, 0x01); /* Synchronous Reset */
709 seq1
|= hwp
->readSeq(hwp
, 0x01) & ~0x20;
710 hwp
->writeSeq(hwp
, 0x01, seq1
);
711 crtc17
|= hwp
->readCrtc(hwp
, 0x17) & ~0x80;
713 hwp
->writeCrtc(hwp
, 0x17, crtc17
);
714 hwp
->writeSeq(hwp
, 0x00, 0x03); /* End Reset */
719 * perform a sequencer reset.
723 vgaHWSeqReset(vgaHWPtr hwp
, Bool start
)
726 hwp
->writeSeq(hwp
, 0x00, 0x01); /* Synchronous Reset */
728 hwp
->writeSeq(hwp
, 0x00, 0x03); /* End Reset */
732 vgaHWRestoreFonts(ScrnInfoPtr scrninfp
, vgaRegPtr restore
)
734 #if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
735 vgaHWPtr hwp
= VGAHWPTR(scrninfp
);
737 unsigned char miscOut
, attr10
, gr1
, gr3
, gr4
, gr5
, gr6
, gr8
, seq2
, seq4
;
740 /* If nothing to do, return now */
741 if (!hwp
->FontInfo1
&& !hwp
->FontInfo2
&& !hwp
->TextInfo
)
744 if (hwp
->Base
== NULL
) {
746 if (!vgaHWMapMem(scrninfp
)) {
747 xf86DrvMsg(scrninfp
->scrnIndex
, X_ERROR
,
748 "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
753 /* save the registers that are needed here */
754 miscOut
= hwp
->readMiscOut(hwp
);
755 attr10
= hwp
->readAttr(hwp
, 0x10);
756 gr1
= hwp
->readGr(hwp
, 0x01);
757 gr3
= hwp
->readGr(hwp
, 0x03);
758 gr4
= hwp
->readGr(hwp
, 0x04);
759 gr5
= hwp
->readGr(hwp
, 0x05);
760 gr6
= hwp
->readGr(hwp
, 0x06);
761 gr8
= hwp
->readGr(hwp
, 0x08);
762 seq2
= hwp
->readSeq(hwp
, 0x02);
763 seq4
= hwp
->readSeq(hwp
, 0x04);
765 /* save hwp->IOBase and temporarily set it for colour mode */
766 savedIOBase
= hwp
->IOBase
;
767 hwp
->IOBase
= VGA_IOBASE_COLOR
;
769 /* Force into colour mode */
770 hwp
->writeMiscOut(hwp
, miscOut
| 0x01);
772 vgaHWBlankScreen(scrninfp
, FALSE
);
775 * here we temporarily switch to 16 colour planar mode, to simply
776 * copy the font-info and saved text.
778 * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
781 hwp
->writeAttr(hwp
, 0x10, 0x01); /* graphics mode */
784 hwp
->writeSeq(hwp
, 0x04, 0x06); /* enable plane graphics */
785 hwp
->writeGr(hwp
, 0x05, 0x00); /* write mode 0, read mode 0 */
786 hwp
->writeGr(hwp
, 0x06, 0x05); /* set graphics */
788 if (scrninfp
->depth
== 4) {
790 hwp
->writeGr(hwp
, 0x03, 0x00); /* don't rotate, write unmodified */
791 hwp
->writeGr(hwp
, 0x08, 0xFF); /* write all bits in a byte */
792 hwp
->writeGr(hwp
, 0x01, 0x00); /* all planes come from CPU */
796 if (hwp
->FontInfo1
) {
797 hwp
->writeSeq(hwp
, 0x02, 0x04); /* write to plane 2 */
798 hwp
->writeGr(hwp
, 0x04, 0x02); /* read plane 2 */
799 slowbcopy_tobus(hwp
->FontInfo1
, hwp
->Base
, FONT_AMOUNT
);
804 if (hwp
->FontInfo2
) {
805 hwp
->writeSeq(hwp
, 0x02, 0x08); /* write to plane 3 */
806 hwp
->writeGr(hwp
, 0x04, 0x03); /* read plane 3 */
807 slowbcopy_tobus(hwp
->FontInfo2
, hwp
->Base
, FONT_AMOUNT
);
813 hwp
->writeSeq(hwp
, 0x02, 0x01); /* write to plane 0 */
814 hwp
->writeGr(hwp
, 0x04, 0x00); /* read plane 0 */
815 slowbcopy_tobus(hwp
->TextInfo
, hwp
->Base
, TEXT_AMOUNT
);
816 hwp
->writeSeq(hwp
, 0x02, 0x02); /* write to plane 1 */
817 hwp
->writeGr(hwp
, 0x04, 0x01); /* read plane 1 */
818 slowbcopy_tobus((unsigned char *) hwp
->TextInfo
+ TEXT_AMOUNT
,
819 hwp
->Base
, TEXT_AMOUNT
);
823 vgaHWBlankScreen(scrninfp
, TRUE
);
825 /* restore the registers that were changed */
826 hwp
->writeMiscOut(hwp
, miscOut
);
827 hwp
->writeAttr(hwp
, 0x10, attr10
);
828 hwp
->writeGr(hwp
, 0x01, gr1
);
829 hwp
->writeGr(hwp
, 0x03, gr3
);
830 hwp
->writeGr(hwp
, 0x04, gr4
);
831 hwp
->writeGr(hwp
, 0x05, gr5
);
832 hwp
->writeGr(hwp
, 0x06, gr6
);
833 hwp
->writeGr(hwp
, 0x08, gr8
);
834 hwp
->writeSeq(hwp
, 0x02, seq2
);
835 hwp
->writeSeq(hwp
, 0x04, seq4
);
836 hwp
->IOBase
= savedIOBase
;
839 vgaHWUnmapMem(scrninfp
);
841 #endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
845 vgaHWRestoreMode(ScrnInfoPtr scrninfp
, vgaRegPtr restore
)
847 vgaHWPtr hwp
= VGAHWPTR(scrninfp
);
850 if (restore
->MiscOutReg
& 0x01)
851 hwp
->IOBase
= VGA_IOBASE_COLOR
;
853 hwp
->IOBase
= VGA_IOBASE_MONO
;
855 hwp
->writeMiscOut(hwp
, restore
->MiscOutReg
);
857 for (i
= 1; i
< restore
->numSequencer
; i
++)
858 hwp
->writeSeq(hwp
, i
, restore
->Sequencer
[i
]);
860 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
861 hwp
->writeCrtc(hwp
, 17, restore
->CRTC
[17] & ~0x80);
863 for (i
= 0; i
< restore
->numCRTC
; i
++)
864 hwp
->writeCrtc(hwp
, i
, restore
->CRTC
[i
]);
866 for (i
= 0; i
< restore
->numGraphics
; i
++)
867 hwp
->writeGr(hwp
, i
, restore
->Graphics
[i
]);
869 hwp
->enablePalette(hwp
);
870 for (i
= 0; i
< restore
->numAttribute
; i
++)
871 hwp
->writeAttr(hwp
, i
, restore
->Attribute
[i
]);
872 hwp
->disablePalette(hwp
);
876 vgaHWRestoreColormap(ScrnInfoPtr scrninfp
, vgaRegPtr restore
)
878 vgaHWPtr hwp
= VGAHWPTR(scrninfp
);
882 hwp
->enablePalette(hwp
);
885 hwp
->writeDacMask(hwp
, 0xFF);
886 hwp
->writeDacWriteAddr(hwp
, 0x00);
887 for (i
= 0; i
< 768; i
++) {
888 hwp
->writeDacData(hwp
, restore
->DAC
[i
]);
892 hwp
->disablePalette(hwp
);
897 * restore the VGA state
901 vgaHWRestore(ScrnInfoPtr scrninfp
, vgaRegPtr restore
, int flags
)
903 if (flags
& VGA_SR_MODE
)
904 vgaHWRestoreMode(scrninfp
, restore
);
906 if (flags
& VGA_SR_FONTS
)
907 vgaHWRestoreFonts(scrninfp
, restore
);
909 if (flags
& VGA_SR_CMAP
)
910 vgaHWRestoreColormap(scrninfp
, restore
);
914 vgaHWSaveFonts(ScrnInfoPtr scrninfp
, vgaRegPtr save
)
916 #if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
917 vgaHWPtr hwp
= VGAHWPTR(scrninfp
);
919 unsigned char miscOut
, attr10
, gr4
, gr5
, gr6
, seq2
, seq4
;
922 if (hwp
->Base
== NULL
) {
924 if (!vgaHWMapMem(scrninfp
)) {
925 xf86DrvMsg(scrninfp
->scrnIndex
, X_ERROR
,
926 "vgaHWSaveFonts: vgaHWMapMem() failed\n");
931 /* If in graphics mode, don't save anything */
932 attr10
= hwp
->readAttr(hwp
, 0x10);
936 /* save the registers that are needed here */
937 miscOut
= hwp
->readMiscOut(hwp
);
938 gr4
= hwp
->readGr(hwp
, 0x04);
939 gr5
= hwp
->readGr(hwp
, 0x05);
940 gr6
= hwp
->readGr(hwp
, 0x06);
941 seq2
= hwp
->readSeq(hwp
, 0x02);
942 seq4
= hwp
->readSeq(hwp
, 0x04);
944 /* save hwp->IOBase and temporarily set it for colour mode */
945 savedIOBase
= hwp
->IOBase
;
946 hwp
->IOBase
= VGA_IOBASE_COLOR
;
948 /* Force into colour mode */
949 hwp
->writeMiscOut(hwp
, miscOut
| 0x01);
951 vgaHWBlankScreen(scrninfp
, FALSE
);
954 * get the character sets, and text screen if required
957 * Here we temporarily switch to 16 colour planar mode, to simply
960 * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
963 hwp
->writeAttr(hwp
, 0x10, 0x01); /* graphics mode */
966 hwp
->writeSeq(hwp
, 0x04, 0x06); /* enable plane graphics */
967 hwp
->writeGr(hwp
, 0x05, 0x00); /* write mode 0, read mode 0 */
968 hwp
->writeGr(hwp
, 0x06, 0x05); /* set graphics */
971 if (hwp
->FontInfo1
|| (hwp
->FontInfo1
= malloc(FONT_AMOUNT
))) {
972 hwp
->writeSeq(hwp
, 0x02, 0x04); /* write to plane 2 */
973 hwp
->writeGr(hwp
, 0x04, 0x02); /* read plane 2 */
974 slowbcopy_frombus(hwp
->Base
, hwp
->FontInfo1
, FONT_AMOUNT
);
976 #endif /* SAVE_FONT1 */
978 if (hwp
->FontInfo2
|| (hwp
->FontInfo2
= malloc(FONT_AMOUNT
))) {
979 hwp
->writeSeq(hwp
, 0x02, 0x08); /* write to plane 3 */
980 hwp
->writeGr(hwp
, 0x04, 0x03); /* read plane 3 */
981 slowbcopy_frombus(hwp
->Base
, hwp
->FontInfo2
, FONT_AMOUNT
);
983 #endif /* SAVE_FONT2 */
985 if (hwp
->TextInfo
|| (hwp
->TextInfo
= malloc(2 * TEXT_AMOUNT
))) {
986 hwp
->writeSeq(hwp
, 0x02, 0x01); /* write to plane 0 */
987 hwp
->writeGr(hwp
, 0x04, 0x00); /* read plane 0 */
988 slowbcopy_frombus(hwp
->Base
, hwp
->TextInfo
, TEXT_AMOUNT
);
989 hwp
->writeSeq(hwp
, 0x02, 0x02); /* write to plane 1 */
990 hwp
->writeGr(hwp
, 0x04, 0x01); /* read plane 1 */
991 slowbcopy_frombus(hwp
->Base
,
992 (unsigned char *) hwp
->TextInfo
+ TEXT_AMOUNT
,
995 #endif /* SAVE_TEXT */
997 /* Restore clobbered registers */
998 hwp
->writeAttr(hwp
, 0x10, attr10
);
999 hwp
->writeSeq(hwp
, 0x02, seq2
);
1000 hwp
->writeSeq(hwp
, 0x04, seq4
);
1001 hwp
->writeGr(hwp
, 0x04, gr4
);
1002 hwp
->writeGr(hwp
, 0x05, gr5
);
1003 hwp
->writeGr(hwp
, 0x06, gr6
);
1004 hwp
->writeMiscOut(hwp
, miscOut
);
1005 hwp
->IOBase
= savedIOBase
;
1007 vgaHWBlankScreen(scrninfp
, TRUE
);
1010 vgaHWUnmapMem(scrninfp
);
1012 #endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
1016 vgaHWSaveMode(ScrnInfoPtr scrninfp
, vgaRegPtr save
)
1018 vgaHWPtr hwp
= VGAHWPTR(scrninfp
);
1021 save
->MiscOutReg
= hwp
->readMiscOut(hwp
);
1022 if (save
->MiscOutReg
& 0x01)
1023 hwp
->IOBase
= VGA_IOBASE_COLOR
;
1025 hwp
->IOBase
= VGA_IOBASE_MONO
;
1027 for (i
= 0; i
< save
->numCRTC
; i
++) {
1028 save
->CRTC
[i
] = hwp
->readCrtc(hwp
, i
);
1029 DebugF("CRTC[0x%02x] = 0x%02x\n", i
, save
->CRTC
[i
]);
1032 hwp
->enablePalette(hwp
);
1033 for (i
= 0; i
< save
->numAttribute
; i
++) {
1034 save
->Attribute
[i
] = hwp
->readAttr(hwp
, i
);
1035 DebugF("Attribute[0x%02x] = 0x%02x\n", i
, save
->Attribute
[i
]);
1037 hwp
->disablePalette(hwp
);
1039 for (i
= 0; i
< save
->numGraphics
; i
++) {
1040 save
->Graphics
[i
] = hwp
->readGr(hwp
, i
);
1041 DebugF("Graphics[0x%02x] = 0x%02x\n", i
, save
->Graphics
[i
]);
1044 for (i
= 1; i
< save
->numSequencer
; i
++) {
1045 save
->Sequencer
[i
] = hwp
->readSeq(hwp
, i
);
1046 DebugF("Sequencer[0x%02x] = 0x%02x\n", i
, save
->Sequencer
[i
]);
1051 vgaHWSaveColormap(ScrnInfoPtr scrninfp
, vgaRegPtr save
)
1053 vgaHWPtr hwp
= VGAHWPTR(scrninfp
);
1054 Bool readError
= FALSE
;
1057 #ifdef NEED_SAVED_CMAP
1059 * Some ET4000 chips from 1991 have a HW bug that prevents the reading
1060 * of the color lookup table. Mask rev 9042EAI is known to have this bug.
1062 * If the colourmap is not readable, we set the saved map to a default
1063 * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA
1067 /* Only save it once */
1072 hwp
->enablePalette(hwp
);
1075 hwp
->writeDacMask(hwp
, 0xFF);
1078 * check if we can read the lookup table
1080 hwp
->writeDacReadAddr(hwp
, 0x00);
1081 for (i
= 0; i
< 6; i
++) {
1082 save
->DAC
[i
] = hwp
->readDacData(hwp
);
1085 DebugF("DAC[0x%02x] = 0x%02x, ", i
/ 3, save
->DAC
[i
]);
1088 DebugF("0x%02x, ", save
->DAC
[i
]);
1091 DebugF("0x%02x\n", save
->DAC
[i
]);
1096 * Check if we can read the palette -
1097 * use foreground color to prevent flashing.
1099 hwp
->writeDacWriteAddr(hwp
, 0x01);
1100 for (i
= 3; i
< 6; i
++)
1101 hwp
->writeDacData(hwp
, ~save
->DAC
[i
] & DAC_TEST_MASK
);
1102 hwp
->writeDacReadAddr(hwp
, 0x01);
1103 for (i
= 3; i
< 6; i
++) {
1104 if (hwp
->readDacData(hwp
) != (~save
->DAC
[i
] & DAC_TEST_MASK
))
1107 hwp
->writeDacWriteAddr(hwp
, 0x01);
1108 for (i
= 3; i
< 6; i
++)
1109 hwp
->writeDacData(hwp
, save
->DAC
[i
]);
1113 * save the default lookup table
1115 memmove(save
->DAC
, defaultDAC
, 768);
1116 xf86DrvMsg(scrninfp
->scrnIndex
, X_WARNING
,
1117 "Cannot read colourmap from VGA. Will restore with default\n");
1120 /* save the colourmap */
1121 hwp
->writeDacReadAddr(hwp
, 0x02);
1122 for (i
= 6; i
< 768; i
++) {
1123 save
->DAC
[i
] = hwp
->readDacData(hwp
);
1127 DebugF("DAC[0x%02x] = 0x%02x, ", i
/ 3, save
->DAC
[i
]);
1130 DebugF("0x%02x, ", save
->DAC
[i
]);
1133 DebugF("0x%02x\n", save
->DAC
[i
]);
1138 hwp
->disablePalette(hwp
);
1139 hwp
->cmapSaved
= TRUE
;
1145 * save the current VGA state
1149 vgaHWSave(ScrnInfoPtr scrninfp
, vgaRegPtr save
, int flags
)
1154 if (flags
& VGA_SR_CMAP
)
1155 vgaHWSaveColormap(scrninfp
, save
);
1157 if (flags
& VGA_SR_MODE
)
1158 vgaHWSaveMode(scrninfp
, save
);
1160 if (flags
& VGA_SR_FONTS
)
1161 vgaHWSaveFonts(scrninfp
, save
);
1166 * Handle the initialization, etc. of a screen.
1167 * Return FALSE on failure.
1171 vgaHWInit(ScrnInfoPtr scrninfp
, DisplayModePtr mode
)
1176 int depth
= scrninfp
->depth
;
1179 * make sure the vgaHWRec is allocated
1181 if (!vgaHWGetHWRec(scrninfp
))
1183 hwp
= VGAHWPTR(scrninfp
);
1184 regp
= &hwp
->ModeReg
;
1187 * compute correct Hsync & Vsync polarity
1189 if ((mode
->Flags
& (V_PHSYNC
| V_NHSYNC
))
1190 && (mode
->Flags
& (V_PVSYNC
| V_NVSYNC
))) {
1191 regp
->MiscOutReg
= 0x23;
1192 if (mode
->Flags
& V_NHSYNC
)
1193 regp
->MiscOutReg
|= 0x40;
1194 if (mode
->Flags
& V_NVSYNC
)
1195 regp
->MiscOutReg
|= 0x80;
1198 int VDisplay
= mode
->VDisplay
;
1200 if (mode
->Flags
& V_DBLSCAN
)
1202 if (mode
->VScan
> 1)
1203 VDisplay
*= mode
->VScan
;
1205 regp
->MiscOutReg
= 0xA3; /* +hsync -vsync */
1206 else if (VDisplay
< 480)
1207 regp
->MiscOutReg
= 0x63; /* -hsync +vsync */
1208 else if (VDisplay
< 768)
1209 regp
->MiscOutReg
= 0xE3; /* -hsync -vsync */
1211 regp
->MiscOutReg
= 0x23; /* +hsync +vsync */
1214 regp
->MiscOutReg
|= (mode
->ClockIndex
& 0x03) << 2;
1220 regp
->Sequencer
[0] = 0x02;
1222 regp
->Sequencer
[0] = 0x00;
1223 if (mode
->Flags
& V_CLKDIV2
)
1224 regp
->Sequencer
[1] = 0x09;
1226 regp
->Sequencer
[1] = 0x01;
1228 regp
->Sequencer
[2] = 1 << BIT_PLANE
;
1230 regp
->Sequencer
[2] = 0x0F;
1231 regp
->Sequencer
[3] = 0x00; /* Font select */
1233 regp
->Sequencer
[4] = 0x06; /* Misc */
1235 regp
->Sequencer
[4] = 0x0E; /* Misc */
1240 regp
->CRTC
[0] = (mode
->CrtcHTotal
>> 3) - 5;
1241 regp
->CRTC
[1] = (mode
->CrtcHDisplay
>> 3) - 1;
1242 regp
->CRTC
[2] = (mode
->CrtcHBlankStart
>> 3) - 1;
1243 regp
->CRTC
[3] = (((mode
->CrtcHBlankEnd
>> 3) - 1) & 0x1F) | 0x80;
1244 i
= (((mode
->CrtcHSkew
<< 2) + 0x10) & ~0x1F);
1247 regp
->CRTC
[4] = (mode
->CrtcHSyncStart
>> 3);
1248 regp
->CRTC
[5] = ((((mode
->CrtcHBlankEnd
>> 3) - 1) & 0x20) << 2)
1249 | (((mode
->CrtcHSyncEnd
>> 3)) & 0x1F);
1250 regp
->CRTC
[6] = (mode
->CrtcVTotal
- 2) & 0xFF;
1251 regp
->CRTC
[7] = (((mode
->CrtcVTotal
- 2) & 0x100) >> 8)
1252 | (((mode
->CrtcVDisplay
- 1) & 0x100) >> 7)
1253 | ((mode
->CrtcVSyncStart
& 0x100) >> 6)
1254 | (((mode
->CrtcVBlankStart
- 1) & 0x100) >> 5)
1255 | 0x10 | (((mode
->CrtcVTotal
- 2) & 0x200) >> 4)
1256 | (((mode
->CrtcVDisplay
- 1) & 0x200) >> 3)
1257 | ((mode
->CrtcVSyncStart
& 0x200) >> 2);
1258 regp
->CRTC
[8] = 0x00;
1259 regp
->CRTC
[9] = (((mode
->CrtcVBlankStart
- 1) & 0x200) >> 4) | 0x40;
1260 if (mode
->Flags
& V_DBLSCAN
)
1261 regp
->CRTC
[9] |= 0x80;
1262 if (mode
->VScan
>= 32)
1263 regp
->CRTC
[9] |= 0x1F;
1264 else if (mode
->VScan
> 1)
1265 regp
->CRTC
[9] |= mode
->VScan
- 1;
1266 regp
->CRTC
[10] = 0x00;
1267 regp
->CRTC
[11] = 0x00;
1268 regp
->CRTC
[12] = 0x00;
1269 regp
->CRTC
[13] = 0x00;
1270 regp
->CRTC
[14] = 0x00;
1271 regp
->CRTC
[15] = 0x00;
1272 regp
->CRTC
[16] = mode
->CrtcVSyncStart
& 0xFF;
1273 regp
->CRTC
[17] = (mode
->CrtcVSyncEnd
& 0x0F) | 0x20;
1274 regp
->CRTC
[18] = (mode
->CrtcVDisplay
- 1) & 0xFF;
1275 regp
->CRTC
[19] = scrninfp
->displayWidth
>> 4; /* just a guess */
1276 regp
->CRTC
[20] = 0x00;
1277 regp
->CRTC
[21] = (mode
->CrtcVBlankStart
- 1) & 0xFF;
1278 regp
->CRTC
[22] = (mode
->CrtcVBlankEnd
- 1) & 0xFF;
1280 regp
->CRTC
[23] = 0xE3;
1282 regp
->CRTC
[23] = 0xC3;
1283 regp
->CRTC
[24] = 0xFF;
1285 vgaHWHBlankKGA(mode
, regp
, 0, KGA_FIX_OVERSCAN
| KGA_ENABLE_ON_ZERO
);
1286 vgaHWVBlankKGA(mode
, regp
, 0, KGA_FIX_OVERSCAN
| KGA_ENABLE_ON_ZERO
);
1289 * Theory resumes here....
1293 * Graphics Display Controller
1295 regp
->Graphics
[0] = 0x00;
1296 regp
->Graphics
[1] = 0x00;
1297 regp
->Graphics
[2] = 0x00;
1298 regp
->Graphics
[3] = 0x00;
1300 regp
->Graphics
[4] = BIT_PLANE
;
1301 regp
->Graphics
[5] = 0x00;
1304 regp
->Graphics
[4] = 0x00;
1306 regp
->Graphics
[5] = 0x02;
1308 regp
->Graphics
[5] = 0x40;
1310 regp
->Graphics
[6] = 0x05; /* only map 64k VGA memory !!!! */
1311 regp
->Graphics
[7] = 0x0F;
1312 regp
->Graphics
[8] = 0xFF;
1315 /* Initialise the Mono map according to which bit-plane gets used */
1317 Bool flipPixels
= xf86GetFlipPixels();
1319 for (i
= 0; i
< 16; i
++)
1320 if (((i
& (1 << BIT_PLANE
)) != 0) != flipPixels
)
1321 regp
->Attribute
[i
] = WHITE_VALUE
;
1323 regp
->Attribute
[i
] = BLACK_VALUE
;
1325 regp
->Attribute
[16] = 0x01; /* -VGA2- *//* wrong for the ET4000 */
1326 if (!hwp
->ShowOverscan
)
1327 regp
->Attribute
[OVERSCAN
] = OVERSCAN_VALUE
; /* -VGA2- */
1330 regp
->Attribute
[0] = 0x00; /* standard colormap translation */
1331 regp
->Attribute
[1] = 0x01;
1332 regp
->Attribute
[2] = 0x02;
1333 regp
->Attribute
[3] = 0x03;
1334 regp
->Attribute
[4] = 0x04;
1335 regp
->Attribute
[5] = 0x05;
1336 regp
->Attribute
[6] = 0x06;
1337 regp
->Attribute
[7] = 0x07;
1338 regp
->Attribute
[8] = 0x08;
1339 regp
->Attribute
[9] = 0x09;
1340 regp
->Attribute
[10] = 0x0A;
1341 regp
->Attribute
[11] = 0x0B;
1342 regp
->Attribute
[12] = 0x0C;
1343 regp
->Attribute
[13] = 0x0D;
1344 regp
->Attribute
[14] = 0x0E;
1345 regp
->Attribute
[15] = 0x0F;
1347 regp
->Attribute
[16] = 0x81; /* wrong for the ET4000 */
1349 regp
->Attribute
[16] = 0x41; /* wrong for the ET4000 */
1350 /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
1352 regp
->Attribute
[18] = 0x0F;
1353 regp
->Attribute
[19] = 0x00;
1354 regp
->Attribute
[20] = 0x00;
1360 * OK, so much for theory. Now, let's deal with the >real< world...
1362 * The above CRTC settings are precise in theory, except that many, if not
1363 * most, VGA clones fail to reset the blanking signal when the character or
1364 * line counter reaches [HV]Total. In this case, the signal is only
1365 * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as
1366 * the case may be) at the start of the >next< scanline or frame, which
1367 * means only part of the screen shows. This affects how null overscans
1368 * are to be implemented on such adapters.
1370 * Henceforth, VGA cores that implement this broken, but unfortunately
1371 * common, behaviour are to be designated as KGA's, in honour of Koen
1372 * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion
1373 * a series of events that led to the discovery of this problem.
1375 * Some VGA's are KGA's only in the horizontal, or only in the vertical,
1376 * some in both, others in neither. Don't let anyone tell you there is
1377 * such a thing as a VGA "standard"... And, thank the Creator for the fact
1378 * that Hilbert spaces are not yet implemented in this industry.
1380 * The following implements a trick suggested by David Dawes. This sets
1381 * [HV]BlankEnd to zero if the blanking interval does not already contain a
1382 * 0-point, and decrements it by one otherwise. In the latter case, this
1383 * will produce a left and/or top overscan which the colourmap code will
1384 * (still) need to ensure is as close to black as possible. This will make
1385 * the behaviour consistent across all chipsets, while allowing all
1386 * chipsets to display the entire screen. Non-KGA drivers can ignore the
1387 * following in their own copy of this code.
1389 * -- TSI @ UQV, 1998.08.21
1393 vgaHWHBlankKGA(DisplayModePtr mode
, vgaRegPtr regp
, int nBits
,
1396 int nExtBits
= (nBits
< 6) ? 0 : nBits
- 6;
1398 CARD32 ExtBitMask
= ((1 << nExtBits
) - 1) << 6;
1400 regp
->CRTC
[3] = (regp
->CRTC
[3] & ~0x1F)
1401 | (((mode
->CrtcHBlankEnd
>> 3) - 1) & 0x1F);
1402 regp
->CRTC
[5] = (regp
->CRTC
[5] & ~0x80)
1403 | ((((mode
->CrtcHBlankEnd
>> 3) - 1) & 0x20) << 2);
1404 ExtBits
= ((mode
->CrtcHBlankEnd
>> 3) - 1) & ExtBitMask
;
1406 /* First the horizontal case */
1407 if ((Flags
& KGA_FIX_OVERSCAN
)
1408 && ((mode
->CrtcHBlankEnd
>> 3) == (mode
->CrtcHTotal
>> 3))) {
1409 int i
= (regp
->CRTC
[3] & 0x1F)
1410 | ((regp
->CRTC
[5] & 0x80) >> 2)
1413 if (Flags
& KGA_ENABLE_ON_ZERO
) {
1414 if ((i
-- > (((mode
->CrtcHBlankStart
>> 3) - 1)
1415 & (0x3F | ExtBitMask
)))
1416 && (mode
->CrtcHBlankEnd
== mode
->CrtcHTotal
))
1419 else if (Flags
& KGA_BE_TOT_DEC
)
1421 regp
->CRTC
[3] = (regp
->CRTC
[3] & ~0x1F) | (i
& 0x1F);
1422 regp
->CRTC
[5] = (regp
->CRTC
[5] & ~0x80) | ((i
<< 2) & 0x80);
1423 ExtBits
= i
& ExtBitMask
;
1425 return ExtBits
>> 6;
1429 * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of
1430 * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the
1431 * very first scanline in a double- or multi-scanned mode. This last case
1432 * needs further investigation.
1435 vgaHWVBlankKGA(DisplayModePtr mode
, vgaRegPtr regp
, int nBits
,
1439 CARD32 nExtBits
= (nBits
< 8) ? 0 : (nBits
- 8);
1440 CARD32 ExtBitMask
= ((1 << nExtBits
) - 1) << 8;
1442 /* If width is not known nBits should be 0. In this
1443 * case BitMask is set to 0 so we can check for it. */
1444 CARD32 BitMask
= (nBits
< 7) ? 0 : ((1 << nExtBits
) - 1);
1445 int VBlankStart
= (mode
->CrtcVBlankStart
- 1) & 0xFF;
1447 regp
->CRTC
[22] = (mode
->CrtcVBlankEnd
- 1) & 0xFF;
1448 ExtBits
= (mode
->CrtcVBlankEnd
- 1) & ExtBitMask
;
1450 if ((Flags
& KGA_FIX_OVERSCAN
)
1451 && (mode
->CrtcVBlankEnd
== mode
->CrtcVTotal
))
1452 /* Null top overscan */
1454 int i
= regp
->CRTC
[22] | ExtBits
;
1456 if (Flags
& KGA_ENABLE_ON_ZERO
) {
1457 if (((BitMask
&& ((i
& BitMask
) > (VBlankStart
& BitMask
)))
1458 || ((i
> VBlankStart
) && /* 8-bit case */
1459 ((i
& 0x7F) > (VBlankStart
& 0x7F)))) && /* 7-bit case */
1460 !(regp
->CRTC
[9] & 0x9F)) /* 1 scanline/row */
1465 else if (Flags
& KGA_BE_TOT_DEC
)
1468 regp
->CRTC
[22] = i
& 0xFF;
1469 ExtBits
= i
& 0xFF00;
1471 return ExtBits
>> 8;
1475 * these are some more hardware specific helpers, formerly in vga.c
1478 vgaHWGetHWRecPrivate(void)
1480 if (vgaHWPrivateIndex
< 0)
1481 vgaHWPrivateIndex
= xf86AllocateScrnInfoPrivateIndex();
1486 vgaHWFreeRegs(vgaRegPtr regp
)
1490 regp
->CRTC
= regp
->Sequencer
= regp
->Graphics
= regp
->Attribute
= NULL
;
1493 regp
->numSequencer
= regp
->numGraphics
= regp
->numAttribute
= 0;
1497 vgaHWAllocRegs(vgaRegPtr regp
)
1501 if ((regp
->numCRTC
+ regp
->numSequencer
+ regp
->numGraphics
+
1502 regp
->numAttribute
) == 0)
1505 buf
= calloc(regp
->numCRTC
+
1506 regp
->numSequencer
+
1507 regp
->numGraphics
+ regp
->numAttribute
, 1);
1512 regp
->Sequencer
= regp
->CRTC
+ regp
->numCRTC
;
1513 regp
->Graphics
= regp
->Sequencer
+ regp
->numSequencer
;
1514 regp
->Attribute
= regp
->Graphics
+ regp
->numGraphics
;
1520 vgaHWAllocDefaultRegs(vgaRegPtr regp
)
1522 regp
->numCRTC
= VGA_NUM_CRTC
;
1523 regp
->numSequencer
= VGA_NUM_SEQ
;
1524 regp
->numGraphics
= VGA_NUM_GFX
;
1525 regp
->numAttribute
= VGA_NUM_ATTR
;
1527 return vgaHWAllocRegs(regp
);
1531 vgaHWSetRegCounts(ScrnInfoPtr scrp
, int numCRTC
, int numSequencer
,
1532 int numGraphics
, int numAttribute
)
1534 #define VGAHWMINNUM(regtype) \
1535 ((newMode.num##regtype < regp->num##regtype) ? \
1536 (newMode.num##regtype) : (regp->num##regtype))
1537 #define VGAHWCOPYREGSET(regtype) \
1538 memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype))
1540 vgaRegRec newMode
, newSaved
;
1543 regp
= &VGAHWPTR(scrp
)->ModeReg
;
1544 memcpy(&newMode
, regp
, sizeof(vgaRegRec
));
1546 /* allocate space for new registers */
1549 regp
->numCRTC
= numCRTC
;
1550 regp
->numSequencer
= numSequencer
;
1551 regp
->numGraphics
= numGraphics
;
1552 regp
->numAttribute
= numAttribute
;
1553 if (!vgaHWAllocRegs(regp
))
1556 regp
= &VGAHWPTR(scrp
)->SavedReg
;
1557 memcpy(&newSaved
, regp
, sizeof(vgaRegRec
));
1560 regp
->numCRTC
= numCRTC
;
1561 regp
->numSequencer
= numSequencer
;
1562 regp
->numGraphics
= numGraphics
;
1563 regp
->numAttribute
= numAttribute
;
1564 if (!vgaHWAllocRegs(regp
)) {
1565 vgaHWFreeRegs(&newMode
);
1569 /* allocations succeeded, copy register data into new space */
1571 regp
= &VGAHWPTR(scrp
)->ModeReg
;
1572 VGAHWCOPYREGSET(CRTC
);
1573 VGAHWCOPYREGSET(Sequencer
);
1574 VGAHWCOPYREGSET(Graphics
);
1575 VGAHWCOPYREGSET(Attribute
);
1577 regp
= &VGAHWPTR(scrp
)->SavedReg
;
1578 VGAHWCOPYREGSET(CRTC
);
1579 VGAHWCOPYREGSET(Sequencer
);
1580 VGAHWCOPYREGSET(Graphics
);
1581 VGAHWCOPYREGSET(Attribute
);
1583 /* free old register arrays */
1585 regp
= &VGAHWPTR(scrp
)->ModeReg
;
1586 vgaHWFreeRegs(regp
);
1587 memcpy(regp
, &newMode
, sizeof(vgaRegRec
));
1589 regp
= &VGAHWPTR(scrp
)->SavedReg
;
1590 vgaHWFreeRegs(regp
);
1591 memcpy(regp
, &newSaved
, sizeof(vgaRegRec
));
1596 #undef VGAHWCOPYREGSET
1600 vgaHWCopyReg(vgaRegPtr dst
, vgaRegPtr src
)
1604 memcpy(dst
, src
, sizeof(vgaRegRec
));
1606 if (!vgaHWAllocRegs(dst
))
1609 memcpy(dst
->CRTC
, src
->CRTC
, src
->numCRTC
);
1610 memcpy(dst
->Sequencer
, src
->Sequencer
, src
->numSequencer
);
1611 memcpy(dst
->Graphics
, src
->Graphics
, src
->numGraphics
);
1612 memcpy(dst
->Attribute
, src
->Attribute
, src
->numAttribute
);
1618 vgaHWGetHWRec(ScrnInfoPtr scrp
)
1625 * Let's make sure that the private exists and allocate one.
1627 vgaHWGetHWRecPrivate();
1629 * New privates are always set to NULL, so we can check if the allocation
1630 * has already been done.
1634 hwp
= VGAHWPTRLVAL(scrp
) = xnfcalloc(sizeof(vgaHWRec
), 1);
1635 regp
= &VGAHWPTR(scrp
)->ModeReg
;
1637 if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp
)->SavedReg
)) ||
1638 (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp
)->ModeReg
))) {
1643 if (scrp
->bitsPerPixel
== 1) {
1644 rgb blackColour
= scrp
->display
->blackColour
,
1645 whiteColour
= scrp
->display
->whiteColour
;
1647 if (blackColour
.red
> 0x3F)
1648 blackColour
.red
= 0x3F;
1649 if (blackColour
.green
> 0x3F)
1650 blackColour
.green
= 0x3F;
1651 if (blackColour
.blue
> 0x3F)
1652 blackColour
.blue
= 0x3F;
1654 if (whiteColour
.red
> 0x3F)
1655 whiteColour
.red
= 0x3F;
1656 if (whiteColour
.green
> 0x3F)
1657 whiteColour
.green
= 0x3F;
1658 if (whiteColour
.blue
> 0x3F)
1659 whiteColour
.blue
= 0x3F;
1661 if ((blackColour
.red
== whiteColour
.red
) &&
1662 (blackColour
.green
== whiteColour
.green
) &&
1663 (blackColour
.blue
== whiteColour
.blue
)) {
1664 blackColour
.red
^= 0x3F;
1665 blackColour
.green
^= 0x3F;
1666 blackColour
.blue
^= 0x3F;
1670 * initialize default colormap for monochrome
1672 for (i
= 0; i
< 3; i
++)
1673 regp
->DAC
[i
] = 0x00;
1674 for (i
= 3; i
< 768; i
++)
1675 regp
->DAC
[i
] = 0x3F;
1676 i
= BLACK_VALUE
* 3;
1677 regp
->DAC
[i
++] = blackColour
.red
;
1678 regp
->DAC
[i
++] = blackColour
.green
;
1679 regp
->DAC
[i
] = blackColour
.blue
;
1680 i
= WHITE_VALUE
* 3;
1681 regp
->DAC
[i
++] = whiteColour
.red
;
1682 regp
->DAC
[i
++] = whiteColour
.green
;
1683 regp
->DAC
[i
] = whiteColour
.blue
;
1684 i
= OVERSCAN_VALUE
* 3;
1685 regp
->DAC
[i
++] = 0x00;
1686 regp
->DAC
[i
++] = 0x00;
1687 regp
->DAC
[i
] = 0x00;
1690 /* Set all colours to black */
1691 for (i
= 0; i
< 768; i
++)
1692 regp
->DAC
[i
] = 0x00;
1693 /* ... and the overscan */
1694 if (scrp
->depth
>= 4)
1695 regp
->Attribute
[OVERSCAN
] = 0xFF;
1697 if (xf86FindOption(scrp
->confScreen
->options
, "ShowOverscan")) {
1698 xf86MarkOptionUsedByName(scrp
->confScreen
->options
, "ShowOverscan");
1699 xf86DrvMsg(scrp
->scrnIndex
, X_CONFIG
, "Showing overscan area\n");
1700 regp
->DAC
[765] = 0x3F;
1701 regp
->DAC
[766] = 0x00;
1702 regp
->DAC
[767] = 0x3F;
1703 regp
->Attribute
[OVERSCAN
] = 0xFF;
1704 hwp
->ShowOverscan
= TRUE
;
1707 hwp
->ShowOverscan
= FALSE
;
1709 hwp
->paletteEnabled
= FALSE
;
1710 hwp
->cmapSaved
= FALSE
;
1714 hwp
->dev
= xf86GetPciInfoForEntity(scrp
->entityList
[0]);
1720 vgaHWFreeHWRec(ScrnInfoPtr scrp
)
1722 if (vgaHWPrivateIndex
>= 0) {
1723 vgaHWPtr hwp
= VGAHWPTR(scrp
);
1728 pci_device_close_io(hwp
->dev
, hwp
->io
);
1730 free(hwp
->FontInfo1
);
1731 free(hwp
->FontInfo2
);
1732 free(hwp
->TextInfo
);
1734 vgaHWFreeRegs(&hwp
->ModeReg
);
1735 vgaHWFreeRegs(&hwp
->SavedReg
);
1738 VGAHWPTRLVAL(scrp
) = NULL
;
1743 vgaHWMapMem(ScrnInfoPtr scrp
)
1745 vgaHWPtr hwp
= VGAHWPTR(scrp
);
1750 /* If not set, initialise with the defaults */
1751 if (hwp
->MapSize
== 0)
1752 hwp
->MapSize
= VGA_DEFAULT_MEM_SIZE
;
1753 if (hwp
->MapPhys
== 0)
1754 hwp
->MapPhys
= VGA_DEFAULT_PHYS_ADDR
;
1757 * Map as VIDMEM_MMIO_32BIT because WC
1758 * is bad when there is page flipping.
1759 * XXX This is not correct but we do it
1762 DebugF("Mapping VGAMem\n");
1763 pci_device_map_legacy(hwp
->dev
, hwp
->MapPhys
, hwp
->MapSize
,
1764 PCI_DEV_MAP_FLAG_WRITABLE
, &hwp
->Base
);
1765 return hwp
->Base
!= NULL
;
1769 vgaHWUnmapMem(ScrnInfoPtr scrp
)
1771 vgaHWPtr hwp
= VGAHWPTR(scrp
);
1773 if (hwp
->Base
== NULL
)
1776 DebugF("Unmapping VGAMem\n");
1777 pci_device_unmap_legacy(hwp
->dev
, hwp
->Base
, hwp
->MapSize
);
1784 return vgaHWPrivateIndex
;
1788 vgaHWGetIOBase(vgaHWPtr hwp
)
1790 hwp
->IOBase
= (hwp
->readMiscOut(hwp
) & 0x01) ?
1791 VGA_IOBASE_COLOR
: VGA_IOBASE_MONO
;
1792 xf86DrvMsgVerb(hwp
->pScrn
->scrnIndex
, X_INFO
, 3,
1793 "vgaHWGetIOBase: hwp->IOBase is 0x%04x\n", hwp
->IOBase
);
1797 vgaHWLock(vgaHWPtr hwp
)
1799 /* Protect CRTC[0-7] */
1800 hwp
->writeCrtc(hwp
, 0x11, hwp
->readCrtc(hwp
, 0x11) | 0x80);
1804 vgaHWUnlock(vgaHWPtr hwp
)
1806 /* Unprotect CRTC[0-7] */
1807 hwp
->writeCrtc(hwp
, 0x11, hwp
->readCrtc(hwp
, 0x11) & ~0x80);
1811 vgaHWEnable(vgaHWPtr hwp
)
1813 hwp
->writeEnable(hwp
, hwp
->readEnable(hwp
) | 0x01);
1817 vgaHWDisable(vgaHWPtr hwp
)
1819 hwp
->writeEnable(hwp
, hwp
->readEnable(hwp
) & ~0x01);
1823 vgaHWLoadPalette(ScrnInfoPtr pScrn
, int numColors
, int *indices
, LOCO
* colors
,
1826 vgaHWPtr hwp
= VGAHWPTR(pScrn
);
1829 for (i
= 0; i
< numColors
; i
++) {
1831 hwp
->writeDacWriteAddr(hwp
, index
);
1833 hwp
->writeDacData(hwp
, colors
[index
].red
);
1835 hwp
->writeDacData(hwp
, colors
[index
].green
);
1837 hwp
->writeDacData(hwp
, colors
[index
].blue
);
1841 /* This shouldn't be necessary, but we'll play safe. */
1842 hwp
->disablePalette(hwp
);
1846 vgaHWSetOverscan(ScrnInfoPtr pScrn
, int overscan
)
1848 vgaHWPtr hwp
= VGAHWPTR(pScrn
);
1850 if (overscan
< 0 || overscan
> 255)
1853 hwp
->enablePalette(hwp
);
1854 hwp
->writeAttr(hwp
, OVERSCAN
, overscan
);
1856 #ifdef DEBUGOVERSCAN
1858 int ov
= hwp
->readAttr(hwp
, OVERSCAN
);
1859 int red
, green
, blue
;
1861 hwp
->writeDacReadAddr(hwp
, ov
);
1862 red
= hwp
->readDacData(hwp
);
1863 green
= hwp
->readDacData(hwp
);
1864 blue
= hwp
->readDacData(hwp
);
1865 ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n",
1866 ov
, red
, green
, blue
);
1870 hwp
->disablePalette(hwp
);
1874 vgaHWHandleColormaps(ScreenPtr pScreen
)
1876 ScrnInfoPtr pScrn
= xf86ScreenToScrn(pScreen
);
1878 if (pScrn
->depth
> 1 && pScrn
->depth
<= 8) {
1879 return xf86HandleColormaps(pScreen
, 1 << pScrn
->depth
,
1880 pScrn
->rgbBits
, vgaHWLoadPalette
,
1881 pScrn
->depth
> 4 ? vgaHWSetOverscan
: NULL
,
1882 CMAP_RELOAD_ON_MODE_SWITCH
);
1887 /* ----------------------- DDC support ------------------------*/
1889 * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total
1890 * to read out EDID at a faster rate. Allowed maximum is 25kHz with
1891 * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen
1892 * readback, enable access to cr00-cr07.
1895 /* vertical timings */
1896 #define DISPLAY_END 0x04
1897 #define BLANK_START DISPLAY_END
1898 #define SYNC_START BLANK_START
1899 #define SYNC_END 0x09
1900 #define BLANK_END SYNC_END
1901 #define V_TOTAL BLANK_END
1902 /* this function doesn't have to be reentrant for our purposes */
1903 struct _vgaDdcSave
{
1917 vgaHWddc1SetSpeed(ScrnInfoPtr pScrn
, xf86ddcSpeed speed
)
1919 vgaHWPtr hwp
= VGAHWPTR(pScrn
);
1921 struct _vgaDdcSave
*save
;
1926 if (hwp
->ddc
!= NULL
)
1928 hwp
->ddc
= xnfcalloc(sizeof(struct _vgaDdcSave
), 1);
1929 save
= (struct _vgaDdcSave
*) hwp
->ddc
;
1930 /* Lightpen register disable - allow access to cr10 & 11; just in case */
1931 save
->cr03
= hwp
->readCrtc(hwp
, 0x03);
1932 hwp
->writeCrtc(hwp
, 0x03, (save
->cr03
| 0x80));
1933 save
->cr12
= hwp
->readCrtc(hwp
, 0x12);
1934 hwp
->writeCrtc(hwp
, 0x12, DISPLAY_END
);
1935 save
->cr15
= hwp
->readCrtc(hwp
, 0x15);
1936 hwp
->writeCrtc(hwp
, 0x15, BLANK_START
);
1937 save
->cr10
= hwp
->readCrtc(hwp
, 0x10);
1938 hwp
->writeCrtc(hwp
, 0x10, SYNC_START
);
1939 save
->cr11
= hwp
->readCrtc(hwp
, 0x11);
1940 /* unprotect group 1 registers; just in case ... */
1941 hwp
->writeCrtc(hwp
, 0x11, ((save
->cr11
& 0x70) | SYNC_END
));
1942 save
->cr16
= hwp
->readCrtc(hwp
, 0x16);
1943 hwp
->writeCrtc(hwp
, 0x16, BLANK_END
);
1944 save
->cr06
= hwp
->readCrtc(hwp
, 0x06);
1945 hwp
->writeCrtc(hwp
, 0x06, V_TOTAL
);
1946 /* all values have less than 8 bit - mask out 9th and 10th bits */
1947 save
->cr09
= hwp
->readCrtc(hwp
, 0x09);
1948 hwp
->writeCrtc(hwp
, 0x09, (save
->cr09
& 0xDF));
1949 save
->cr07
= hwp
->readCrtc(hwp
, 0x07);
1950 hwp
->writeCrtc(hwp
, 0x07, (save
->cr07
& 0x10));
1951 /* vsync polarity negativ & ensure a 25MHz clock */
1952 save
->msr
= hwp
->readMiscOut(hwp
);
1953 hwp
->writeMiscOut(hwp
, ((save
->msr
& 0xF3) | 0x80));
1956 if (hwp
->ddc
== NULL
)
1958 save
= (struct _vgaDdcSave
*) hwp
->ddc
;
1959 hwp
->writeMiscOut(hwp
, save
->msr
);
1960 hwp
->writeCrtc(hwp
, 0x07, save
->cr07
);
1961 tmp
= hwp
->readCrtc(hwp
, 0x09);
1962 hwp
->writeCrtc(hwp
, 0x09, ((save
->cr09
& 0x20) | (tmp
& 0xDF)));
1963 hwp
->writeCrtc(hwp
, 0x06, save
->cr06
);
1964 hwp
->writeCrtc(hwp
, 0x16, save
->cr16
);
1965 hwp
->writeCrtc(hwp
, 0x11, save
->cr11
);
1966 hwp
->writeCrtc(hwp
, 0x10, save
->cr10
);
1967 hwp
->writeCrtc(hwp
, 0x15, save
->cr15
);
1968 hwp
->writeCrtc(hwp
, 0x12, save
->cr12
);
1969 hwp
->writeCrtc(hwp
, 0x03, save
->cr03
);
1979 vgaHWddc1SetSpeedWeak(void)
1981 return vgaHWddc1SetSpeed
;
1985 vgaHWSaveScreenWeak(void)
1987 return vgaHWSaveScreen
;
1991 * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
1994 xf86GetClocks(ScrnInfoPtr pScrn
, int num
, Bool (*ClockFunc
) (ScrnInfoPtr
, int),
1995 void (*ProtectRegs
) (ScrnInfoPtr
, Bool
),
1996 void (*BlankScreen
) (ScrnInfoPtr
, Bool
),
1997 unsigned long vertsyncreg
, int maskval
, int knownclkindex
,
2000 register int status
= vertsyncreg
;
2001 unsigned long i
, cnt
, rcnt
, sync
;
2002 vgaHWPtr hwp
= VGAHWPTR(pScrn
);
2004 /* First save registers that get written on */
2005 (*ClockFunc
) (pScrn
, CLK_REG_SAVE
);
2007 if (num
> MAXCLOCKS
)
2010 for (i
= 0; i
< num
; i
++) {
2012 (*ProtectRegs
) (pScrn
, TRUE
);
2013 if (!(*ClockFunc
) (pScrn
, i
)) {
2014 pScrn
->clock
[i
] = -1;
2018 (*ProtectRegs
) (pScrn
, FALSE
);
2020 (*BlankScreen
) (pScrn
, FALSE
);
2022 usleep(50000); /* let VCO stabilise */
2027 while ((pci_io_read8(hwp
->io
, status
) & maskval
) == 0x00)
2030 /* Something appears to be happening, so reset sync count */
2032 while ((pci_io_read8(hwp
->io
, status
) & maskval
) == maskval
)
2035 /* Something appears to be happening, so reset sync count */
2037 while ((pci_io_read8(hwp
->io
, status
) & maskval
) == 0x00)
2041 for (rcnt
= 0; rcnt
< 5; rcnt
++) {
2042 while (!(pci_io_read8(hwp
->io
, status
) & maskval
))
2044 while ((pci_io_read8(hwp
->io
, status
) & maskval
))
2049 pScrn
->clock
[i
] = cnt
? cnt
: -1;
2051 (*BlankScreen
) (pScrn
, TRUE
);
2054 for (i
= 0; i
< num
; i
++) {
2055 if (i
!= knownclkindex
) {
2056 if (pScrn
->clock
[i
] == -1) {
2057 pScrn
->clock
[i
] = 0;
2060 pScrn
->clock
[i
] = (int) (0.5 +
2061 (((float) knownclkvalue
) *
2062 pScrn
->clock
[knownclkindex
]) /
2064 /* Round to nearest 10KHz */
2065 pScrn
->clock
[i
] += 5;
2066 pScrn
->clock
[i
] /= 10;
2067 pScrn
->clock
[i
] *= 10;
2072 pScrn
->clock
[knownclkindex
] = knownclkvalue
;
2073 pScrn
->numClocks
= num
;
2075 /* Restore registers that were written on */
2076 (*ClockFunc
) (pScrn
, CLK_REG_RESTORE
);