105b261ecSmrg 205b261ecSmrg/* 305b261ecSmrg * 405b261ecSmrg * Copyright 1991-1999 by The XFree86 Project, Inc. 505b261ecSmrg * 605b261ecSmrg * Loosely based on code bearing the following copyright: 705b261ecSmrg * 805b261ecSmrg * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 905b261ecSmrg * 1005b261ecSmrg */ 1105b261ecSmrg 1205b261ecSmrg#define _NEED_SYSI86 1305b261ecSmrg 1405b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 1505b261ecSmrg#include <xorg-config.h> 1605b261ecSmrg#endif 1705b261ecSmrg 1805b261ecSmrg#include <stdlib.h> 1905b261ecSmrg#include <string.h> 2005b261ecSmrg#include <unistd.h> 2105b261ecSmrg 2205b261ecSmrg#include <X11/X.h> 2305b261ecSmrg#include "misc.h" 2405b261ecSmrg 2505b261ecSmrg#include "xf86.h" 2605b261ecSmrg#include "xf86_OSproc.h" 2705b261ecSmrg#include "vgaHW.h" 2805b261ecSmrg 2905b261ecSmrg#include "compiler.h" 3005b261ecSmrg 3105b261ecSmrg#include "xf86cmap.h" 3205b261ecSmrg 334642e01fSmrg#include "Pci.h" 344642e01fSmrg 3505b261ecSmrg#ifndef SAVE_FONT1 3605b261ecSmrg#define SAVE_FONT1 1 3705b261ecSmrg#endif 3805b261ecSmrg 3905b261ecSmrg/* 4005b261ecSmrg * These used to be OS-specific, which made this module have an undesirable 4105b261ecSmrg * OS dependency. Define them by default for all platforms. 4205b261ecSmrg */ 4305b261ecSmrg#ifndef NEED_SAVED_CMAP 4405b261ecSmrg#define NEED_SAVED_CMAP 4505b261ecSmrg#endif 4605b261ecSmrg#ifndef SAVE_TEXT 4705b261ecSmrg#define SAVE_TEXT 1 4805b261ecSmrg#endif 4905b261ecSmrg#ifndef SAVE_FONT2 5005b261ecSmrg#define SAVE_FONT2 1 5105b261ecSmrg#endif 5205b261ecSmrg 5305b261ecSmrg/* bytes per plane to save for text */ 5405b261ecSmrg#define TEXT_AMOUNT 16384 5505b261ecSmrg 5605b261ecSmrg/* bytes per plane to save for font data */ 5705b261ecSmrg#define FONT_AMOUNT (8*8192) 5805b261ecSmrg 5905b261ecSmrg#if 0 6005b261ecSmrg/* Override all of these for now */ 6105b261ecSmrg#undef SAVE_FONT1 6205b261ecSmrg#define SAVE_FONT1 1 6305b261ecSmrg#undef SAVE_FONT2 6405b261ecSmrg#define SAVE_FONT2 1 6505b261ecSmrg#undef SAVE_TEST 6605b261ecSmrg#define SAVE_TEST 1 6705b261ecSmrg#undef FONT_AMOUNT 6805b261ecSmrg#define FONT_AMOUNT 65536 6905b261ecSmrg#undef TEXT_AMOUNT 7005b261ecSmrg#define TEXT_AMOUNT 65536 7105b261ecSmrg#endif 7205b261ecSmrg 7305b261ecSmrg/* DAC indices for white and black */ 7405b261ecSmrg#define WHITE_VALUE 0x3F 7505b261ecSmrg#define BLACK_VALUE 0x00 7605b261ecSmrg#define OVERSCAN_VALUE 0x01 7705b261ecSmrg 7805b261ecSmrg/* Use a private definition of this here */ 7905b261ecSmrg#undef VGAHWPTR 8005b261ecSmrg#define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr 8105b261ecSmrg#define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p))) 8205b261ecSmrg 8305b261ecSmrgstatic int vgaHWPrivateIndex = -1; 8405b261ecSmrg 8505b261ecSmrg#define DAC_TEST_MASK 0x3F 8605b261ecSmrg 8705b261ecSmrg#ifdef NEED_SAVED_CMAP 8805b261ecSmrg/* This default colourmap is used only when it can't be read from the VGA */ 8905b261ecSmrg 9035c4bbdfSmrgstatic CARD8 defaultDAC[768] = { 9135c4bbdfSmrg 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42, 9235c4bbdfSmrg 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42, 9335c4bbdfSmrg 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63, 9435c4bbdfSmrg 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63, 9535c4bbdfSmrg 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11, 9635c4bbdfSmrg 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24, 9735c4bbdfSmrg 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40, 9835c4bbdfSmrg 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63, 9935c4bbdfSmrg 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63, 10035c4bbdfSmrg 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 10135c4bbdfSmrg 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 10235c4bbdfSmrg 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0, 10335c4bbdfSmrg 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 10435c4bbdfSmrg 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 10535c4bbdfSmrg 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63, 10635c4bbdfSmrg 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 10735c4bbdfSmrg 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 10835c4bbdfSmrg 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31, 10935c4bbdfSmrg 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 11035c4bbdfSmrg 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 11135c4bbdfSmrg 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63, 11235c4bbdfSmrg 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 11335c4bbdfSmrg 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 11435c4bbdfSmrg 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45, 11535c4bbdfSmrg 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 11635c4bbdfSmrg 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 11735c4bbdfSmrg 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28, 11835c4bbdfSmrg 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 11935c4bbdfSmrg 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 12035c4bbdfSmrg 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0, 12135c4bbdfSmrg 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 12235c4bbdfSmrg 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 12335c4bbdfSmrg 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28, 12435c4bbdfSmrg 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 12535c4bbdfSmrg 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 12635c4bbdfSmrg 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14, 12735c4bbdfSmrg 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 12835c4bbdfSmrg 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 12935c4bbdfSmrg 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28, 13035c4bbdfSmrg 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 13135c4bbdfSmrg 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 13235c4bbdfSmrg 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20, 13335c4bbdfSmrg 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 13435c4bbdfSmrg 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 13535c4bbdfSmrg 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16, 13635c4bbdfSmrg 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 13735c4bbdfSmrg 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 13835c4bbdfSmrg 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0, 13935c4bbdfSmrg 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 14035c4bbdfSmrg 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 14135c4bbdfSmrg 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16, 14235c4bbdfSmrg 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 14335c4bbdfSmrg 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 14435c4bbdfSmrg 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8, 14535c4bbdfSmrg 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 14635c4bbdfSmrg 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 14735c4bbdfSmrg 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16, 14835c4bbdfSmrg 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 14935c4bbdfSmrg 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 15035c4bbdfSmrg 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11, 15135c4bbdfSmrg 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 15235c4bbdfSmrg 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 15335c4bbdfSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15435c4bbdfSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15505b261ecSmrg}; 15635c4bbdfSmrg#endif /* NEED_SAVED_CMAP */ 15705b261ecSmrg 15805b261ecSmrg/* 15905b261ecSmrg * Standard VGA versions of the register access functions. 16005b261ecSmrg */ 16105b261ecSmrgstatic void 16205b261ecSmrgstdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 16305b261ecSmrg{ 16435c4bbdfSmrg pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 16535c4bbdfSmrg pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_DATA_OFFSET, value); 16605b261ecSmrg} 16705b261ecSmrg 16805b261ecSmrgstatic CARD8 16905b261ecSmrgstdReadCrtc(vgaHWPtr hwp, CARD8 index) 17005b261ecSmrg{ 17135c4bbdfSmrg pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 17235c4bbdfSmrg return pci_io_read8(hwp->io, hwp->IOBase + VGA_CRTC_DATA_OFFSET); 17305b261ecSmrg} 17405b261ecSmrg 17505b261ecSmrgstatic void 17605b261ecSmrgstdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value) 17705b261ecSmrg{ 17835c4bbdfSmrg pci_io_write8(hwp->io, VGA_GRAPH_INDEX, index); 17935c4bbdfSmrg pci_io_write8(hwp->io, VGA_GRAPH_DATA, value); 18005b261ecSmrg} 18105b261ecSmrg 18205b261ecSmrgstatic CARD8 18305b261ecSmrgstdReadGr(vgaHWPtr hwp, CARD8 index) 18405b261ecSmrg{ 18535c4bbdfSmrg pci_io_write8(hwp->io, VGA_GRAPH_INDEX, index); 18635c4bbdfSmrg return pci_io_read8(hwp->io, VGA_GRAPH_DATA); 18705b261ecSmrg} 18805b261ecSmrg 18905b261ecSmrgstatic void 19005b261ecSmrgstdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value) 19105b261ecSmrg{ 19235c4bbdfSmrg pci_io_write8(hwp->io, VGA_SEQ_INDEX, index); 19335c4bbdfSmrg pci_io_write8(hwp->io, VGA_SEQ_DATA, value); 19405b261ecSmrg} 19505b261ecSmrg 19605b261ecSmrgstatic CARD8 19705b261ecSmrgstdReadSeq(vgaHWPtr hwp, CARD8 index) 19805b261ecSmrg{ 19935c4bbdfSmrg pci_io_write8(hwp->io, VGA_SEQ_INDEX, index); 20035c4bbdfSmrg return pci_io_read8(hwp->io, VGA_SEQ_DATA); 20105b261ecSmrg} 20205b261ecSmrg 20305b261ecSmrgstatic CARD8 20405b261ecSmrgstdReadST00(vgaHWPtr hwp) 20505b261ecSmrg{ 20635c4bbdfSmrg return pci_io_read8(hwp->io, VGA_IN_STAT_0); 20705b261ecSmrg} 20805b261ecSmrg 20905b261ecSmrgstatic CARD8 21005b261ecSmrgstdReadST01(vgaHWPtr hwp) 21105b261ecSmrg{ 21235c4bbdfSmrg return pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET); 21305b261ecSmrg} 21405b261ecSmrg 21505b261ecSmrgstatic CARD8 21605b261ecSmrgstdReadFCR(vgaHWPtr hwp) 21705b261ecSmrg{ 21835c4bbdfSmrg return pci_io_read8(hwp->io, VGA_FEATURE_R); 21905b261ecSmrg} 22005b261ecSmrg 22105b261ecSmrgstatic void 22205b261ecSmrgstdWriteFCR(vgaHWPtr hwp, CARD8 value) 22305b261ecSmrg{ 22435c4bbdfSmrg pci_io_write8(hwp->io, hwp->IOBase + VGA_FEATURE_W_OFFSET, value); 22505b261ecSmrg} 22605b261ecSmrg 22705b261ecSmrgstatic void 22805b261ecSmrgstdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value) 22905b261ecSmrg{ 23005b261ecSmrg if (hwp->paletteEnabled) 23135c4bbdfSmrg index &= ~0x20; 23205b261ecSmrg else 23335c4bbdfSmrg index |= 0x20; 23405b261ecSmrg 23535c4bbdfSmrg (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET); 23635c4bbdfSmrg pci_io_write8(hwp->io, VGA_ATTR_INDEX, index); 23735c4bbdfSmrg pci_io_write8(hwp->io, VGA_ATTR_DATA_W, value); 23805b261ecSmrg} 23905b261ecSmrg 24005b261ecSmrgstatic CARD8 24105b261ecSmrgstdReadAttr(vgaHWPtr hwp, CARD8 index) 24205b261ecSmrg{ 24305b261ecSmrg if (hwp->paletteEnabled) 24435c4bbdfSmrg index &= ~0x20; 24505b261ecSmrg else 24635c4bbdfSmrg index |= 0x20; 24705b261ecSmrg 24835c4bbdfSmrg (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET); 24935c4bbdfSmrg pci_io_write8(hwp->io, VGA_ATTR_INDEX, index); 25035c4bbdfSmrg return pci_io_read8(hwp->io, VGA_ATTR_DATA_R); 25105b261ecSmrg} 25205b261ecSmrg 25305b261ecSmrgstatic void 25405b261ecSmrgstdWriteMiscOut(vgaHWPtr hwp, CARD8 value) 25505b261ecSmrg{ 25635c4bbdfSmrg pci_io_write8(hwp->io, VGA_MISC_OUT_W, value); 25705b261ecSmrg} 25805b261ecSmrg 25905b261ecSmrgstatic CARD8 26005b261ecSmrgstdReadMiscOut(vgaHWPtr hwp) 26105b261ecSmrg{ 26235c4bbdfSmrg return pci_io_read8(hwp->io, VGA_MISC_OUT_R); 26305b261ecSmrg} 26405b261ecSmrg 26505b261ecSmrgstatic void 26605b261ecSmrgstdEnablePalette(vgaHWPtr hwp) 26705b261ecSmrg{ 26835c4bbdfSmrg (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET); 26935c4bbdfSmrg pci_io_write8(hwp->io, VGA_ATTR_INDEX, 0x00); 27005b261ecSmrg hwp->paletteEnabled = TRUE; 27105b261ecSmrg} 27205b261ecSmrg 27305b261ecSmrgstatic void 27405b261ecSmrgstdDisablePalette(vgaHWPtr hwp) 27505b261ecSmrg{ 27635c4bbdfSmrg (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET); 27735c4bbdfSmrg pci_io_write8(hwp->io, VGA_ATTR_INDEX, 0x20); 27805b261ecSmrg hwp->paletteEnabled = FALSE; 27905b261ecSmrg} 28005b261ecSmrg 28105b261ecSmrgstatic void 28205b261ecSmrgstdWriteDacMask(vgaHWPtr hwp, CARD8 value) 28305b261ecSmrg{ 28435c4bbdfSmrg pci_io_write8(hwp->io, VGA_DAC_MASK, value); 28505b261ecSmrg} 28605b261ecSmrg 28705b261ecSmrgstatic CARD8 28805b261ecSmrgstdReadDacMask(vgaHWPtr hwp) 28905b261ecSmrg{ 29035c4bbdfSmrg return pci_io_read8(hwp->io, VGA_DAC_MASK); 29105b261ecSmrg} 29205b261ecSmrg 29305b261ecSmrgstatic void 29405b261ecSmrgstdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value) 29505b261ecSmrg{ 29635c4bbdfSmrg pci_io_write8(hwp->io, VGA_DAC_READ_ADDR, value); 29705b261ecSmrg} 29805b261ecSmrg 29905b261ecSmrgstatic void 30005b261ecSmrgstdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value) 30105b261ecSmrg{ 30235c4bbdfSmrg pci_io_write8(hwp->io, VGA_DAC_WRITE_ADDR, value); 30305b261ecSmrg} 30405b261ecSmrg 30505b261ecSmrgstatic void 30605b261ecSmrgstdWriteDacData(vgaHWPtr hwp, CARD8 value) 30705b261ecSmrg{ 30835c4bbdfSmrg pci_io_write8(hwp->io, VGA_DAC_DATA, value); 30905b261ecSmrg} 31005b261ecSmrg 31105b261ecSmrgstatic CARD8 31205b261ecSmrgstdReadDacData(vgaHWPtr hwp) 31305b261ecSmrg{ 31435c4bbdfSmrg return pci_io_read8(hwp->io, VGA_DAC_DATA); 31505b261ecSmrg} 31605b261ecSmrg 31705b261ecSmrgstatic CARD8 31805b261ecSmrgstdReadEnable(vgaHWPtr hwp) 31905b261ecSmrg{ 32035c4bbdfSmrg return pci_io_read8(hwp->io, VGA_ENABLE); 32105b261ecSmrg} 32205b261ecSmrg 32305b261ecSmrgstatic void 32405b261ecSmrgstdWriteEnable(vgaHWPtr hwp, CARD8 value) 32505b261ecSmrg{ 32635c4bbdfSmrg pci_io_write8(hwp->io, VGA_ENABLE, value); 32705b261ecSmrg} 32805b261ecSmrg 32905b261ecSmrgvoid 33005b261ecSmrgvgaHWSetStdFuncs(vgaHWPtr hwp) 33105b261ecSmrg{ 33235c4bbdfSmrg hwp->writeCrtc = stdWriteCrtc; 33335c4bbdfSmrg hwp->readCrtc = stdReadCrtc; 33435c4bbdfSmrg hwp->writeGr = stdWriteGr; 33535c4bbdfSmrg hwp->readGr = stdReadGr; 33635c4bbdfSmrg hwp->readST00 = stdReadST00; 33735c4bbdfSmrg hwp->readST01 = stdReadST01; 33835c4bbdfSmrg hwp->readFCR = stdReadFCR; 33935c4bbdfSmrg hwp->writeFCR = stdWriteFCR; 34035c4bbdfSmrg hwp->writeAttr = stdWriteAttr; 34135c4bbdfSmrg hwp->readAttr = stdReadAttr; 34235c4bbdfSmrg hwp->writeSeq = stdWriteSeq; 34335c4bbdfSmrg hwp->readSeq = stdReadSeq; 34435c4bbdfSmrg hwp->writeMiscOut = stdWriteMiscOut; 34535c4bbdfSmrg hwp->readMiscOut = stdReadMiscOut; 34635c4bbdfSmrg hwp->enablePalette = stdEnablePalette; 34735c4bbdfSmrg hwp->disablePalette = stdDisablePalette; 34835c4bbdfSmrg hwp->writeDacMask = stdWriteDacMask; 34935c4bbdfSmrg hwp->readDacMask = stdReadDacMask; 35035c4bbdfSmrg hwp->writeDacWriteAddr = stdWriteDacWriteAddr; 35135c4bbdfSmrg hwp->writeDacReadAddr = stdWriteDacReadAddr; 35235c4bbdfSmrg hwp->writeDacData = stdWriteDacData; 35335c4bbdfSmrg hwp->readDacData = stdReadDacData; 35435c4bbdfSmrg hwp->readEnable = stdReadEnable; 35535c4bbdfSmrg hwp->writeEnable = stdWriteEnable; 35635c4bbdfSmrg 35735c4bbdfSmrg hwp->io = pci_legacy_open_io(hwp->dev, 0, 64 * 1024); 35805b261ecSmrg} 35905b261ecSmrg 36005b261ecSmrg/* 36105b261ecSmrg * MMIO versions of the register access functions. These require 36205b261ecSmrg * hwp->MemBase to be set in such a way that when the standard VGA port 36305b261ecSmrg * adderss is added the correct memory address results. 36405b261ecSmrg */ 36505b261ecSmrg 36605b261ecSmrg#define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p))) 36705b261ecSmrg#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v)) 36805b261ecSmrg 36905b261ecSmrgstatic void 37005b261ecSmrgmmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 37105b261ecSmrg{ 37205b261ecSmrg moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 37305b261ecSmrg moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value); 37405b261ecSmrg} 37505b261ecSmrg 37605b261ecSmrgstatic CARD8 37705b261ecSmrgmmioReadCrtc(vgaHWPtr hwp, CARD8 index) 37805b261ecSmrg{ 37905b261ecSmrg moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 38005b261ecSmrg return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET); 38105b261ecSmrg} 38205b261ecSmrg 38305b261ecSmrgstatic void 38405b261ecSmrgmmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value) 38505b261ecSmrg{ 38605b261ecSmrg moutb(VGA_GRAPH_INDEX, index); 38705b261ecSmrg moutb(VGA_GRAPH_DATA, value); 38805b261ecSmrg} 38905b261ecSmrg 39005b261ecSmrgstatic CARD8 39105b261ecSmrgmmioReadGr(vgaHWPtr hwp, CARD8 index) 39205b261ecSmrg{ 39305b261ecSmrg moutb(VGA_GRAPH_INDEX, index); 39405b261ecSmrg return minb(VGA_GRAPH_DATA); 39505b261ecSmrg} 39605b261ecSmrg 39705b261ecSmrgstatic void 39805b261ecSmrgmmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value) 39905b261ecSmrg{ 40005b261ecSmrg moutb(VGA_SEQ_INDEX, index); 40105b261ecSmrg moutb(VGA_SEQ_DATA, value); 40205b261ecSmrg} 40305b261ecSmrg 40405b261ecSmrgstatic CARD8 40505b261ecSmrgmmioReadSeq(vgaHWPtr hwp, CARD8 index) 40605b261ecSmrg{ 40705b261ecSmrg moutb(VGA_SEQ_INDEX, index); 40805b261ecSmrg return minb(VGA_SEQ_DATA); 40905b261ecSmrg} 41005b261ecSmrg 41105b261ecSmrgstatic CARD8 41205b261ecSmrgmmioReadST00(vgaHWPtr hwp) 41305b261ecSmrg{ 41405b261ecSmrg return minb(VGA_IN_STAT_0); 41505b261ecSmrg} 41605b261ecSmrg 41705b261ecSmrgstatic CARD8 41805b261ecSmrgmmioReadST01(vgaHWPtr hwp) 41905b261ecSmrg{ 42005b261ecSmrg return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 42105b261ecSmrg} 42205b261ecSmrg 42305b261ecSmrgstatic CARD8 42405b261ecSmrgmmioReadFCR(vgaHWPtr hwp) 42505b261ecSmrg{ 42605b261ecSmrg return minb(VGA_FEATURE_R); 42705b261ecSmrg} 42805b261ecSmrg 42905b261ecSmrgstatic void 43005b261ecSmrgmmioWriteFCR(vgaHWPtr hwp, CARD8 value) 43105b261ecSmrg{ 43235c4bbdfSmrg moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET, value); 43305b261ecSmrg} 43405b261ecSmrg 43505b261ecSmrgstatic void 43605b261ecSmrgmmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value) 43705b261ecSmrg{ 43805b261ecSmrg if (hwp->paletteEnabled) 43935c4bbdfSmrg index &= ~0x20; 44005b261ecSmrg else 44135c4bbdfSmrg index |= 0x20; 44205b261ecSmrg 44305b261ecSmrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 44405b261ecSmrg moutb(VGA_ATTR_INDEX, index); 44505b261ecSmrg moutb(VGA_ATTR_DATA_W, value); 44605b261ecSmrg} 44705b261ecSmrg 44805b261ecSmrgstatic CARD8 44905b261ecSmrgmmioReadAttr(vgaHWPtr hwp, CARD8 index) 45005b261ecSmrg{ 45105b261ecSmrg if (hwp->paletteEnabled) 45235c4bbdfSmrg index &= ~0x20; 45305b261ecSmrg else 45435c4bbdfSmrg index |= 0x20; 45505b261ecSmrg 45605b261ecSmrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 45705b261ecSmrg moutb(VGA_ATTR_INDEX, index); 45805b261ecSmrg return minb(VGA_ATTR_DATA_R); 45905b261ecSmrg} 46005b261ecSmrg 46105b261ecSmrgstatic void 46205b261ecSmrgmmioWriteMiscOut(vgaHWPtr hwp, CARD8 value) 46305b261ecSmrg{ 46405b261ecSmrg moutb(VGA_MISC_OUT_W, value); 46505b261ecSmrg} 46605b261ecSmrg 46705b261ecSmrgstatic CARD8 46805b261ecSmrgmmioReadMiscOut(vgaHWPtr hwp) 46905b261ecSmrg{ 47005b261ecSmrg return minb(VGA_MISC_OUT_R); 47105b261ecSmrg} 47205b261ecSmrg 47305b261ecSmrgstatic void 47405b261ecSmrgmmioEnablePalette(vgaHWPtr hwp) 47505b261ecSmrg{ 47605b261ecSmrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 47705b261ecSmrg moutb(VGA_ATTR_INDEX, 0x00); 47805b261ecSmrg hwp->paletteEnabled = TRUE; 47905b261ecSmrg} 48005b261ecSmrg 48105b261ecSmrgstatic void 48205b261ecSmrgmmioDisablePalette(vgaHWPtr hwp) 48305b261ecSmrg{ 48405b261ecSmrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 48505b261ecSmrg moutb(VGA_ATTR_INDEX, 0x20); 48605b261ecSmrg hwp->paletteEnabled = FALSE; 48705b261ecSmrg} 48805b261ecSmrg 48905b261ecSmrgstatic void 49005b261ecSmrgmmioWriteDacMask(vgaHWPtr hwp, CARD8 value) 49105b261ecSmrg{ 49205b261ecSmrg moutb(VGA_DAC_MASK, value); 49305b261ecSmrg} 49405b261ecSmrg 49505b261ecSmrgstatic CARD8 49605b261ecSmrgmmioReadDacMask(vgaHWPtr hwp) 49705b261ecSmrg{ 49805b261ecSmrg return minb(VGA_DAC_MASK); 49905b261ecSmrg} 50005b261ecSmrg 50105b261ecSmrgstatic void 50205b261ecSmrgmmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value) 50305b261ecSmrg{ 50405b261ecSmrg moutb(VGA_DAC_READ_ADDR, value); 50505b261ecSmrg} 50605b261ecSmrg 50705b261ecSmrgstatic void 50805b261ecSmrgmmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value) 50905b261ecSmrg{ 51005b261ecSmrg moutb(VGA_DAC_WRITE_ADDR, value); 51105b261ecSmrg} 51205b261ecSmrg 51305b261ecSmrgstatic void 51405b261ecSmrgmmioWriteDacData(vgaHWPtr hwp, CARD8 value) 51505b261ecSmrg{ 51605b261ecSmrg moutb(VGA_DAC_DATA, value); 51705b261ecSmrg} 51805b261ecSmrg 51905b261ecSmrgstatic CARD8 52005b261ecSmrgmmioReadDacData(vgaHWPtr hwp) 52105b261ecSmrg{ 52205b261ecSmrg return minb(VGA_DAC_DATA); 52305b261ecSmrg} 52405b261ecSmrg 52505b261ecSmrgstatic CARD8 52605b261ecSmrgmmioReadEnable(vgaHWPtr hwp) 52705b261ecSmrg{ 52805b261ecSmrg return minb(VGA_ENABLE); 52905b261ecSmrg} 53005b261ecSmrg 53105b261ecSmrgstatic void 53205b261ecSmrgmmioWriteEnable(vgaHWPtr hwp, CARD8 value) 53305b261ecSmrg{ 53405b261ecSmrg moutb(VGA_ENABLE, value); 53505b261ecSmrg} 53605b261ecSmrg 53705b261ecSmrgvoid 53805b261ecSmrgvgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset) 53905b261ecSmrg{ 54035c4bbdfSmrg hwp->writeCrtc = mmioWriteCrtc; 54135c4bbdfSmrg hwp->readCrtc = mmioReadCrtc; 54235c4bbdfSmrg hwp->writeGr = mmioWriteGr; 54335c4bbdfSmrg hwp->readGr = mmioReadGr; 54435c4bbdfSmrg hwp->readST00 = mmioReadST00; 54535c4bbdfSmrg hwp->readST01 = mmioReadST01; 54635c4bbdfSmrg hwp->readFCR = mmioReadFCR; 54735c4bbdfSmrg hwp->writeFCR = mmioWriteFCR; 54835c4bbdfSmrg hwp->writeAttr = mmioWriteAttr; 54935c4bbdfSmrg hwp->readAttr = mmioReadAttr; 55035c4bbdfSmrg hwp->writeSeq = mmioWriteSeq; 55135c4bbdfSmrg hwp->readSeq = mmioReadSeq; 55235c4bbdfSmrg hwp->writeMiscOut = mmioWriteMiscOut; 55335c4bbdfSmrg hwp->readMiscOut = mmioReadMiscOut; 55435c4bbdfSmrg hwp->enablePalette = mmioEnablePalette; 55535c4bbdfSmrg hwp->disablePalette = mmioDisablePalette; 55635c4bbdfSmrg hwp->writeDacMask = mmioWriteDacMask; 55735c4bbdfSmrg hwp->readDacMask = mmioReadDacMask; 55835c4bbdfSmrg hwp->writeDacWriteAddr = mmioWriteDacWriteAddr; 55935c4bbdfSmrg hwp->writeDacReadAddr = mmioWriteDacReadAddr; 56035c4bbdfSmrg hwp->writeDacData = mmioWriteDacData; 56135c4bbdfSmrg hwp->readDacData = mmioReadDacData; 56235c4bbdfSmrg hwp->MMIOBase = base; 56335c4bbdfSmrg hwp->MMIOOffset = offset; 56435c4bbdfSmrg hwp->readEnable = mmioReadEnable; 56535c4bbdfSmrg hwp->writeEnable = mmioWriteEnable; 56605b261ecSmrg} 56705b261ecSmrg 56805b261ecSmrg/* 56905b261ecSmrg * vgaHWProtect -- 57005b261ecSmrg * Protect VGA registers and memory from corruption during loads. 57105b261ecSmrg */ 57205b261ecSmrg 57305b261ecSmrgvoid 57405b261ecSmrgvgaHWProtect(ScrnInfoPtr pScrn, Bool on) 57505b261ecSmrg{ 57635c4bbdfSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 57735c4bbdfSmrg 57835c4bbdfSmrg unsigned char tmp; 57935c4bbdfSmrg 58035c4bbdfSmrg if (pScrn->vtSema) { 58135c4bbdfSmrg if (on) { 58235c4bbdfSmrg /* 58335c4bbdfSmrg * Turn off screen and disable sequencer. 58435c4bbdfSmrg */ 58535c4bbdfSmrg tmp = hwp->readSeq(hwp, 0x01); 58635c4bbdfSmrg 58735c4bbdfSmrg vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */ 58835c4bbdfSmrg hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */ 58935c4bbdfSmrg 59035c4bbdfSmrg hwp->enablePalette(hwp); 59135c4bbdfSmrg } 59235c4bbdfSmrg else { 59335c4bbdfSmrg /* 594ed6184dfSmrg * Re-enable sequencer, then turn on screen. 59535c4bbdfSmrg */ 59635c4bbdfSmrg 59735c4bbdfSmrg tmp = hwp->readSeq(hwp, 0x01); 59835c4bbdfSmrg 599ed6184dfSmrg hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* re-enable display */ 60035c4bbdfSmrg vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */ 60135c4bbdfSmrg 60235c4bbdfSmrg hwp->disablePalette(hwp); 60335c4bbdfSmrg } 60405b261ecSmrg } 60505b261ecSmrg} 60605b261ecSmrg 60735c4bbdfSmrgvgaHWProtectProc * 60835c4bbdfSmrgvgaHWProtectWeak(void) 60935c4bbdfSmrg{ 61035c4bbdfSmrg return vgaHWProtect; 61105b261ecSmrg} 61205b261ecSmrg 61305b261ecSmrg/* 61405b261ecSmrg * vgaHWBlankScreen -- blank the screen. 61505b261ecSmrg */ 61605b261ecSmrg 61705b261ecSmrgvoid 61805b261ecSmrgvgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on) 61905b261ecSmrg{ 62035c4bbdfSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 62135c4bbdfSmrg unsigned char scrn; 62205b261ecSmrg 62335c4bbdfSmrg scrn = hwp->readSeq(hwp, 0x01); 62405b261ecSmrg 62535c4bbdfSmrg if (on) { 62635c4bbdfSmrg scrn &= ~0x20; /* enable screen */ 62735c4bbdfSmrg } 62835c4bbdfSmrg else { 62935c4bbdfSmrg scrn |= 0x20; /* blank screen */ 63035c4bbdfSmrg } 63105b261ecSmrg 63235c4bbdfSmrg vgaHWSeqReset(hwp, TRUE); 63335c4bbdfSmrg hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 63435c4bbdfSmrg vgaHWSeqReset(hwp, FALSE); 63505b261ecSmrg} 63605b261ecSmrg 63735c4bbdfSmrgvgaHWBlankScreenProc * 63835c4bbdfSmrgvgaHWBlankScreenWeak(void) 63935c4bbdfSmrg{ 64035c4bbdfSmrg return vgaHWBlankScreen; 64135c4bbdfSmrg} 64205b261ecSmrg 64305b261ecSmrg/* 64405b261ecSmrg * vgaHWSaveScreen -- blank the screen. 64505b261ecSmrg */ 64605b261ecSmrg 64705b261ecSmrgBool 64805b261ecSmrgvgaHWSaveScreen(ScreenPtr pScreen, int mode) 64905b261ecSmrg{ 65035c4bbdfSmrg ScrnInfoPtr pScrn = NULL; 65135c4bbdfSmrg Bool on; 65205b261ecSmrg 65335c4bbdfSmrg if (pScreen != NULL) 65435c4bbdfSmrg pScrn = xf86ScreenToScrn(pScreen); 65505b261ecSmrg 65635c4bbdfSmrg on = xf86IsUnblank(mode); 65705b261ecSmrg 65805b261ecSmrg#if 0 65935c4bbdfSmrg if (on) 66035c4bbdfSmrg SetTimeSinceLastInputEvent(); 66105b261ecSmrg#endif 66205b261ecSmrg 66335c4bbdfSmrg if ((pScrn != NULL) && pScrn->vtSema) { 66435c4bbdfSmrg vgaHWBlankScreen(pScrn, on); 66535c4bbdfSmrg } 66635c4bbdfSmrg return TRUE; 66705b261ecSmrg} 66805b261ecSmrg 66905b261ecSmrg/* 67005b261ecSmrg * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode 67105b261ecSmrg * 67205b261ecSmrg * This generic VGA function can only set the Off and On modes. If the 67305b261ecSmrg * Standby and Suspend modes are to be supported, a chip specific replacement 67405b261ecSmrg * for this function must be written. 67505b261ecSmrg */ 67605b261ecSmrg 67705b261ecSmrgvoid 67805b261ecSmrgvgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) 67905b261ecSmrg{ 68035c4bbdfSmrg unsigned char seq1 = 0, crtc17 = 0; 68135c4bbdfSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 68205b261ecSmrg 68335c4bbdfSmrg if (!pScrn->vtSema) 68435c4bbdfSmrg return; 68535c4bbdfSmrg 68635c4bbdfSmrg switch (PowerManagementMode) { 68735c4bbdfSmrg case DPMSModeOn: 68835c4bbdfSmrg /* Screen: On; HSync: On, VSync: On */ 68935c4bbdfSmrg seq1 = 0x00; 69035c4bbdfSmrg crtc17 = 0x80; 69135c4bbdfSmrg break; 69235c4bbdfSmrg case DPMSModeStandby: 69335c4bbdfSmrg /* Screen: Off; HSync: Off, VSync: On -- Not Supported */ 69435c4bbdfSmrg seq1 = 0x20; 69535c4bbdfSmrg crtc17 = 0x80; 69635c4bbdfSmrg break; 69735c4bbdfSmrg case DPMSModeSuspend: 69835c4bbdfSmrg /* Screen: Off; HSync: On, VSync: Off -- Not Supported */ 69935c4bbdfSmrg seq1 = 0x20; 70035c4bbdfSmrg crtc17 = 0x80; 70135c4bbdfSmrg break; 70235c4bbdfSmrg case DPMSModeOff: 70335c4bbdfSmrg /* Screen: Off; HSync: Off, VSync: Off */ 70435c4bbdfSmrg seq1 = 0x20; 70535c4bbdfSmrg crtc17 = 0x00; 70635c4bbdfSmrg break; 70735c4bbdfSmrg } 70835c4bbdfSmrg hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */ 70935c4bbdfSmrg seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20; 71035c4bbdfSmrg hwp->writeSeq(hwp, 0x01, seq1); 71135c4bbdfSmrg crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80; 71235c4bbdfSmrg usleep(10000); 71335c4bbdfSmrg hwp->writeCrtc(hwp, 0x17, crtc17); 71435c4bbdfSmrg hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */ 71535c4bbdfSmrg} 71605b261ecSmrg 71705b261ecSmrg/* 71805b261ecSmrg * vgaHWSeqReset 71905b261ecSmrg * perform a sequencer reset. 72005b261ecSmrg */ 72105b261ecSmrg 72205b261ecSmrgvoid 72305b261ecSmrgvgaHWSeqReset(vgaHWPtr hwp, Bool start) 72405b261ecSmrg{ 72535c4bbdfSmrg if (start) 72635c4bbdfSmrg hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */ 72735c4bbdfSmrg else 72835c4bbdfSmrg hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */ 72905b261ecSmrg} 73005b261ecSmrg 73105b261ecSmrgvoid 73205b261ecSmrgvgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) 73305b261ecSmrg{ 73405b261ecSmrg#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 73505b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 73605b261ecSmrg int savedIOBase; 73705b261ecSmrg unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4; 73805b261ecSmrg Bool doMap = FALSE; 73905b261ecSmrg 74005b261ecSmrg /* If nothing to do, return now */ 74105b261ecSmrg if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo) 74235c4bbdfSmrg return; 74305b261ecSmrg 74405b261ecSmrg if (hwp->Base == NULL) { 74535c4bbdfSmrg doMap = TRUE; 74635c4bbdfSmrg if (!vgaHWMapMem(scrninfp)) { 74735c4bbdfSmrg xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, 74835c4bbdfSmrg "vgaHWRestoreFonts: vgaHWMapMem() failed\n"); 74935c4bbdfSmrg return; 75035c4bbdfSmrg } 75105b261ecSmrg } 75205b261ecSmrg 75305b261ecSmrg /* save the registers that are needed here */ 75405b261ecSmrg miscOut = hwp->readMiscOut(hwp); 75505b261ecSmrg attr10 = hwp->readAttr(hwp, 0x10); 75605b261ecSmrg gr1 = hwp->readGr(hwp, 0x01); 75705b261ecSmrg gr3 = hwp->readGr(hwp, 0x03); 75805b261ecSmrg gr4 = hwp->readGr(hwp, 0x04); 75905b261ecSmrg gr5 = hwp->readGr(hwp, 0x05); 76005b261ecSmrg gr6 = hwp->readGr(hwp, 0x06); 76105b261ecSmrg gr8 = hwp->readGr(hwp, 0x08); 76205b261ecSmrg seq2 = hwp->readSeq(hwp, 0x02); 76305b261ecSmrg seq4 = hwp->readSeq(hwp, 0x04); 76405b261ecSmrg 76505b261ecSmrg /* save hwp->IOBase and temporarily set it for colour mode */ 76605b261ecSmrg savedIOBase = hwp->IOBase; 76705b261ecSmrg hwp->IOBase = VGA_IOBASE_COLOR; 76805b261ecSmrg 76905b261ecSmrg /* Force into colour mode */ 77005b261ecSmrg hwp->writeMiscOut(hwp, miscOut | 0x01); 77105b261ecSmrg 77205b261ecSmrg vgaHWBlankScreen(scrninfp, FALSE); 77305b261ecSmrg 77405b261ecSmrg /* 77505b261ecSmrg * here we temporarily switch to 16 colour planar mode, to simply 77605b261ecSmrg * copy the font-info and saved text. 77705b261ecSmrg * 77805b261ecSmrg * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! 77905b261ecSmrg */ 78005b261ecSmrg#if 0 78135c4bbdfSmrg hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ 78205b261ecSmrg#endif 78305b261ecSmrg 78435c4bbdfSmrg hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ 78535c4bbdfSmrg hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ 78635c4bbdfSmrg hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ 78705b261ecSmrg 78805b261ecSmrg if (scrninfp->depth == 4) { 78935c4bbdfSmrg /* GJA */ 79035c4bbdfSmrg hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */ 79135c4bbdfSmrg hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */ 79235c4bbdfSmrg hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */ 79305b261ecSmrg } 79405b261ecSmrg 79505b261ecSmrg#if SAVE_FONT1 79605b261ecSmrg if (hwp->FontInfo1) { 79735c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ 79835c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ 79935c4bbdfSmrg slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT); 80005b261ecSmrg } 80105b261ecSmrg#endif 80205b261ecSmrg 80305b261ecSmrg#if SAVE_FONT2 80405b261ecSmrg if (hwp->FontInfo2) { 80535c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ 80635c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ 80735c4bbdfSmrg slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT); 80805b261ecSmrg } 80905b261ecSmrg#endif 81005b261ecSmrg 81105b261ecSmrg#if SAVE_TEXT 81205b261ecSmrg if (hwp->TextInfo) { 81335c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ 81435c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ 81535c4bbdfSmrg slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT); 81635c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ 81735c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ 81835c4bbdfSmrg slowbcopy_tobus((unsigned char *) hwp->TextInfo + TEXT_AMOUNT, 81935c4bbdfSmrg hwp->Base, TEXT_AMOUNT); 82005b261ecSmrg } 82105b261ecSmrg#endif 82205b261ecSmrg 82305b261ecSmrg vgaHWBlankScreen(scrninfp, TRUE); 82405b261ecSmrg 82505b261ecSmrg /* restore the registers that were changed */ 82605b261ecSmrg hwp->writeMiscOut(hwp, miscOut); 82705b261ecSmrg hwp->writeAttr(hwp, 0x10, attr10); 82805b261ecSmrg hwp->writeGr(hwp, 0x01, gr1); 82905b261ecSmrg hwp->writeGr(hwp, 0x03, gr3); 83005b261ecSmrg hwp->writeGr(hwp, 0x04, gr4); 83105b261ecSmrg hwp->writeGr(hwp, 0x05, gr5); 83205b261ecSmrg hwp->writeGr(hwp, 0x06, gr6); 83305b261ecSmrg hwp->writeGr(hwp, 0x08, gr8); 83405b261ecSmrg hwp->writeSeq(hwp, 0x02, seq2); 83505b261ecSmrg hwp->writeSeq(hwp, 0x04, seq4); 83605b261ecSmrg hwp->IOBase = savedIOBase; 83705b261ecSmrg 83805b261ecSmrg if (doMap) 83935c4bbdfSmrg vgaHWUnmapMem(scrninfp); 84005b261ecSmrg 84135c4bbdfSmrg#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */ 84205b261ecSmrg} 84305b261ecSmrg 84405b261ecSmrgvoid 84505b261ecSmrgvgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore) 84605b261ecSmrg{ 84705b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 84805b261ecSmrg int i; 84905b261ecSmrg 85005b261ecSmrg if (restore->MiscOutReg & 0x01) 85135c4bbdfSmrg hwp->IOBase = VGA_IOBASE_COLOR; 85205b261ecSmrg else 85335c4bbdfSmrg hwp->IOBase = VGA_IOBASE_MONO; 85405b261ecSmrg 85505b261ecSmrg hwp->writeMiscOut(hwp, restore->MiscOutReg); 85605b261ecSmrg 85705b261ecSmrg for (i = 1; i < restore->numSequencer; i++) 85835c4bbdfSmrg hwp->writeSeq(hwp, i, restore->Sequencer[i]); 85935c4bbdfSmrg 86005b261ecSmrg /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */ 86105b261ecSmrg hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80); 86205b261ecSmrg 86305b261ecSmrg for (i = 0; i < restore->numCRTC; i++) 86435c4bbdfSmrg hwp->writeCrtc(hwp, i, restore->CRTC[i]); 86505b261ecSmrg 86605b261ecSmrg for (i = 0; i < restore->numGraphics; i++) 86735c4bbdfSmrg hwp->writeGr(hwp, i, restore->Graphics[i]); 86805b261ecSmrg 86905b261ecSmrg hwp->enablePalette(hwp); 87005b261ecSmrg for (i = 0; i < restore->numAttribute; i++) 87135c4bbdfSmrg hwp->writeAttr(hwp, i, restore->Attribute[i]); 87205b261ecSmrg hwp->disablePalette(hwp); 87305b261ecSmrg} 87405b261ecSmrg 87505b261ecSmrgvoid 87605b261ecSmrgvgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore) 87705b261ecSmrg{ 87805b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 87905b261ecSmrg int i; 88005b261ecSmrg 88105b261ecSmrg#if 0 88205b261ecSmrg hwp->enablePalette(hwp); 88305b261ecSmrg#endif 88405b261ecSmrg 88505b261ecSmrg hwp->writeDacMask(hwp, 0xFF); 88605b261ecSmrg hwp->writeDacWriteAddr(hwp, 0x00); 88705b261ecSmrg for (i = 0; i < 768; i++) { 88835c4bbdfSmrg hwp->writeDacData(hwp, restore->DAC[i]); 88935c4bbdfSmrg DACDelay(hwp); 89005b261ecSmrg } 89105b261ecSmrg 89205b261ecSmrg hwp->disablePalette(hwp); 89305b261ecSmrg} 89405b261ecSmrg 89505b261ecSmrg/* 89605b261ecSmrg * vgaHWRestore -- 89705b261ecSmrg * restore the VGA state 89805b261ecSmrg */ 89905b261ecSmrg 90005b261ecSmrgvoid 90105b261ecSmrgvgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags) 90205b261ecSmrg{ 90305b261ecSmrg if (flags & VGA_SR_MODE) 90435c4bbdfSmrg vgaHWRestoreMode(scrninfp, restore); 90505b261ecSmrg 90605b261ecSmrg if (flags & VGA_SR_FONTS) 90735c4bbdfSmrg vgaHWRestoreFonts(scrninfp, restore); 90805b261ecSmrg 90905b261ecSmrg if (flags & VGA_SR_CMAP) 91035c4bbdfSmrg vgaHWRestoreColormap(scrninfp, restore); 91105b261ecSmrg} 91205b261ecSmrg 91305b261ecSmrgvoid 91405b261ecSmrgvgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) 91505b261ecSmrg{ 91605b261ecSmrg#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 91705b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 91805b261ecSmrg int savedIOBase; 91905b261ecSmrg unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4; 92005b261ecSmrg Bool doMap = FALSE; 92105b261ecSmrg 92205b261ecSmrg if (hwp->Base == NULL) { 92335c4bbdfSmrg doMap = TRUE; 92435c4bbdfSmrg if (!vgaHWMapMem(scrninfp)) { 92535c4bbdfSmrg xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, 92635c4bbdfSmrg "vgaHWSaveFonts: vgaHWMapMem() failed\n"); 92735c4bbdfSmrg return; 92835c4bbdfSmrg } 92905b261ecSmrg } 93005b261ecSmrg 93105b261ecSmrg /* If in graphics mode, don't save anything */ 93205b261ecSmrg attr10 = hwp->readAttr(hwp, 0x10); 93305b261ecSmrg if (attr10 & 0x01) 93435c4bbdfSmrg return; 93505b261ecSmrg 93605b261ecSmrg /* save the registers that are needed here */ 93705b261ecSmrg miscOut = hwp->readMiscOut(hwp); 93805b261ecSmrg gr4 = hwp->readGr(hwp, 0x04); 93905b261ecSmrg gr5 = hwp->readGr(hwp, 0x05); 94005b261ecSmrg gr6 = hwp->readGr(hwp, 0x06); 94105b261ecSmrg seq2 = hwp->readSeq(hwp, 0x02); 94205b261ecSmrg seq4 = hwp->readSeq(hwp, 0x04); 94305b261ecSmrg 94405b261ecSmrg /* save hwp->IOBase and temporarily set it for colour mode */ 94505b261ecSmrg savedIOBase = hwp->IOBase; 94605b261ecSmrg hwp->IOBase = VGA_IOBASE_COLOR; 94705b261ecSmrg 94805b261ecSmrg /* Force into colour mode */ 94905b261ecSmrg hwp->writeMiscOut(hwp, miscOut | 0x01); 95005b261ecSmrg 95105b261ecSmrg vgaHWBlankScreen(scrninfp, FALSE); 95235c4bbdfSmrg 95305b261ecSmrg /* 95405b261ecSmrg * get the character sets, and text screen if required 95505b261ecSmrg */ 95605b261ecSmrg /* 95705b261ecSmrg * Here we temporarily switch to 16 colour planar mode, to simply 95805b261ecSmrg * copy the font-info 95905b261ecSmrg * 96005b261ecSmrg * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! 96105b261ecSmrg */ 96205b261ecSmrg#if 0 96335c4bbdfSmrg hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ 96405b261ecSmrg#endif 96505b261ecSmrg 96635c4bbdfSmrg hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ 96735c4bbdfSmrg hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ 96835c4bbdfSmrg hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ 96905b261ecSmrg 97005b261ecSmrg#if SAVE_FONT1 9716747b715Smrg if (hwp->FontInfo1 || (hwp->FontInfo1 = malloc(FONT_AMOUNT))) { 97235c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ 97335c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ 97435c4bbdfSmrg slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT); 97505b261ecSmrg } 97635c4bbdfSmrg#endif /* SAVE_FONT1 */ 97705b261ecSmrg#if SAVE_FONT2 9786747b715Smrg if (hwp->FontInfo2 || (hwp->FontInfo2 = malloc(FONT_AMOUNT))) { 97935c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ 98035c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ 98135c4bbdfSmrg slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT); 98205b261ecSmrg } 98335c4bbdfSmrg#endif /* SAVE_FONT2 */ 98405b261ecSmrg#if SAVE_TEXT 9856747b715Smrg if (hwp->TextInfo || (hwp->TextInfo = malloc(2 * TEXT_AMOUNT))) { 98635c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ 98735c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ 98835c4bbdfSmrg slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT); 98935c4bbdfSmrg hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ 99035c4bbdfSmrg hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ 99135c4bbdfSmrg slowbcopy_frombus(hwp->Base, 99235c4bbdfSmrg (unsigned char *) hwp->TextInfo + TEXT_AMOUNT, 99335c4bbdfSmrg TEXT_AMOUNT); 99405b261ecSmrg } 99535c4bbdfSmrg#endif /* SAVE_TEXT */ 99605b261ecSmrg 99705b261ecSmrg /* Restore clobbered registers */ 99805b261ecSmrg hwp->writeAttr(hwp, 0x10, attr10); 99905b261ecSmrg hwp->writeSeq(hwp, 0x02, seq2); 100005b261ecSmrg hwp->writeSeq(hwp, 0x04, seq4); 100105b261ecSmrg hwp->writeGr(hwp, 0x04, gr4); 100205b261ecSmrg hwp->writeGr(hwp, 0x05, gr5); 100305b261ecSmrg hwp->writeGr(hwp, 0x06, gr6); 100405b261ecSmrg hwp->writeMiscOut(hwp, miscOut); 100505b261ecSmrg hwp->IOBase = savedIOBase; 100605b261ecSmrg 100705b261ecSmrg vgaHWBlankScreen(scrninfp, TRUE); 100805b261ecSmrg 100905b261ecSmrg if (doMap) 101035c4bbdfSmrg vgaHWUnmapMem(scrninfp); 101105b261ecSmrg 101235c4bbdfSmrg#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */ 101305b261ecSmrg} 101405b261ecSmrg 101505b261ecSmrgvoid 101605b261ecSmrgvgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save) 101705b261ecSmrg{ 101805b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 101905b261ecSmrg int i; 102005b261ecSmrg 102105b261ecSmrg save->MiscOutReg = hwp->readMiscOut(hwp); 102205b261ecSmrg if (save->MiscOutReg & 0x01) 102335c4bbdfSmrg hwp->IOBase = VGA_IOBASE_COLOR; 102405b261ecSmrg else 102535c4bbdfSmrg hwp->IOBase = VGA_IOBASE_MONO; 102605b261ecSmrg 102705b261ecSmrg for (i = 0; i < save->numCRTC; i++) { 102835c4bbdfSmrg save->CRTC[i] = hwp->readCrtc(hwp, i); 102935c4bbdfSmrg DebugF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]); 103005b261ecSmrg } 103105b261ecSmrg 103205b261ecSmrg hwp->enablePalette(hwp); 103305b261ecSmrg for (i = 0; i < save->numAttribute; i++) { 103435c4bbdfSmrg save->Attribute[i] = hwp->readAttr(hwp, i); 103535c4bbdfSmrg DebugF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]); 103605b261ecSmrg } 103705b261ecSmrg hwp->disablePalette(hwp); 103805b261ecSmrg 103905b261ecSmrg for (i = 0; i < save->numGraphics; i++) { 104035c4bbdfSmrg save->Graphics[i] = hwp->readGr(hwp, i); 104135c4bbdfSmrg DebugF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]); 104205b261ecSmrg } 104305b261ecSmrg 104405b261ecSmrg for (i = 1; i < save->numSequencer; i++) { 104535c4bbdfSmrg save->Sequencer[i] = hwp->readSeq(hwp, i); 104635c4bbdfSmrg DebugF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]); 104705b261ecSmrg } 104805b261ecSmrg} 104905b261ecSmrg 105005b261ecSmrgvoid 105105b261ecSmrgvgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save) 105205b261ecSmrg{ 105305b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 105405b261ecSmrg Bool readError = FALSE; 105505b261ecSmrg int i; 105605b261ecSmrg 105705b261ecSmrg#ifdef NEED_SAVED_CMAP 105805b261ecSmrg /* 105905b261ecSmrg * Some ET4000 chips from 1991 have a HW bug that prevents the reading 106005b261ecSmrg * of the color lookup table. Mask rev 9042EAI is known to have this bug. 106105b261ecSmrg * 106205b261ecSmrg * If the colourmap is not readable, we set the saved map to a default 106305b261ecSmrg * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA 106405b261ecSmrg * Cards" 2nd ed). 106505b261ecSmrg */ 106605b261ecSmrg 106705b261ecSmrg /* Only save it once */ 106805b261ecSmrg if (hwp->cmapSaved) 106935c4bbdfSmrg return; 107005b261ecSmrg 107105b261ecSmrg#if 0 107205b261ecSmrg hwp->enablePalette(hwp); 107305b261ecSmrg#endif 107405b261ecSmrg 107505b261ecSmrg hwp->writeDacMask(hwp, 0xFF); 107605b261ecSmrg 107705b261ecSmrg /* 107805b261ecSmrg * check if we can read the lookup table 107905b261ecSmrg */ 108005b261ecSmrg hwp->writeDacReadAddr(hwp, 0x00); 108105b261ecSmrg for (i = 0; i < 6; i++) { 108235c4bbdfSmrg save->DAC[i] = hwp->readDacData(hwp); 108335c4bbdfSmrg switch (i % 3) { 108435c4bbdfSmrg case 0: 108535c4bbdfSmrg DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]); 108635c4bbdfSmrg break; 108735c4bbdfSmrg case 1: 108835c4bbdfSmrg DebugF("0x%02x, ", save->DAC[i]); 108935c4bbdfSmrg break; 109035c4bbdfSmrg case 2: 109135c4bbdfSmrg DebugF("0x%02x\n", save->DAC[i]); 109235c4bbdfSmrg } 109305b261ecSmrg } 109405b261ecSmrg 109505b261ecSmrg /* 109605b261ecSmrg * Check if we can read the palette - 109705b261ecSmrg * use foreground color to prevent flashing. 109805b261ecSmrg */ 109905b261ecSmrg hwp->writeDacWriteAddr(hwp, 0x01); 110005b261ecSmrg for (i = 3; i < 6; i++) 110135c4bbdfSmrg hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK); 110205b261ecSmrg hwp->writeDacReadAddr(hwp, 0x01); 110305b261ecSmrg for (i = 3; i < 6; i++) { 110435c4bbdfSmrg if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK)) 110535c4bbdfSmrg readError = TRUE; 110605b261ecSmrg } 110705b261ecSmrg hwp->writeDacWriteAddr(hwp, 0x01); 110805b261ecSmrg for (i = 3; i < 6; i++) 110935c4bbdfSmrg hwp->writeDacData(hwp, save->DAC[i]); 111005b261ecSmrg 111105b261ecSmrg if (readError) { 111235c4bbdfSmrg /* 111335c4bbdfSmrg * save the default lookup table 111435c4bbdfSmrg */ 111535c4bbdfSmrg memmove(save->DAC, defaultDAC, 768); 111635c4bbdfSmrg xf86DrvMsg(scrninfp->scrnIndex, X_WARNING, 111735c4bbdfSmrg "Cannot read colourmap from VGA. Will restore with default\n"); 111835c4bbdfSmrg } 111935c4bbdfSmrg else { 112035c4bbdfSmrg /* save the colourmap */ 112135c4bbdfSmrg hwp->writeDacReadAddr(hwp, 0x02); 112235c4bbdfSmrg for (i = 6; i < 768; i++) { 112335c4bbdfSmrg save->DAC[i] = hwp->readDacData(hwp); 112435c4bbdfSmrg DACDelay(hwp); 112535c4bbdfSmrg switch (i % 3) { 112635c4bbdfSmrg case 0: 112735c4bbdfSmrg DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]); 112835c4bbdfSmrg break; 112935c4bbdfSmrg case 1: 113035c4bbdfSmrg DebugF("0x%02x, ", save->DAC[i]); 113135c4bbdfSmrg break; 113235c4bbdfSmrg case 2: 113335c4bbdfSmrg DebugF("0x%02x\n", save->DAC[i]); 113435c4bbdfSmrg } 113535c4bbdfSmrg } 113605b261ecSmrg } 113705b261ecSmrg 113805b261ecSmrg hwp->disablePalette(hwp); 113905b261ecSmrg hwp->cmapSaved = TRUE; 114005b261ecSmrg#endif 114105b261ecSmrg} 114205b261ecSmrg 114305b261ecSmrg/* 114405b261ecSmrg * vgaHWSave -- 114505b261ecSmrg * save the current VGA state 114605b261ecSmrg */ 114705b261ecSmrg 114805b261ecSmrgvoid 114905b261ecSmrgvgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags) 115005b261ecSmrg{ 115105b261ecSmrg if (save == NULL) 115235c4bbdfSmrg return; 115305b261ecSmrg 115435c4bbdfSmrg if (flags & VGA_SR_CMAP) 115535c4bbdfSmrg vgaHWSaveColormap(scrninfp, save); 115605b261ecSmrg 115735c4bbdfSmrg if (flags & VGA_SR_MODE) 115835c4bbdfSmrg vgaHWSaveMode(scrninfp, save); 115905b261ecSmrg 116035c4bbdfSmrg if (flags & VGA_SR_FONTS) 116135c4bbdfSmrg vgaHWSaveFonts(scrninfp, save); 116205b261ecSmrg} 116305b261ecSmrg 116405b261ecSmrg/* 116505b261ecSmrg * vgaHWInit -- 116605b261ecSmrg * Handle the initialization, etc. of a screen. 116705b261ecSmrg * Return FALSE on failure. 116805b261ecSmrg */ 116905b261ecSmrg 117005b261ecSmrgBool 117105b261ecSmrgvgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode) 117205b261ecSmrg{ 117335c4bbdfSmrg unsigned int i; 117405b261ecSmrg vgaHWPtr hwp; 117505b261ecSmrg vgaRegPtr regp; 117605b261ecSmrg int depth = scrninfp->depth; 117705b261ecSmrg 117805b261ecSmrg /* 117905b261ecSmrg * make sure the vgaHWRec is allocated 118005b261ecSmrg */ 118105b261ecSmrg if (!vgaHWGetHWRec(scrninfp)) 118235c4bbdfSmrg return FALSE; 118305b261ecSmrg hwp = VGAHWPTR(scrninfp); 118405b261ecSmrg regp = &hwp->ModeReg; 118535c4bbdfSmrg 118605b261ecSmrg /* 118735c4bbdfSmrg * compute correct Hsync & Vsync polarity 118805b261ecSmrg */ 118905b261ecSmrg if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) 119035c4bbdfSmrg && (mode->Flags & (V_PVSYNC | V_NVSYNC))) { 119105b261ecSmrg regp->MiscOutReg = 0x23; 119235c4bbdfSmrg if (mode->Flags & V_NHSYNC) 119335c4bbdfSmrg regp->MiscOutReg |= 0x40; 119435c4bbdfSmrg if (mode->Flags & V_NVSYNC) 119535c4bbdfSmrg regp->MiscOutReg |= 0x80; 119605b261ecSmrg } 119735c4bbdfSmrg else { 119805b261ecSmrg int VDisplay = mode->VDisplay; 119935c4bbdfSmrg 120005b261ecSmrg if (mode->Flags & V_DBLSCAN) 120105b261ecSmrg VDisplay *= 2; 120205b261ecSmrg if (mode->VScan > 1) 120305b261ecSmrg VDisplay *= mode->VScan; 120435c4bbdfSmrg if (VDisplay < 400) 120535c4bbdfSmrg regp->MiscOutReg = 0xA3; /* +hsync -vsync */ 120605b261ecSmrg else if (VDisplay < 480) 120735c4bbdfSmrg regp->MiscOutReg = 0x63; /* -hsync +vsync */ 120805b261ecSmrg else if (VDisplay < 768) 120935c4bbdfSmrg regp->MiscOutReg = 0xE3; /* -hsync -vsync */ 121005b261ecSmrg else 121135c4bbdfSmrg regp->MiscOutReg = 0x23; /* +hsync +vsync */ 121205b261ecSmrg } 121335c4bbdfSmrg 121405b261ecSmrg regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2; 121505b261ecSmrg 121605b261ecSmrg /* 121705b261ecSmrg * Time Sequencer 121805b261ecSmrg */ 121905b261ecSmrg if (depth == 4) 122005b261ecSmrg regp->Sequencer[0] = 0x02; 122105b261ecSmrg else 122205b261ecSmrg regp->Sequencer[0] = 0x00; 122335c4bbdfSmrg if (mode->Flags & V_CLKDIV2) 122405b261ecSmrg regp->Sequencer[1] = 0x09; 122505b261ecSmrg else 122605b261ecSmrg regp->Sequencer[1] = 0x01; 122705b261ecSmrg if (depth == 1) 122805b261ecSmrg regp->Sequencer[2] = 1 << BIT_PLANE; 122905b261ecSmrg else 123005b261ecSmrg regp->Sequencer[2] = 0x0F; 123135c4bbdfSmrg regp->Sequencer[3] = 0x00; /* Font select */ 123205b261ecSmrg if (depth < 8) 123335c4bbdfSmrg regp->Sequencer[4] = 0x06; /* Misc */ 123405b261ecSmrg else 123535c4bbdfSmrg regp->Sequencer[4] = 0x0E; /* Misc */ 123605b261ecSmrg 123705b261ecSmrg /* 123805b261ecSmrg * CRTC Controller 123905b261ecSmrg */ 124035c4bbdfSmrg regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5; 124135c4bbdfSmrg regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1; 124235c4bbdfSmrg regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1; 124335c4bbdfSmrg regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80; 124405b261ecSmrg i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F); 124505b261ecSmrg if (i < 0x80) 124635c4bbdfSmrg regp->CRTC[3] |= i; 124735c4bbdfSmrg regp->CRTC[4] = (mode->CrtcHSyncStart >> 3); 124835c4bbdfSmrg regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2) 124935c4bbdfSmrg | (((mode->CrtcHSyncEnd >> 3)) & 0x1F); 125035c4bbdfSmrg regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF; 125135c4bbdfSmrg regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8) 125235c4bbdfSmrg | (((mode->CrtcVDisplay - 1) & 0x100) >> 7) 125335c4bbdfSmrg | ((mode->CrtcVSyncStart & 0x100) >> 6) 125435c4bbdfSmrg | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5) 125535c4bbdfSmrg | 0x10 | (((mode->CrtcVTotal - 2) & 0x200) >> 4) 125635c4bbdfSmrg | (((mode->CrtcVDisplay - 1) & 0x200) >> 3) 125735c4bbdfSmrg | ((mode->CrtcVSyncStart & 0x200) >> 2); 125835c4bbdfSmrg regp->CRTC[8] = 0x00; 125935c4bbdfSmrg regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40; 126005b261ecSmrg if (mode->Flags & V_DBLSCAN) 126135c4bbdfSmrg regp->CRTC[9] |= 0x80; 126205b261ecSmrg if (mode->VScan >= 32) 126335c4bbdfSmrg regp->CRTC[9] |= 0x1F; 126405b261ecSmrg else if (mode->VScan > 1) 126535c4bbdfSmrg regp->CRTC[9] |= mode->VScan - 1; 126605b261ecSmrg regp->CRTC[10] = 0x00; 126705b261ecSmrg regp->CRTC[11] = 0x00; 126805b261ecSmrg regp->CRTC[12] = 0x00; 126905b261ecSmrg regp->CRTC[13] = 0x00; 127005b261ecSmrg regp->CRTC[14] = 0x00; 127105b261ecSmrg regp->CRTC[15] = 0x00; 127205b261ecSmrg regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF; 127305b261ecSmrg regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20; 127405b261ecSmrg regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF; 127535c4bbdfSmrg regp->CRTC[19] = scrninfp->displayWidth >> 4; /* just a guess */ 127605b261ecSmrg regp->CRTC[20] = 0x00; 127735c4bbdfSmrg regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF; 127805b261ecSmrg regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; 127905b261ecSmrg if (depth < 8) 128035c4bbdfSmrg regp->CRTC[23] = 0xE3; 128105b261ecSmrg else 128235c4bbdfSmrg regp->CRTC[23] = 0xC3; 128305b261ecSmrg regp->CRTC[24] = 0xFF; 128405b261ecSmrg 128505b261ecSmrg vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO); 128605b261ecSmrg vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO); 128705b261ecSmrg 128805b261ecSmrg /* 128905b261ecSmrg * Theory resumes here.... 129005b261ecSmrg */ 129105b261ecSmrg 129205b261ecSmrg /* 129305b261ecSmrg * Graphics Display Controller 129405b261ecSmrg */ 129505b261ecSmrg regp->Graphics[0] = 0x00; 129605b261ecSmrg regp->Graphics[1] = 0x00; 129705b261ecSmrg regp->Graphics[2] = 0x00; 129805b261ecSmrg regp->Graphics[3] = 0x00; 129905b261ecSmrg if (depth == 1) { 130005b261ecSmrg regp->Graphics[4] = BIT_PLANE; 130105b261ecSmrg regp->Graphics[5] = 0x00; 130235c4bbdfSmrg } 130335c4bbdfSmrg else { 130405b261ecSmrg regp->Graphics[4] = 0x00; 130505b261ecSmrg if (depth == 4) 130605b261ecSmrg regp->Graphics[5] = 0x02; 130705b261ecSmrg else 130805b261ecSmrg regp->Graphics[5] = 0x40; 130905b261ecSmrg } 131005b261ecSmrg regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */ 131105b261ecSmrg regp->Graphics[7] = 0x0F; 131205b261ecSmrg regp->Graphics[8] = 0xFF; 131335c4bbdfSmrg 131405b261ecSmrg if (depth == 1) { 131505b261ecSmrg /* Initialise the Mono map according to which bit-plane gets used */ 131605b261ecSmrg 13179b06bd19Stsutsui Bool flipPixels = xf86GetFlipPixels(); 13189b06bd19Stsutsui 131935c4bbdfSmrg for (i = 0; i < 16; i++) 13209b06bd19Stsutsui if (((i & (1 << BIT_PLANE)) != 0) != flipPixels) 132105b261ecSmrg regp->Attribute[i] = WHITE_VALUE; 132205b261ecSmrg else 132305b261ecSmrg regp->Attribute[i] = BLACK_VALUE; 132405b261ecSmrg 132535c4bbdfSmrg regp->Attribute[16] = 0x01; /* -VGA2- *//* wrong for the ET4000 */ 132635c4bbdfSmrg if (!hwp->ShowOverscan) 132735c4bbdfSmrg regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */ 132835c4bbdfSmrg } 132935c4bbdfSmrg else { 133035c4bbdfSmrg regp->Attribute[0] = 0x00; /* standard colormap translation */ 133135c4bbdfSmrg regp->Attribute[1] = 0x01; 133235c4bbdfSmrg regp->Attribute[2] = 0x02; 133335c4bbdfSmrg regp->Attribute[3] = 0x03; 133435c4bbdfSmrg regp->Attribute[4] = 0x04; 133535c4bbdfSmrg regp->Attribute[5] = 0x05; 133635c4bbdfSmrg regp->Attribute[6] = 0x06; 133735c4bbdfSmrg regp->Attribute[7] = 0x07; 133835c4bbdfSmrg regp->Attribute[8] = 0x08; 133935c4bbdfSmrg regp->Attribute[9] = 0x09; 134005b261ecSmrg regp->Attribute[10] = 0x0A; 134105b261ecSmrg regp->Attribute[11] = 0x0B; 134205b261ecSmrg regp->Attribute[12] = 0x0C; 134305b261ecSmrg regp->Attribute[13] = 0x0D; 134405b261ecSmrg regp->Attribute[14] = 0x0E; 134505b261ecSmrg regp->Attribute[15] = 0x0F; 134605b261ecSmrg if (depth == 4) 134705b261ecSmrg regp->Attribute[16] = 0x81; /* wrong for the ET4000 */ 134805b261ecSmrg else 134905b261ecSmrg regp->Attribute[16] = 0x41; /* wrong for the ET4000 */ 135005b261ecSmrg /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */ 135105b261ecSmrg } 135205b261ecSmrg regp->Attribute[18] = 0x0F; 135305b261ecSmrg regp->Attribute[19] = 0x00; 135405b261ecSmrg regp->Attribute[20] = 0x00; 135505b261ecSmrg 13566747b715Smrg return TRUE; 135705b261ecSmrg} 135805b261ecSmrg 135905b261ecSmrg /* 136005b261ecSmrg * OK, so much for theory. Now, let's deal with the >real< world... 136105b261ecSmrg * 136205b261ecSmrg * The above CRTC settings are precise in theory, except that many, if not 136305b261ecSmrg * most, VGA clones fail to reset the blanking signal when the character or 136405b261ecSmrg * line counter reaches [HV]Total. In this case, the signal is only 136505b261ecSmrg * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as 136605b261ecSmrg * the case may be) at the start of the >next< scanline or frame, which 136705b261ecSmrg * means only part of the screen shows. This affects how null overscans 136805b261ecSmrg * are to be implemented on such adapters. 136905b261ecSmrg * 137005b261ecSmrg * Henceforth, VGA cores that implement this broken, but unfortunately 137105b261ecSmrg * common, behaviour are to be designated as KGA's, in honour of Koen 137205b261ecSmrg * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion 137305b261ecSmrg * a series of events that led to the discovery of this problem. 137405b261ecSmrg * 137505b261ecSmrg * Some VGA's are KGA's only in the horizontal, or only in the vertical, 137605b261ecSmrg * some in both, others in neither. Don't let anyone tell you there is 137705b261ecSmrg * such a thing as a VGA "standard"... And, thank the Creator for the fact 137805b261ecSmrg * that Hilbert spaces are not yet implemented in this industry. 137905b261ecSmrg * 138005b261ecSmrg * The following implements a trick suggested by David Dawes. This sets 138105b261ecSmrg * [HV]BlankEnd to zero if the blanking interval does not already contain a 138205b261ecSmrg * 0-point, and decrements it by one otherwise. In the latter case, this 138305b261ecSmrg * will produce a left and/or top overscan which the colourmap code will 138405b261ecSmrg * (still) need to ensure is as close to black as possible. This will make 138505b261ecSmrg * the behaviour consistent across all chipsets, while allowing all 138605b261ecSmrg * chipsets to display the entire screen. Non-KGA drivers can ignore the 138705b261ecSmrg * following in their own copy of this code. 138805b261ecSmrg * 138905b261ecSmrg * -- TSI @ UQV, 1998.08.21 139005b261ecSmrg */ 139105b261ecSmrg 139205b261ecSmrgCARD32 139335c4bbdfSmrgvgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 139435c4bbdfSmrg unsigned int Flags) 139505b261ecSmrg{ 139605b261ecSmrg int nExtBits = (nBits < 6) ? 0 : nBits - 6; 139705b261ecSmrg CARD32 ExtBits; 139805b261ecSmrg CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6; 139905b261ecSmrg 140035c4bbdfSmrg regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) 140135c4bbdfSmrg | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F); 140235c4bbdfSmrg regp->CRTC[5] = (regp->CRTC[5] & ~0x80) 140335c4bbdfSmrg | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2); 140435c4bbdfSmrg ExtBits = ((mode->CrtcHBlankEnd >> 3) - 1) & ExtBitMask; 140505b261ecSmrg 140605b261ecSmrg /* First the horizontal case */ 140705b261ecSmrg if ((Flags & KGA_FIX_OVERSCAN) 140835c4bbdfSmrg && ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3))) { 140935c4bbdfSmrg int i = (regp->CRTC[3] & 0x1F) 141035c4bbdfSmrg | ((regp->CRTC[5] & 0x80) >> 2) 141135c4bbdfSmrg | ExtBits; 141235c4bbdfSmrg 141335c4bbdfSmrg if (Flags & KGA_ENABLE_ON_ZERO) { 141435c4bbdfSmrg if ((i-- > (((mode->CrtcHBlankStart >> 3) - 1) 141535c4bbdfSmrg & (0x3F | ExtBitMask))) 141635c4bbdfSmrg && (mode->CrtcHBlankEnd == mode->CrtcHTotal)) 141735c4bbdfSmrg i = 0; 141835c4bbdfSmrg } 141935c4bbdfSmrg else if (Flags & KGA_BE_TOT_DEC) 142035c4bbdfSmrg i--; 142135c4bbdfSmrg regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F); 142235c4bbdfSmrg regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80); 142335c4bbdfSmrg ExtBits = i & ExtBitMask; 142405b261ecSmrg } 142505b261ecSmrg return ExtBits >> 6; 142605b261ecSmrg} 142705b261ecSmrg 142805b261ecSmrg /* 142905b261ecSmrg * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of 143005b261ecSmrg * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the 143105b261ecSmrg * very first scanline in a double- or multi-scanned mode. This last case 143205b261ecSmrg * needs further investigation. 143305b261ecSmrg */ 143405b261ecSmrgCARD32 143535c4bbdfSmrgvgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 143635c4bbdfSmrg unsigned int Flags) 143705b261ecSmrg{ 143805b261ecSmrg CARD32 ExtBits; 143905b261ecSmrg CARD32 nExtBits = (nBits < 8) ? 0 : (nBits - 8); 144005b261ecSmrg CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 8; 144135c4bbdfSmrg 144235c4bbdfSmrg /* If width is not known nBits should be 0. In this 144305b261ecSmrg * case BitMask is set to 0 so we can check for it. */ 144405b261ecSmrg CARD32 BitMask = (nBits < 7) ? 0 : ((1 << nExtBits) - 1); 144535c4bbdfSmrg int VBlankStart = (mode->CrtcVBlankStart - 1) & 0xFF; 144635c4bbdfSmrg 144705b261ecSmrg regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; 144835c4bbdfSmrg ExtBits = (mode->CrtcVBlankEnd - 1) & ExtBitMask; 144905b261ecSmrg 145035c4bbdfSmrg if ((Flags & KGA_FIX_OVERSCAN) 145135c4bbdfSmrg && (mode->CrtcVBlankEnd == mode->CrtcVTotal)) 145235c4bbdfSmrg /* Null top overscan */ 145305b261ecSmrg { 145435c4bbdfSmrg int i = regp->CRTC[22] | ExtBits; 145535c4bbdfSmrg 145635c4bbdfSmrg if (Flags & KGA_ENABLE_ON_ZERO) { 145735c4bbdfSmrg if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask))) 145835c4bbdfSmrg || ((i > VBlankStart) && /* 8-bit case */ 145935c4bbdfSmrg ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */ 146035c4bbdfSmrg !(regp->CRTC[9] & 0x9F)) /* 1 scanline/row */ 146135c4bbdfSmrg i = 0; 146235c4bbdfSmrg else 146335c4bbdfSmrg i = (i - 1); 146435c4bbdfSmrg } 146535c4bbdfSmrg else if (Flags & KGA_BE_TOT_DEC) 146635c4bbdfSmrg i = (i - 1); 146735c4bbdfSmrg 146835c4bbdfSmrg regp->CRTC[22] = i & 0xFF; 146935c4bbdfSmrg ExtBits = i & 0xFF00; 147005b261ecSmrg } 147105b261ecSmrg return ExtBits >> 8; 147205b261ecSmrg} 147305b261ecSmrg 147405b261ecSmrg/* 147505b261ecSmrg * these are some more hardware specific helpers, formerly in vga.c 147605b261ecSmrg */ 147705b261ecSmrgstatic void 147805b261ecSmrgvgaHWGetHWRecPrivate(void) 147905b261ecSmrg{ 148005b261ecSmrg if (vgaHWPrivateIndex < 0) 148135c4bbdfSmrg vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); 148205b261ecSmrg return; 148305b261ecSmrg} 148405b261ecSmrg 148505b261ecSmrgstatic void 148605b261ecSmrgvgaHWFreeRegs(vgaRegPtr regp) 148705b261ecSmrg{ 14886747b715Smrg free(regp->CRTC); 148905b261ecSmrg 149035c4bbdfSmrg regp->CRTC = regp->Sequencer = regp->Graphics = regp->Attribute = NULL; 149105b261ecSmrg 149205b261ecSmrg regp->numCRTC = 149335c4bbdfSmrg regp->numSequencer = regp->numGraphics = regp->numAttribute = 0; 149405b261ecSmrg} 149505b261ecSmrg 149605b261ecSmrgstatic Bool 149705b261ecSmrgvgaHWAllocRegs(vgaRegPtr regp) 149805b261ecSmrg{ 149905b261ecSmrg unsigned char *buf; 150005b261ecSmrg 150105b261ecSmrg if ((regp->numCRTC + regp->numSequencer + regp->numGraphics + 150205b261ecSmrg regp->numAttribute) == 0) 150305b261ecSmrg return FALSE; 150405b261ecSmrg 15056747b715Smrg buf = calloc(regp->numCRTC + 150635c4bbdfSmrg regp->numSequencer + 150735c4bbdfSmrg regp->numGraphics + regp->numAttribute, 1); 150805b261ecSmrg if (!buf) 150935c4bbdfSmrg return FALSE; 151005b261ecSmrg 151105b261ecSmrg regp->CRTC = buf; 151205b261ecSmrg regp->Sequencer = regp->CRTC + regp->numCRTC; 151305b261ecSmrg regp->Graphics = regp->Sequencer + regp->numSequencer; 151405b261ecSmrg regp->Attribute = regp->Graphics + regp->numGraphics; 151505b261ecSmrg 151605b261ecSmrg return TRUE; 151705b261ecSmrg} 151805b261ecSmrg 151905b261ecSmrgBool 152005b261ecSmrgvgaHWAllocDefaultRegs(vgaRegPtr regp) 152105b261ecSmrg{ 152205b261ecSmrg regp->numCRTC = VGA_NUM_CRTC; 152305b261ecSmrg regp->numSequencer = VGA_NUM_SEQ; 152405b261ecSmrg regp->numGraphics = VGA_NUM_GFX; 152505b261ecSmrg regp->numAttribute = VGA_NUM_ATTR; 152605b261ecSmrg 152705b261ecSmrg return vgaHWAllocRegs(regp); 152805b261ecSmrg} 152905b261ecSmrg 153005b261ecSmrgBool 153105b261ecSmrgvgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer, 153235c4bbdfSmrg int numGraphics, int numAttribute) 153305b261ecSmrg{ 153405b261ecSmrg#define VGAHWMINNUM(regtype) \ 153505b261ecSmrg ((newMode.num##regtype < regp->num##regtype) ? \ 153605b261ecSmrg (newMode.num##regtype) : (regp->num##regtype)) 153705b261ecSmrg#define VGAHWCOPYREGSET(regtype) \ 153805b261ecSmrg memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype)) 153905b261ecSmrg 154005b261ecSmrg vgaRegRec newMode, newSaved; 154105b261ecSmrg vgaRegPtr regp; 154205b261ecSmrg 154305b261ecSmrg regp = &VGAHWPTR(scrp)->ModeReg; 154435c4bbdfSmrg memcpy(&newMode, regp, sizeof(vgaRegRec)); 154505b261ecSmrg 154605b261ecSmrg /* allocate space for new registers */ 154705b261ecSmrg 154805b261ecSmrg regp = &newMode; 154905b261ecSmrg regp->numCRTC = numCRTC; 155005b261ecSmrg regp->numSequencer = numSequencer; 155105b261ecSmrg regp->numGraphics = numGraphics; 155205b261ecSmrg regp->numAttribute = numAttribute; 155305b261ecSmrg if (!vgaHWAllocRegs(regp)) 155435c4bbdfSmrg return FALSE; 155505b261ecSmrg 155605b261ecSmrg regp = &VGAHWPTR(scrp)->SavedReg; 155735c4bbdfSmrg memcpy(&newSaved, regp, sizeof(vgaRegRec)); 155805b261ecSmrg 155905b261ecSmrg regp = &newSaved; 156005b261ecSmrg regp->numCRTC = numCRTC; 156105b261ecSmrg regp->numSequencer = numSequencer; 156205b261ecSmrg regp->numGraphics = numGraphics; 156305b261ecSmrg regp->numAttribute = numAttribute; 156405b261ecSmrg if (!vgaHWAllocRegs(regp)) { 156505b261ecSmrg vgaHWFreeRegs(&newMode); 156635c4bbdfSmrg return FALSE; 156705b261ecSmrg } 156805b261ecSmrg 156905b261ecSmrg /* allocations succeeded, copy register data into new space */ 157005b261ecSmrg 157105b261ecSmrg regp = &VGAHWPTR(scrp)->ModeReg; 157205b261ecSmrg VGAHWCOPYREGSET(CRTC); 157305b261ecSmrg VGAHWCOPYREGSET(Sequencer); 157405b261ecSmrg VGAHWCOPYREGSET(Graphics); 157505b261ecSmrg VGAHWCOPYREGSET(Attribute); 157605b261ecSmrg 157705b261ecSmrg regp = &VGAHWPTR(scrp)->SavedReg; 157805b261ecSmrg VGAHWCOPYREGSET(CRTC); 157905b261ecSmrg VGAHWCOPYREGSET(Sequencer); 158005b261ecSmrg VGAHWCOPYREGSET(Graphics); 158105b261ecSmrg VGAHWCOPYREGSET(Attribute); 158205b261ecSmrg 158305b261ecSmrg /* free old register arrays */ 158405b261ecSmrg 158505b261ecSmrg regp = &VGAHWPTR(scrp)->ModeReg; 158605b261ecSmrg vgaHWFreeRegs(regp); 158705b261ecSmrg memcpy(regp, &newMode, sizeof(vgaRegRec)); 158805b261ecSmrg 158905b261ecSmrg regp = &VGAHWPTR(scrp)->SavedReg; 159005b261ecSmrg vgaHWFreeRegs(regp); 159105b261ecSmrg memcpy(regp, &newSaved, sizeof(vgaRegRec)); 159205b261ecSmrg 159305b261ecSmrg return TRUE; 159405b261ecSmrg 159505b261ecSmrg#undef VGAHWMINNUM 159605b261ecSmrg#undef VGAHWCOPYREGSET 159705b261ecSmrg} 159805b261ecSmrg 159905b261ecSmrgBool 160005b261ecSmrgvgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src) 160105b261ecSmrg{ 160205b261ecSmrg vgaHWFreeRegs(dst); 160305b261ecSmrg 160405b261ecSmrg memcpy(dst, src, sizeof(vgaRegRec)); 160505b261ecSmrg 160605b261ecSmrg if (!vgaHWAllocRegs(dst)) 160735c4bbdfSmrg return FALSE; 160805b261ecSmrg 160905b261ecSmrg memcpy(dst->CRTC, src->CRTC, src->numCRTC); 161005b261ecSmrg memcpy(dst->Sequencer, src->Sequencer, src->numSequencer); 161105b261ecSmrg memcpy(dst->Graphics, src->Graphics, src->numGraphics); 161205b261ecSmrg memcpy(dst->Attribute, src->Attribute, src->numAttribute); 161305b261ecSmrg 161405b261ecSmrg return TRUE; 161505b261ecSmrg} 161605b261ecSmrg 161705b261ecSmrgBool 161805b261ecSmrgvgaHWGetHWRec(ScrnInfoPtr scrp) 161905b261ecSmrg{ 162005b261ecSmrg vgaRegPtr regp; 162105b261ecSmrg vgaHWPtr hwp; 162205b261ecSmrg int i; 162335c4bbdfSmrg 162405b261ecSmrg /* 162505b261ecSmrg * Let's make sure that the private exists and allocate one. 162605b261ecSmrg */ 162705b261ecSmrg vgaHWGetHWRecPrivate(); 162805b261ecSmrg /* 162905b261ecSmrg * New privates are always set to NULL, so we can check if the allocation 163005b261ecSmrg * has already been done. 163105b261ecSmrg */ 163205b261ecSmrg if (VGAHWPTR(scrp)) 163335c4bbdfSmrg return TRUE; 163405b261ecSmrg hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1); 163505b261ecSmrg regp = &VGAHWPTR(scrp)->ModeReg; 163605b261ecSmrg 163705b261ecSmrg if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) || 163835c4bbdfSmrg (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) { 16396747b715Smrg free(hwp); 164035c4bbdfSmrg return FALSE; 164105b261ecSmrg } 164205b261ecSmrg 164305b261ecSmrg if (scrp->bitsPerPixel == 1) { 164435c4bbdfSmrg rgb blackColour = scrp->display->blackColour, 164535c4bbdfSmrg whiteColour = scrp->display->whiteColour; 164635c4bbdfSmrg 164735c4bbdfSmrg if (blackColour.red > 0x3F) 164835c4bbdfSmrg blackColour.red = 0x3F; 164935c4bbdfSmrg if (blackColour.green > 0x3F) 165035c4bbdfSmrg blackColour.green = 0x3F; 165135c4bbdfSmrg if (blackColour.blue > 0x3F) 165235c4bbdfSmrg blackColour.blue = 0x3F; 165335c4bbdfSmrg 165435c4bbdfSmrg if (whiteColour.red > 0x3F) 165535c4bbdfSmrg whiteColour.red = 0x3F; 165635c4bbdfSmrg if (whiteColour.green > 0x3F) 165735c4bbdfSmrg whiteColour.green = 0x3F; 165835c4bbdfSmrg if (whiteColour.blue > 0x3F) 165935c4bbdfSmrg whiteColour.blue = 0x3F; 166035c4bbdfSmrg 166135c4bbdfSmrg if ((blackColour.red == whiteColour.red) && 166235c4bbdfSmrg (blackColour.green == whiteColour.green) && 166335c4bbdfSmrg (blackColour.blue == whiteColour.blue)) { 166435c4bbdfSmrg blackColour.red ^= 0x3F; 166535c4bbdfSmrg blackColour.green ^= 0x3F; 166635c4bbdfSmrg blackColour.blue ^= 0x3F; 166735c4bbdfSmrg } 166805b261ecSmrg 166905b261ecSmrg /* 167005b261ecSmrg * initialize default colormap for monochrome 167105b261ecSmrg */ 167235c4bbdfSmrg for (i = 0; i < 3; i++) 167335c4bbdfSmrg regp->DAC[i] = 0x00; 167435c4bbdfSmrg for (i = 3; i < 768; i++) 167535c4bbdfSmrg regp->DAC[i] = 0x3F; 167605b261ecSmrg i = BLACK_VALUE * 3; 167705b261ecSmrg regp->DAC[i++] = blackColour.red; 167805b261ecSmrg regp->DAC[i++] = blackColour.green; 167905b261ecSmrg regp->DAC[i] = blackColour.blue; 168005b261ecSmrg i = WHITE_VALUE * 3; 168105b261ecSmrg regp->DAC[i++] = whiteColour.red; 168205b261ecSmrg regp->DAC[i++] = whiteColour.green; 168305b261ecSmrg regp->DAC[i] = whiteColour.blue; 168405b261ecSmrg i = OVERSCAN_VALUE * 3; 168505b261ecSmrg regp->DAC[i++] = 0x00; 168605b261ecSmrg regp->DAC[i++] = 0x00; 168705b261ecSmrg regp->DAC[i] = 0x00; 168835c4bbdfSmrg } 168935c4bbdfSmrg else { 169035c4bbdfSmrg /* Set all colours to black */ 169135c4bbdfSmrg for (i = 0; i < 768; i++) 169235c4bbdfSmrg regp->DAC[i] = 0x00; 169305b261ecSmrg /* ... and the overscan */ 169405b261ecSmrg if (scrp->depth >= 4) 169505b261ecSmrg regp->Attribute[OVERSCAN] = 0xFF; 169605b261ecSmrg } 169705b261ecSmrg if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) { 169835c4bbdfSmrg xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan"); 169935c4bbdfSmrg xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n"); 170035c4bbdfSmrg regp->DAC[765] = 0x3F; 170135c4bbdfSmrg regp->DAC[766] = 0x00; 170235c4bbdfSmrg regp->DAC[767] = 0x3F; 170335c4bbdfSmrg regp->Attribute[OVERSCAN] = 0xFF; 170435c4bbdfSmrg hwp->ShowOverscan = TRUE; 170535c4bbdfSmrg } 170635c4bbdfSmrg else 170735c4bbdfSmrg hwp->ShowOverscan = FALSE; 170805b261ecSmrg 170905b261ecSmrg hwp->paletteEnabled = FALSE; 171005b261ecSmrg hwp->cmapSaved = FALSE; 171105b261ecSmrg hwp->MapSize = 0; 171205b261ecSmrg hwp->pScrn = scrp; 171305b261ecSmrg 17144642e01fSmrg hwp->dev = xf86GetPciInfoForEntity(scrp->entityList[0]); 171505b261ecSmrg 171605b261ecSmrg return TRUE; 171705b261ecSmrg} 171805b261ecSmrg 171905b261ecSmrgvoid 172005b261ecSmrgvgaHWFreeHWRec(ScrnInfoPtr scrp) 172105b261ecSmrg{ 172205b261ecSmrg if (vgaHWPrivateIndex >= 0) { 172335c4bbdfSmrg vgaHWPtr hwp = VGAHWPTR(scrp); 172435c4bbdfSmrg 172535c4bbdfSmrg if (!hwp) 172635c4bbdfSmrg return; 172705b261ecSmrg 172835c4bbdfSmrg pci_device_close_io(hwp->dev, hwp->io); 172905b261ecSmrg 173035c4bbdfSmrg free(hwp->FontInfo1); 173135c4bbdfSmrg free(hwp->FontInfo2); 173235c4bbdfSmrg free(hwp->TextInfo); 173305b261ecSmrg 173435c4bbdfSmrg vgaHWFreeRegs(&hwp->ModeReg); 173535c4bbdfSmrg vgaHWFreeRegs(&hwp->SavedReg); 173605b261ecSmrg 173735c4bbdfSmrg free(hwp); 173835c4bbdfSmrg VGAHWPTRLVAL(scrp) = NULL; 173905b261ecSmrg } 174005b261ecSmrg} 174105b261ecSmrg 174205b261ecSmrgBool 174305b261ecSmrgvgaHWMapMem(ScrnInfoPtr scrp) 174405b261ecSmrg{ 174505b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrp); 174635c4bbdfSmrg 174705b261ecSmrg if (hwp->Base) 174835c4bbdfSmrg return TRUE; 174905b261ecSmrg 175005b261ecSmrg /* If not set, initialise with the defaults */ 175105b261ecSmrg if (hwp->MapSize == 0) 175235c4bbdfSmrg hwp->MapSize = VGA_DEFAULT_MEM_SIZE; 175305b261ecSmrg if (hwp->MapPhys == 0) 175435c4bbdfSmrg hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR; 175505b261ecSmrg 175605b261ecSmrg /* 175705b261ecSmrg * Map as VIDMEM_MMIO_32BIT because WC 175805b261ecSmrg * is bad when there is page flipping. 175905b261ecSmrg * XXX This is not correct but we do it 176005b261ecSmrg * for now. 176105b261ecSmrg */ 17626747b715Smrg DebugF("Mapping VGAMem\n"); 176335c4bbdfSmrg pci_device_map_legacy(hwp->dev, hwp->MapPhys, hwp->MapSize, 176435c4bbdfSmrg PCI_DEV_MAP_FLAG_WRITABLE, &hwp->Base); 176505b261ecSmrg return hwp->Base != NULL; 176605b261ecSmrg} 176705b261ecSmrg 176805b261ecSmrgvoid 176905b261ecSmrgvgaHWUnmapMem(ScrnInfoPtr scrp) 177005b261ecSmrg{ 177105b261ecSmrg vgaHWPtr hwp = VGAHWPTR(scrp); 177205b261ecSmrg 177305b261ecSmrg if (hwp->Base == NULL) 177435c4bbdfSmrg return; 177535c4bbdfSmrg 17766747b715Smrg DebugF("Unmapping VGAMem\n"); 177735c4bbdfSmrg pci_device_unmap_legacy(hwp->dev, hwp->Base, hwp->MapSize); 177805b261ecSmrg hwp->Base = NULL; 177905b261ecSmrg} 178005b261ecSmrg 178105b261ecSmrgint 17826747b715SmrgvgaHWGetIndex(void) 178305b261ecSmrg{ 178405b261ecSmrg return vgaHWPrivateIndex; 178505b261ecSmrg} 178605b261ecSmrg 178705b261ecSmrgvoid 178805b261ecSmrgvgaHWGetIOBase(vgaHWPtr hwp) 178905b261ecSmrg{ 179005b261ecSmrg hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ? 179135c4bbdfSmrg VGA_IOBASE_COLOR : VGA_IOBASE_MONO; 179205b261ecSmrg xf86DrvMsgVerb(hwp->pScrn->scrnIndex, X_INFO, 3, 179335c4bbdfSmrg "vgaHWGetIOBase: hwp->IOBase is 0x%04x\n", hwp->IOBase); 179405b261ecSmrg} 179505b261ecSmrg 179605b261ecSmrgvoid 179705b261ecSmrgvgaHWLock(vgaHWPtr hwp) 179805b261ecSmrg{ 179905b261ecSmrg /* Protect CRTC[0-7] */ 180005b261ecSmrg hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80); 180105b261ecSmrg} 180205b261ecSmrg 180305b261ecSmrgvoid 180405b261ecSmrgvgaHWUnlock(vgaHWPtr hwp) 180505b261ecSmrg{ 180605b261ecSmrg /* Unprotect CRTC[0-7] */ 180735c4bbdfSmrg hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80); 180805b261ecSmrg} 180905b261ecSmrg 181005b261ecSmrgvoid 181105b261ecSmrgvgaHWEnable(vgaHWPtr hwp) 181205b261ecSmrg{ 181305b261ecSmrg hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01); 181405b261ecSmrg} 181505b261ecSmrg 181605b261ecSmrgvoid 181705b261ecSmrgvgaHWDisable(vgaHWPtr hwp) 181805b261ecSmrg{ 181905b261ecSmrg hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01); 182005b261ecSmrg} 182105b261ecSmrg 182205b261ecSmrgstatic void 182335c4bbdfSmrgvgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO * colors, 182435c4bbdfSmrg VisualPtr pVisual) 182505b261ecSmrg{ 182605b261ecSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 182705b261ecSmrg int i, index; 182805b261ecSmrg 182905b261ecSmrg for (i = 0; i < numColors; i++) { 183035c4bbdfSmrg index = indices[i]; 183135c4bbdfSmrg hwp->writeDacWriteAddr(hwp, index); 183235c4bbdfSmrg DACDelay(hwp); 183335c4bbdfSmrg hwp->writeDacData(hwp, colors[index].red); 183435c4bbdfSmrg DACDelay(hwp); 183535c4bbdfSmrg hwp->writeDacData(hwp, colors[index].green); 183635c4bbdfSmrg DACDelay(hwp); 183735c4bbdfSmrg hwp->writeDacData(hwp, colors[index].blue); 183835c4bbdfSmrg DACDelay(hwp); 183905b261ecSmrg } 184005b261ecSmrg 184105b261ecSmrg /* This shouldn't be necessary, but we'll play safe. */ 184205b261ecSmrg hwp->disablePalette(hwp); 184305b261ecSmrg} 184405b261ecSmrg 184505b261ecSmrgstatic void 184605b261ecSmrgvgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan) 184705b261ecSmrg{ 184805b261ecSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 184905b261ecSmrg 185005b261ecSmrg if (overscan < 0 || overscan > 255) 185135c4bbdfSmrg return; 185205b261ecSmrg 185305b261ecSmrg hwp->enablePalette(hwp); 185405b261ecSmrg hwp->writeAttr(hwp, OVERSCAN, overscan); 185505b261ecSmrg 185605b261ecSmrg#ifdef DEBUGOVERSCAN 185705b261ecSmrg { 185835c4bbdfSmrg int ov = hwp->readAttr(hwp, OVERSCAN); 185935c4bbdfSmrg int red, green, blue; 186035c4bbdfSmrg 186135c4bbdfSmrg hwp->writeDacReadAddr(hwp, ov); 186235c4bbdfSmrg red = hwp->readDacData(hwp); 186335c4bbdfSmrg green = hwp->readDacData(hwp); 186435c4bbdfSmrg blue = hwp->readDacData(hwp); 186535c4bbdfSmrg ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n", 186635c4bbdfSmrg ov, red, green, blue); 186705b261ecSmrg } 186805b261ecSmrg#endif 186905b261ecSmrg 187005b261ecSmrg hwp->disablePalette(hwp); 187105b261ecSmrg} 187205b261ecSmrg 187305b261ecSmrgBool 187405b261ecSmrgvgaHWHandleColormaps(ScreenPtr pScreen) 187505b261ecSmrg{ 187635c4bbdfSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 187705b261ecSmrg 187805b261ecSmrg if (pScrn->depth > 1 && pScrn->depth <= 8) { 187935c4bbdfSmrg return xf86HandleColormaps(pScreen, 1 << pScrn->depth, 188035c4bbdfSmrg pScrn->rgbBits, vgaHWLoadPalette, 188135c4bbdfSmrg pScrn->depth > 4 ? vgaHWSetOverscan : NULL, 188235c4bbdfSmrg CMAP_RELOAD_ON_MODE_SWITCH); 188305b261ecSmrg } 188405b261ecSmrg return TRUE; 188505b261ecSmrg} 188605b261ecSmrg 188705b261ecSmrg/* ----------------------- DDC support ------------------------*/ 188835c4bbdfSmrg/* 188905b261ecSmrg * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total 189005b261ecSmrg * to read out EDID at a faster rate. Allowed maximum is 25kHz with 189105b261ecSmrg * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen 189205b261ecSmrg * readback, enable access to cr00-cr07. 189305b261ecSmrg */ 189405b261ecSmrg 189505b261ecSmrg/* vertical timings */ 189605b261ecSmrg#define DISPLAY_END 0x04 189705b261ecSmrg#define BLANK_START DISPLAY_END 189805b261ecSmrg#define SYNC_START BLANK_START 189905b261ecSmrg#define SYNC_END 0x09 190005b261ecSmrg#define BLANK_END SYNC_END 190105b261ecSmrg#define V_TOTAL BLANK_END 190205b261ecSmrg/* this function doesn't have to be reentrant for our purposes */ 190305b261ecSmrgstruct _vgaDdcSave { 190405b261ecSmrg unsigned char cr03; 190505b261ecSmrg unsigned char cr06; 190605b261ecSmrg unsigned char cr07; 190705b261ecSmrg unsigned char cr09; 190805b261ecSmrg unsigned char cr10; 190905b261ecSmrg unsigned char cr11; 191005b261ecSmrg unsigned char cr12; 191105b261ecSmrg unsigned char cr15; 191205b261ecSmrg unsigned char cr16; 191305b261ecSmrg unsigned char msr; 191405b261ecSmrg}; 191505b261ecSmrg 191605b261ecSmrgvoid 191705b261ecSmrgvgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed) 191805b261ecSmrg{ 191905b261ecSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 192005b261ecSmrg unsigned char tmp; 192135c4bbdfSmrg struct _vgaDdcSave *save; 192235c4bbdfSmrg 192305b261ecSmrg switch (speed) { 192405b261ecSmrg case DDC_FAST: 192535c4bbdfSmrg 192635c4bbdfSmrg if (hwp->ddc != NULL) 192735c4bbdfSmrg break; 192835c4bbdfSmrg hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave), 1); 192935c4bbdfSmrg save = (struct _vgaDdcSave *) hwp->ddc; 193035c4bbdfSmrg /* Lightpen register disable - allow access to cr10 & 11; just in case */ 193135c4bbdfSmrg save->cr03 = hwp->readCrtc(hwp, 0x03); 193235c4bbdfSmrg hwp->writeCrtc(hwp, 0x03, (save->cr03 | 0x80)); 193335c4bbdfSmrg save->cr12 = hwp->readCrtc(hwp, 0x12); 193435c4bbdfSmrg hwp->writeCrtc(hwp, 0x12, DISPLAY_END); 193535c4bbdfSmrg save->cr15 = hwp->readCrtc(hwp, 0x15); 193635c4bbdfSmrg hwp->writeCrtc(hwp, 0x15, BLANK_START); 193735c4bbdfSmrg save->cr10 = hwp->readCrtc(hwp, 0x10); 193835c4bbdfSmrg hwp->writeCrtc(hwp, 0x10, SYNC_START); 193935c4bbdfSmrg save->cr11 = hwp->readCrtc(hwp, 0x11); 194035c4bbdfSmrg /* unprotect group 1 registers; just in case ... */ 194135c4bbdfSmrg hwp->writeCrtc(hwp, 0x11, ((save->cr11 & 0x70) | SYNC_END)); 194235c4bbdfSmrg save->cr16 = hwp->readCrtc(hwp, 0x16); 194335c4bbdfSmrg hwp->writeCrtc(hwp, 0x16, BLANK_END); 194435c4bbdfSmrg save->cr06 = hwp->readCrtc(hwp, 0x06); 194535c4bbdfSmrg hwp->writeCrtc(hwp, 0x06, V_TOTAL); 194635c4bbdfSmrg /* all values have less than 8 bit - mask out 9th and 10th bits */ 194735c4bbdfSmrg save->cr09 = hwp->readCrtc(hwp, 0x09); 194835c4bbdfSmrg hwp->writeCrtc(hwp, 0x09, (save->cr09 & 0xDF)); 194935c4bbdfSmrg save->cr07 = hwp->readCrtc(hwp, 0x07); 195035c4bbdfSmrg hwp->writeCrtc(hwp, 0x07, (save->cr07 & 0x10)); 1951ed6184dfSmrg /* vsync polarity negative & ensure a 25MHz clock */ 195235c4bbdfSmrg save->msr = hwp->readMiscOut(hwp); 195335c4bbdfSmrg hwp->writeMiscOut(hwp, ((save->msr & 0xF3) | 0x80)); 195435c4bbdfSmrg break; 195505b261ecSmrg case DDC_SLOW: 195635c4bbdfSmrg if (hwp->ddc == NULL) 195735c4bbdfSmrg break; 195835c4bbdfSmrg save = (struct _vgaDdcSave *) hwp->ddc; 195935c4bbdfSmrg hwp->writeMiscOut(hwp, save->msr); 196035c4bbdfSmrg hwp->writeCrtc(hwp, 0x07, save->cr07); 196135c4bbdfSmrg tmp = hwp->readCrtc(hwp, 0x09); 196235c4bbdfSmrg hwp->writeCrtc(hwp, 0x09, ((save->cr09 & 0x20) | (tmp & 0xDF))); 196335c4bbdfSmrg hwp->writeCrtc(hwp, 0x06, save->cr06); 196435c4bbdfSmrg hwp->writeCrtc(hwp, 0x16, save->cr16); 196535c4bbdfSmrg hwp->writeCrtc(hwp, 0x11, save->cr11); 196635c4bbdfSmrg hwp->writeCrtc(hwp, 0x10, save->cr10); 196735c4bbdfSmrg hwp->writeCrtc(hwp, 0x15, save->cr15); 196835c4bbdfSmrg hwp->writeCrtc(hwp, 0x12, save->cr12); 196935c4bbdfSmrg hwp->writeCrtc(hwp, 0x03, save->cr03); 197035c4bbdfSmrg free(save); 197135c4bbdfSmrg hwp->ddc = NULL; 197235c4bbdfSmrg break; 197305b261ecSmrg default: 197435c4bbdfSmrg break; 197505b261ecSmrg } 197605b261ecSmrg} 197705b261ecSmrg 19786747b715SmrgDDC1SetSpeedProc 19796747b715SmrgvgaHWddc1SetSpeedWeak(void) 19806747b715Smrg{ 19816747b715Smrg return vgaHWddc1SetSpeed; 19826747b715Smrg} 198305b261ecSmrg 198435c4bbdfSmrgSaveScreenProcPtr 198535c4bbdfSmrgvgaHWSaveScreenWeak(void) 19866747b715Smrg{ 19876747b715Smrg return vgaHWSaveScreen; 19886747b715Smrg} 198935c4bbdfSmrg 199035c4bbdfSmrg/* 199135c4bbdfSmrg * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ... 199235c4bbdfSmrg */ 199335c4bbdfSmrgvoid 199435c4bbdfSmrgxf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc) (ScrnInfoPtr, int), 199535c4bbdfSmrg void (*ProtectRegs) (ScrnInfoPtr, Bool), 199635c4bbdfSmrg void (*BlankScreen) (ScrnInfoPtr, Bool), 199735c4bbdfSmrg unsigned long vertsyncreg, int maskval, int knownclkindex, 199835c4bbdfSmrg int knownclkvalue) 199935c4bbdfSmrg{ 200035c4bbdfSmrg register int status = vertsyncreg; 200135c4bbdfSmrg unsigned long i, cnt, rcnt, sync; 200235c4bbdfSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 200335c4bbdfSmrg 200435c4bbdfSmrg /* First save registers that get written on */ 200535c4bbdfSmrg (*ClockFunc) (pScrn, CLK_REG_SAVE); 200635c4bbdfSmrg 200735c4bbdfSmrg if (num > MAXCLOCKS) 200835c4bbdfSmrg num = MAXCLOCKS; 200935c4bbdfSmrg 201035c4bbdfSmrg for (i = 0; i < num; i++) { 201135c4bbdfSmrg if (ProtectRegs) 201235c4bbdfSmrg (*ProtectRegs) (pScrn, TRUE); 201335c4bbdfSmrg if (!(*ClockFunc) (pScrn, i)) { 201435c4bbdfSmrg pScrn->clock[i] = -1; 201535c4bbdfSmrg continue; 201635c4bbdfSmrg } 201735c4bbdfSmrg if (ProtectRegs) 201835c4bbdfSmrg (*ProtectRegs) (pScrn, FALSE); 201935c4bbdfSmrg if (BlankScreen) 202035c4bbdfSmrg (*BlankScreen) (pScrn, FALSE); 202135c4bbdfSmrg 202235c4bbdfSmrg usleep(50000); /* let VCO stabilise */ 202335c4bbdfSmrg 202435c4bbdfSmrg cnt = 0; 202535c4bbdfSmrg sync = 200000; 202635c4bbdfSmrg 202735c4bbdfSmrg while ((pci_io_read8(hwp->io, status) & maskval) == 0x00) 202835c4bbdfSmrg if (sync-- == 0) 202935c4bbdfSmrg goto finish; 203035c4bbdfSmrg /* Something appears to be happening, so reset sync count */ 203135c4bbdfSmrg sync = 200000; 203235c4bbdfSmrg while ((pci_io_read8(hwp->io, status) & maskval) == maskval) 203335c4bbdfSmrg if (sync-- == 0) 203435c4bbdfSmrg goto finish; 203535c4bbdfSmrg /* Something appears to be happening, so reset sync count */ 203635c4bbdfSmrg sync = 200000; 203735c4bbdfSmrg while ((pci_io_read8(hwp->io, status) & maskval) == 0x00) 203835c4bbdfSmrg if (sync-- == 0) 203935c4bbdfSmrg goto finish; 204035c4bbdfSmrg 204135c4bbdfSmrg for (rcnt = 0; rcnt < 5; rcnt++) { 204235c4bbdfSmrg while (!(pci_io_read8(hwp->io, status) & maskval)) 204335c4bbdfSmrg cnt++; 204435c4bbdfSmrg while ((pci_io_read8(hwp->io, status) & maskval)) 204535c4bbdfSmrg cnt++; 204635c4bbdfSmrg } 204735c4bbdfSmrg 204835c4bbdfSmrg finish: 204935c4bbdfSmrg pScrn->clock[i] = cnt ? cnt : -1; 205035c4bbdfSmrg if (BlankScreen) 205135c4bbdfSmrg (*BlankScreen) (pScrn, TRUE); 205235c4bbdfSmrg } 205335c4bbdfSmrg 205435c4bbdfSmrg for (i = 0; i < num; i++) { 205535c4bbdfSmrg if (i != knownclkindex) { 205635c4bbdfSmrg if (pScrn->clock[i] == -1) { 205735c4bbdfSmrg pScrn->clock[i] = 0; 205835c4bbdfSmrg } 205935c4bbdfSmrg else { 206035c4bbdfSmrg pScrn->clock[i] = (int) (0.5 + 206135c4bbdfSmrg (((float) knownclkvalue) * 206235c4bbdfSmrg pScrn->clock[knownclkindex]) / 206335c4bbdfSmrg (pScrn->clock[i])); 206435c4bbdfSmrg /* Round to nearest 10KHz */ 206535c4bbdfSmrg pScrn->clock[i] += 5; 206635c4bbdfSmrg pScrn->clock[i] /= 10; 206735c4bbdfSmrg pScrn->clock[i] *= 10; 206835c4bbdfSmrg } 206935c4bbdfSmrg } 207035c4bbdfSmrg } 207135c4bbdfSmrg 207235c4bbdfSmrg pScrn->clock[knownclkindex] = knownclkvalue; 207335c4bbdfSmrg pScrn->numClocks = num; 207435c4bbdfSmrg 207535c4bbdfSmrg /* Restore registers that were written on */ 207635c4bbdfSmrg (*ClockFunc) (pScrn, CLK_REG_RESTORE); 207735c4bbdfSmrg} 2078