1706f2543Smrg 2706f2543Smrg/* 3706f2543Smrg * 4706f2543Smrg * Copyright 1991-1999 by The XFree86 Project, Inc. 5706f2543Smrg * 6706f2543Smrg * Loosely based on code bearing the following copyright: 7706f2543Smrg * 8706f2543Smrg * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 9706f2543Smrg * 10706f2543Smrg */ 11706f2543Smrg 12706f2543Smrg#define _NEED_SYSI86 13706f2543Smrg 14706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 15706f2543Smrg#include <xorg-config.h> 16706f2543Smrg#endif 17706f2543Smrg 18706f2543Smrg#include <stdlib.h> 19706f2543Smrg#include <string.h> 20706f2543Smrg#include <unistd.h> 21706f2543Smrg 22706f2543Smrg#include <X11/X.h> 23706f2543Smrg#include "misc.h" 24706f2543Smrg 25706f2543Smrg#include "xf86.h" 26706f2543Smrg#include "xf86_OSproc.h" 27706f2543Smrg#include "vgaHW.h" 28706f2543Smrg 29706f2543Smrg#include "compiler.h" 30706f2543Smrg 31706f2543Smrg#include "xf86cmap.h" 32706f2543Smrg 33706f2543Smrg#include "Pci.h" 34706f2543Smrg 35706f2543Smrg#ifndef SAVE_FONT1 36706f2543Smrg#define SAVE_FONT1 1 37706f2543Smrg#endif 38706f2543Smrg 39706f2543Smrg/* 40706f2543Smrg * These used to be OS-specific, which made this module have an undesirable 41706f2543Smrg * OS dependency. Define them by default for all platforms. 42706f2543Smrg */ 43706f2543Smrg#ifndef NEED_SAVED_CMAP 44706f2543Smrg#define NEED_SAVED_CMAP 45706f2543Smrg#endif 46706f2543Smrg#ifndef SAVE_TEXT 47706f2543Smrg#define SAVE_TEXT 1 48706f2543Smrg#endif 49706f2543Smrg#ifndef SAVE_FONT2 50706f2543Smrg#define SAVE_FONT2 1 51706f2543Smrg#endif 52706f2543Smrg 53706f2543Smrg/* bytes per plane to save for text */ 54706f2543Smrg#define TEXT_AMOUNT 16384 55706f2543Smrg 56706f2543Smrg/* bytes per plane to save for font data */ 57706f2543Smrg#define FONT_AMOUNT (8*8192) 58706f2543Smrg 59706f2543Smrg#if 0 60706f2543Smrg/* Override all of these for now */ 61706f2543Smrg#undef SAVE_FONT1 62706f2543Smrg#define SAVE_FONT1 1 63706f2543Smrg#undef SAVE_FONT2 64706f2543Smrg#define SAVE_FONT2 1 65706f2543Smrg#undef SAVE_TEST 66706f2543Smrg#define SAVE_TEST 1 67706f2543Smrg#undef FONT_AMOUNT 68706f2543Smrg#define FONT_AMOUNT 65536 69706f2543Smrg#undef TEXT_AMOUNT 70706f2543Smrg#define TEXT_AMOUNT 65536 71706f2543Smrg#endif 72706f2543Smrg 73706f2543Smrg/* DAC indices for white and black */ 74706f2543Smrg#define WHITE_VALUE 0x3F 75706f2543Smrg#define BLACK_VALUE 0x00 76706f2543Smrg#define OVERSCAN_VALUE 0x01 77706f2543Smrg 78706f2543Smrg 79706f2543Smrg/* Use a private definition of this here */ 80706f2543Smrg#undef VGAHWPTR 81706f2543Smrg#define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr 82706f2543Smrg#define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p))) 83706f2543Smrg 84706f2543Smrgstatic int vgaHWPrivateIndex = -1; 85706f2543Smrg 86706f2543Smrg#define DAC_TEST_MASK 0x3F 87706f2543Smrg 88706f2543Smrg#ifdef NEED_SAVED_CMAP 89706f2543Smrg/* This default colourmap is used only when it can't be read from the VGA */ 90706f2543Smrg 91706f2543Smrgstatic CARD8 defaultDAC[768] = 92706f2543Smrg{ 93706f2543Smrg 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42, 94706f2543Smrg 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42, 95706f2543Smrg 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63, 96706f2543Smrg 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63, 97706f2543Smrg 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11, 98706f2543Smrg 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24, 99706f2543Smrg 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40, 100706f2543Smrg 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63, 101706f2543Smrg 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63, 102706f2543Smrg 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 103706f2543Smrg 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 104706f2543Smrg 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0, 105706f2543Smrg 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 106706f2543Smrg 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 107706f2543Smrg 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63, 108706f2543Smrg 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 109706f2543Smrg 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 110706f2543Smrg 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31, 111706f2543Smrg 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 112706f2543Smrg 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 113706f2543Smrg 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63, 114706f2543Smrg 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 115706f2543Smrg 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 116706f2543Smrg 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45, 117706f2543Smrg 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 118706f2543Smrg 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 119706f2543Smrg 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28, 120706f2543Smrg 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 121706f2543Smrg 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 122706f2543Smrg 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0, 123706f2543Smrg 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 124706f2543Smrg 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 125706f2543Smrg 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28, 126706f2543Smrg 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 127706f2543Smrg 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 128706f2543Smrg 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14, 129706f2543Smrg 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 130706f2543Smrg 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 131706f2543Smrg 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28, 132706f2543Smrg 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 133706f2543Smrg 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 134706f2543Smrg 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20, 135706f2543Smrg 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 136706f2543Smrg 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 137706f2543Smrg 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16, 138706f2543Smrg 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 139706f2543Smrg 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 140706f2543Smrg 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0, 141706f2543Smrg 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 142706f2543Smrg 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 143706f2543Smrg 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16, 144706f2543Smrg 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 145706f2543Smrg 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 146706f2543Smrg 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8, 147706f2543Smrg 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 148706f2543Smrg 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 149706f2543Smrg 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16, 150706f2543Smrg 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 151706f2543Smrg 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 152706f2543Smrg 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11, 153706f2543Smrg 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 154706f2543Smrg 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 155706f2543Smrg 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156706f2543Smrg 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157706f2543Smrg}; 158706f2543Smrg#endif /* NEED_SAVED_CMAP */ 159706f2543Smrg 160706f2543Smrg/* 161706f2543Smrg * Standard VGA versions of the register access functions. 162706f2543Smrg */ 163706f2543Smrgstatic void 164706f2543SmrgstdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 165706f2543Smrg{ 166706f2543Smrg outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index); 167706f2543Smrg outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET, value); 168706f2543Smrg} 169706f2543Smrg 170706f2543Smrgstatic CARD8 171706f2543SmrgstdReadCrtc(vgaHWPtr hwp, CARD8 index) 172706f2543Smrg{ 173706f2543Smrg outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index); 174706f2543Smrg return inb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET); 175706f2543Smrg} 176706f2543Smrg 177706f2543Smrgstatic void 178706f2543SmrgstdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value) 179706f2543Smrg{ 180706f2543Smrg outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index); 181706f2543Smrg outb(hwp->PIOOffset + VGA_GRAPH_DATA, value); 182706f2543Smrg} 183706f2543Smrg 184706f2543Smrgstatic CARD8 185706f2543SmrgstdReadGr(vgaHWPtr hwp, CARD8 index) 186706f2543Smrg{ 187706f2543Smrg outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index); 188706f2543Smrg return inb(hwp->PIOOffset + VGA_GRAPH_DATA); 189706f2543Smrg} 190706f2543Smrg 191706f2543Smrgstatic void 192706f2543SmrgstdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value) 193706f2543Smrg{ 194706f2543Smrg outb(hwp->PIOOffset + VGA_SEQ_INDEX, index); 195706f2543Smrg outb(hwp->PIOOffset + VGA_SEQ_DATA, value); 196706f2543Smrg} 197706f2543Smrg 198706f2543Smrgstatic CARD8 199706f2543SmrgstdReadSeq(vgaHWPtr hwp, CARD8 index) 200706f2543Smrg{ 201706f2543Smrg outb(hwp->PIOOffset + VGA_SEQ_INDEX, index); 202706f2543Smrg return inb(hwp->PIOOffset + VGA_SEQ_DATA); 203706f2543Smrg} 204706f2543Smrg 205706f2543Smrgstatic CARD8 206706f2543SmrgstdReadST00(vgaHWPtr hwp) 207706f2543Smrg{ 208706f2543Smrg return inb(hwp->PIOOffset + VGA_IN_STAT_0); 209706f2543Smrg} 210706f2543Smrg 211706f2543Smrgstatic CARD8 212706f2543SmrgstdReadST01(vgaHWPtr hwp) 213706f2543Smrg{ 214706f2543Smrg return inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 215706f2543Smrg} 216706f2543Smrg 217706f2543Smrgstatic CARD8 218706f2543SmrgstdReadFCR(vgaHWPtr hwp) 219706f2543Smrg{ 220706f2543Smrg return inb(hwp->PIOOffset + VGA_FEATURE_R); 221706f2543Smrg} 222706f2543Smrg 223706f2543Smrgstatic void 224706f2543SmrgstdWriteFCR(vgaHWPtr hwp, CARD8 value) 225706f2543Smrg{ 226706f2543Smrg outb(hwp->IOBase + hwp->PIOOffset + VGA_FEATURE_W_OFFSET,value); 227706f2543Smrg} 228706f2543Smrg 229706f2543Smrgstatic void 230706f2543SmrgstdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value) 231706f2543Smrg{ 232706f2543Smrg if (hwp->paletteEnabled) 233706f2543Smrg index &= ~0x20; 234706f2543Smrg else 235706f2543Smrg index |= 0x20; 236706f2543Smrg 237706f2543Smrg (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 238706f2543Smrg outb(hwp->PIOOffset + VGA_ATTR_INDEX, index); 239706f2543Smrg outb(hwp->PIOOffset + VGA_ATTR_DATA_W, value); 240706f2543Smrg} 241706f2543Smrg 242706f2543Smrgstatic CARD8 243706f2543SmrgstdReadAttr(vgaHWPtr hwp, CARD8 index) 244706f2543Smrg{ 245706f2543Smrg if (hwp->paletteEnabled) 246706f2543Smrg index &= ~0x20; 247706f2543Smrg else 248706f2543Smrg index |= 0x20; 249706f2543Smrg 250706f2543Smrg (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 251706f2543Smrg outb(hwp->PIOOffset + VGA_ATTR_INDEX, index); 252706f2543Smrg return inb(hwp->PIOOffset + VGA_ATTR_DATA_R); 253706f2543Smrg} 254706f2543Smrg 255706f2543Smrgstatic void 256706f2543SmrgstdWriteMiscOut(vgaHWPtr hwp, CARD8 value) 257706f2543Smrg{ 258706f2543Smrg outb(hwp->PIOOffset + VGA_MISC_OUT_W, value); 259706f2543Smrg} 260706f2543Smrg 261706f2543Smrgstatic CARD8 262706f2543SmrgstdReadMiscOut(vgaHWPtr hwp) 263706f2543Smrg{ 264706f2543Smrg return inb(hwp->PIOOffset + VGA_MISC_OUT_R); 265706f2543Smrg} 266706f2543Smrg 267706f2543Smrgstatic void 268706f2543SmrgstdEnablePalette(vgaHWPtr hwp) 269706f2543Smrg{ 270706f2543Smrg (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 271706f2543Smrg outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x00); 272706f2543Smrg hwp->paletteEnabled = TRUE; 273706f2543Smrg} 274706f2543Smrg 275706f2543Smrgstatic void 276706f2543SmrgstdDisablePalette(vgaHWPtr hwp) 277706f2543Smrg{ 278706f2543Smrg (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET); 279706f2543Smrg outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x20); 280706f2543Smrg hwp->paletteEnabled = FALSE; 281706f2543Smrg} 282706f2543Smrg 283706f2543Smrgstatic void 284706f2543SmrgstdWriteDacMask(vgaHWPtr hwp, CARD8 value) 285706f2543Smrg{ 286706f2543Smrg outb(hwp->PIOOffset + VGA_DAC_MASK, value); 287706f2543Smrg} 288706f2543Smrg 289706f2543Smrgstatic CARD8 290706f2543SmrgstdReadDacMask(vgaHWPtr hwp) 291706f2543Smrg{ 292706f2543Smrg return inb(hwp->PIOOffset + VGA_DAC_MASK); 293706f2543Smrg} 294706f2543Smrg 295706f2543Smrgstatic void 296706f2543SmrgstdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value) 297706f2543Smrg{ 298706f2543Smrg outb(hwp->PIOOffset + VGA_DAC_READ_ADDR, value); 299706f2543Smrg} 300706f2543Smrg 301706f2543Smrgstatic void 302706f2543SmrgstdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value) 303706f2543Smrg{ 304706f2543Smrg outb(hwp->PIOOffset + VGA_DAC_WRITE_ADDR, value); 305706f2543Smrg} 306706f2543Smrg 307706f2543Smrgstatic void 308706f2543SmrgstdWriteDacData(vgaHWPtr hwp, CARD8 value) 309706f2543Smrg{ 310706f2543Smrg outb(hwp->PIOOffset + VGA_DAC_DATA, value); 311706f2543Smrg} 312706f2543Smrg 313706f2543Smrgstatic CARD8 314706f2543SmrgstdReadDacData(vgaHWPtr hwp) 315706f2543Smrg{ 316706f2543Smrg return inb(hwp->PIOOffset + VGA_DAC_DATA); 317706f2543Smrg} 318706f2543Smrg 319706f2543Smrgstatic CARD8 320706f2543SmrgstdReadEnable(vgaHWPtr hwp) 321706f2543Smrg{ 322706f2543Smrg return inb(hwp->PIOOffset + VGA_ENABLE); 323706f2543Smrg} 324706f2543Smrg 325706f2543Smrgstatic void 326706f2543SmrgstdWriteEnable(vgaHWPtr hwp, CARD8 value) 327706f2543Smrg{ 328706f2543Smrg outb(hwp->PIOOffset + VGA_ENABLE, value); 329706f2543Smrg} 330706f2543Smrg 331706f2543Smrgvoid 332706f2543SmrgvgaHWSetStdFuncs(vgaHWPtr hwp) 333706f2543Smrg{ 334706f2543Smrg hwp->writeCrtc = stdWriteCrtc; 335706f2543Smrg hwp->readCrtc = stdReadCrtc; 336706f2543Smrg hwp->writeGr = stdWriteGr; 337706f2543Smrg hwp->readGr = stdReadGr; 338706f2543Smrg hwp->readST00 = stdReadST00; 339706f2543Smrg hwp->readST01 = stdReadST01; 340706f2543Smrg hwp->readFCR = stdReadFCR; 341706f2543Smrg hwp->writeFCR = stdWriteFCR; 342706f2543Smrg hwp->writeAttr = stdWriteAttr; 343706f2543Smrg hwp->readAttr = stdReadAttr; 344706f2543Smrg hwp->writeSeq = stdWriteSeq; 345706f2543Smrg hwp->readSeq = stdReadSeq; 346706f2543Smrg hwp->writeMiscOut = stdWriteMiscOut; 347706f2543Smrg hwp->readMiscOut = stdReadMiscOut; 348706f2543Smrg hwp->enablePalette = stdEnablePalette; 349706f2543Smrg hwp->disablePalette = stdDisablePalette; 350706f2543Smrg hwp->writeDacMask = stdWriteDacMask; 351706f2543Smrg hwp->readDacMask = stdReadDacMask; 352706f2543Smrg hwp->writeDacWriteAddr = stdWriteDacWriteAddr; 353706f2543Smrg hwp->writeDacReadAddr = stdWriteDacReadAddr; 354706f2543Smrg hwp->writeDacData = stdWriteDacData; 355706f2543Smrg hwp->readDacData = stdReadDacData; 356706f2543Smrg hwp->PIOOffset = 0; 357706f2543Smrg hwp->readEnable = stdReadEnable; 358706f2543Smrg hwp->writeEnable = stdWriteEnable; 359706f2543Smrg} 360706f2543Smrg 361706f2543Smrg/* 362706f2543Smrg * MMIO versions of the register access functions. These require 363706f2543Smrg * hwp->MemBase to be set in such a way that when the standard VGA port 364706f2543Smrg * adderss is added the correct memory address results. 365706f2543Smrg */ 366706f2543Smrg 367706f2543Smrg#define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p))) 368706f2543Smrg#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v)) 369706f2543Smrg 370706f2543Smrgstatic void 371706f2543SmrgmmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 372706f2543Smrg{ 373706f2543Smrg moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 374706f2543Smrg moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value); 375706f2543Smrg} 376706f2543Smrg 377706f2543Smrgstatic CARD8 378706f2543SmrgmmioReadCrtc(vgaHWPtr hwp, CARD8 index) 379706f2543Smrg{ 380706f2543Smrg moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index); 381706f2543Smrg return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET); 382706f2543Smrg} 383706f2543Smrg 384706f2543Smrgstatic void 385706f2543SmrgmmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value) 386706f2543Smrg{ 387706f2543Smrg moutb(VGA_GRAPH_INDEX, index); 388706f2543Smrg moutb(VGA_GRAPH_DATA, value); 389706f2543Smrg} 390706f2543Smrg 391706f2543Smrgstatic CARD8 392706f2543SmrgmmioReadGr(vgaHWPtr hwp, CARD8 index) 393706f2543Smrg{ 394706f2543Smrg moutb(VGA_GRAPH_INDEX, index); 395706f2543Smrg return minb(VGA_GRAPH_DATA); 396706f2543Smrg} 397706f2543Smrg 398706f2543Smrgstatic void 399706f2543SmrgmmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value) 400706f2543Smrg{ 401706f2543Smrg moutb(VGA_SEQ_INDEX, index); 402706f2543Smrg moutb(VGA_SEQ_DATA, value); 403706f2543Smrg} 404706f2543Smrg 405706f2543Smrgstatic CARD8 406706f2543SmrgmmioReadSeq(vgaHWPtr hwp, CARD8 index) 407706f2543Smrg{ 408706f2543Smrg moutb(VGA_SEQ_INDEX, index); 409706f2543Smrg return minb(VGA_SEQ_DATA); 410706f2543Smrg} 411706f2543Smrg 412706f2543Smrgstatic CARD8 413706f2543SmrgmmioReadST00(vgaHWPtr hwp) 414706f2543Smrg{ 415706f2543Smrg return minb(VGA_IN_STAT_0); 416706f2543Smrg} 417706f2543Smrg 418706f2543Smrgstatic CARD8 419706f2543SmrgmmioReadST01(vgaHWPtr hwp) 420706f2543Smrg{ 421706f2543Smrg return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 422706f2543Smrg} 423706f2543Smrg 424706f2543Smrgstatic CARD8 425706f2543SmrgmmioReadFCR(vgaHWPtr hwp) 426706f2543Smrg{ 427706f2543Smrg return minb(VGA_FEATURE_R); 428706f2543Smrg} 429706f2543Smrg 430706f2543Smrgstatic void 431706f2543SmrgmmioWriteFCR(vgaHWPtr hwp, CARD8 value) 432706f2543Smrg{ 433706f2543Smrg moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET,value); 434706f2543Smrg} 435706f2543Smrg 436706f2543Smrgstatic void 437706f2543SmrgmmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value) 438706f2543Smrg{ 439706f2543Smrg if (hwp->paletteEnabled) 440706f2543Smrg index &= ~0x20; 441706f2543Smrg else 442706f2543Smrg index |= 0x20; 443706f2543Smrg 444706f2543Smrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 445706f2543Smrg moutb(VGA_ATTR_INDEX, index); 446706f2543Smrg moutb(VGA_ATTR_DATA_W, value); 447706f2543Smrg} 448706f2543Smrg 449706f2543Smrgstatic CARD8 450706f2543SmrgmmioReadAttr(vgaHWPtr hwp, CARD8 index) 451706f2543Smrg{ 452706f2543Smrg if (hwp->paletteEnabled) 453706f2543Smrg index &= ~0x20; 454706f2543Smrg else 455706f2543Smrg index |= 0x20; 456706f2543Smrg 457706f2543Smrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 458706f2543Smrg moutb(VGA_ATTR_INDEX, index); 459706f2543Smrg return minb(VGA_ATTR_DATA_R); 460706f2543Smrg} 461706f2543Smrg 462706f2543Smrgstatic void 463706f2543SmrgmmioWriteMiscOut(vgaHWPtr hwp, CARD8 value) 464706f2543Smrg{ 465706f2543Smrg moutb(VGA_MISC_OUT_W, value); 466706f2543Smrg} 467706f2543Smrg 468706f2543Smrgstatic CARD8 469706f2543SmrgmmioReadMiscOut(vgaHWPtr hwp) 470706f2543Smrg{ 471706f2543Smrg return minb(VGA_MISC_OUT_R); 472706f2543Smrg} 473706f2543Smrg 474706f2543Smrgstatic void 475706f2543SmrgmmioEnablePalette(vgaHWPtr hwp) 476706f2543Smrg{ 477706f2543Smrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 478706f2543Smrg moutb(VGA_ATTR_INDEX, 0x00); 479706f2543Smrg hwp->paletteEnabled = TRUE; 480706f2543Smrg} 481706f2543Smrg 482706f2543Smrgstatic void 483706f2543SmrgmmioDisablePalette(vgaHWPtr hwp) 484706f2543Smrg{ 485706f2543Smrg (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); 486706f2543Smrg moutb(VGA_ATTR_INDEX, 0x20); 487706f2543Smrg hwp->paletteEnabled = FALSE; 488706f2543Smrg} 489706f2543Smrg 490706f2543Smrgstatic void 491706f2543SmrgmmioWriteDacMask(vgaHWPtr hwp, CARD8 value) 492706f2543Smrg{ 493706f2543Smrg moutb(VGA_DAC_MASK, value); 494706f2543Smrg} 495706f2543Smrg 496706f2543Smrgstatic CARD8 497706f2543SmrgmmioReadDacMask(vgaHWPtr hwp) 498706f2543Smrg{ 499706f2543Smrg return minb(VGA_DAC_MASK); 500706f2543Smrg} 501706f2543Smrg 502706f2543Smrgstatic void 503706f2543SmrgmmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value) 504706f2543Smrg{ 505706f2543Smrg moutb(VGA_DAC_READ_ADDR, value); 506706f2543Smrg} 507706f2543Smrg 508706f2543Smrgstatic void 509706f2543SmrgmmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value) 510706f2543Smrg{ 511706f2543Smrg moutb(VGA_DAC_WRITE_ADDR, value); 512706f2543Smrg} 513706f2543Smrg 514706f2543Smrgstatic void 515706f2543SmrgmmioWriteDacData(vgaHWPtr hwp, CARD8 value) 516706f2543Smrg{ 517706f2543Smrg moutb(VGA_DAC_DATA, value); 518706f2543Smrg} 519706f2543Smrg 520706f2543Smrgstatic CARD8 521706f2543SmrgmmioReadDacData(vgaHWPtr hwp) 522706f2543Smrg{ 523706f2543Smrg return minb(VGA_DAC_DATA); 524706f2543Smrg} 525706f2543Smrg 526706f2543Smrgstatic CARD8 527706f2543SmrgmmioReadEnable(vgaHWPtr hwp) 528706f2543Smrg{ 529706f2543Smrg return minb(VGA_ENABLE); 530706f2543Smrg} 531706f2543Smrg 532706f2543Smrgstatic void 533706f2543SmrgmmioWriteEnable(vgaHWPtr hwp, CARD8 value) 534706f2543Smrg{ 535706f2543Smrg moutb(VGA_ENABLE, value); 536706f2543Smrg} 537706f2543Smrg 538706f2543Smrgvoid 539706f2543SmrgvgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset) 540706f2543Smrg{ 541706f2543Smrg hwp->writeCrtc = mmioWriteCrtc; 542706f2543Smrg hwp->readCrtc = mmioReadCrtc; 543706f2543Smrg hwp->writeGr = mmioWriteGr; 544706f2543Smrg hwp->readGr = mmioReadGr; 545706f2543Smrg hwp->readST00 = mmioReadST00; 546706f2543Smrg hwp->readST01 = mmioReadST01; 547706f2543Smrg hwp->readFCR = mmioReadFCR; 548706f2543Smrg hwp->writeFCR = mmioWriteFCR; 549706f2543Smrg hwp->writeAttr = mmioWriteAttr; 550706f2543Smrg hwp->readAttr = mmioReadAttr; 551706f2543Smrg hwp->writeSeq = mmioWriteSeq; 552706f2543Smrg hwp->readSeq = mmioReadSeq; 553706f2543Smrg hwp->writeMiscOut = mmioWriteMiscOut; 554706f2543Smrg hwp->readMiscOut = mmioReadMiscOut; 555706f2543Smrg hwp->enablePalette = mmioEnablePalette; 556706f2543Smrg hwp->disablePalette = mmioDisablePalette; 557706f2543Smrg hwp->writeDacMask = mmioWriteDacMask; 558706f2543Smrg hwp->readDacMask = mmioReadDacMask; 559706f2543Smrg hwp->writeDacWriteAddr = mmioWriteDacWriteAddr; 560706f2543Smrg hwp->writeDacReadAddr = mmioWriteDacReadAddr; 561706f2543Smrg hwp->writeDacData = mmioWriteDacData; 562706f2543Smrg hwp->readDacData = mmioReadDacData; 563706f2543Smrg hwp->MMIOBase = base; 564706f2543Smrg hwp->MMIOOffset = offset; 565706f2543Smrg hwp->readEnable = mmioReadEnable; 566706f2543Smrg hwp->writeEnable = mmioWriteEnable; 567706f2543Smrg} 568706f2543Smrg 569706f2543Smrg/* 570706f2543Smrg * vgaHWProtect -- 571706f2543Smrg * Protect VGA registers and memory from corruption during loads. 572706f2543Smrg */ 573706f2543Smrg 574706f2543Smrgvoid 575706f2543SmrgvgaHWProtect(ScrnInfoPtr pScrn, Bool on) 576706f2543Smrg{ 577706f2543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 578706f2543Smrg 579706f2543Smrg unsigned char tmp; 580706f2543Smrg 581706f2543Smrg if (pScrn->vtSema) { 582706f2543Smrg if (on) { 583706f2543Smrg /* 584706f2543Smrg * Turn off screen and disable sequencer. 585706f2543Smrg */ 586706f2543Smrg tmp = hwp->readSeq(hwp, 0x01); 587706f2543Smrg 588706f2543Smrg vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */ 589706f2543Smrg hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */ 590706f2543Smrg 591706f2543Smrg hwp->enablePalette(hwp); 592706f2543Smrg } else { 593706f2543Smrg /* 594706f2543Smrg * Reenable sequencer, then turn on screen. 595706f2543Smrg */ 596706f2543Smrg 597706f2543Smrg tmp = hwp->readSeq(hwp, 0x01); 598706f2543Smrg 599706f2543Smrg hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */ 600706f2543Smrg vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */ 601706f2543Smrg 602706f2543Smrg hwp->disablePalette(hwp); 603706f2543Smrg } 604706f2543Smrg } 605706f2543Smrg} 606706f2543Smrg 607706f2543SmrgvgaHWProtectProc *vgaHWProtectWeak(void) { 608706f2543Smrg return vgaHWProtect; 609706f2543Smrg} 610706f2543Smrg 611706f2543Smrg/* 612706f2543Smrg * vgaHWBlankScreen -- blank the screen. 613706f2543Smrg */ 614706f2543Smrg 615706f2543Smrgvoid 616706f2543SmrgvgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on) 617706f2543Smrg{ 618706f2543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 619706f2543Smrg unsigned char scrn; 620706f2543Smrg 621706f2543Smrg scrn = hwp->readSeq(hwp, 0x01); 622706f2543Smrg 623706f2543Smrg if (on) { 624706f2543Smrg scrn &= ~0x20; /* enable screen */ 625706f2543Smrg } else { 626706f2543Smrg scrn |= 0x20; /* blank screen */ 627706f2543Smrg } 628706f2543Smrg 629706f2543Smrg vgaHWSeqReset(hwp, TRUE); 630706f2543Smrg hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 631706f2543Smrg vgaHWSeqReset(hwp, FALSE); 632706f2543Smrg} 633706f2543Smrg 634706f2543SmrgvgaHWBlankScreenProc *vgaHWBlankScreenWeak(void) { 635706f2543Smrg return vgaHWBlankScreen; 636706f2543Smrg} 637706f2543Smrg 638706f2543Smrg/* 639706f2543Smrg * vgaHWSaveScreen -- blank the screen. 640706f2543Smrg */ 641706f2543Smrg 642706f2543SmrgBool 643706f2543SmrgvgaHWSaveScreen(ScreenPtr pScreen, int mode) 644706f2543Smrg{ 645706f2543Smrg ScrnInfoPtr pScrn = NULL; 646706f2543Smrg Bool on; 647706f2543Smrg 648706f2543Smrg if (pScreen != NULL) 649706f2543Smrg pScrn = xf86Screens[pScreen->myNum]; 650706f2543Smrg 651706f2543Smrg on = xf86IsUnblank(mode); 652706f2543Smrg 653706f2543Smrg#if 0 654706f2543Smrg if (on) 655706f2543Smrg SetTimeSinceLastInputEvent(); 656706f2543Smrg#endif 657706f2543Smrg 658706f2543Smrg if ((pScrn != NULL) && pScrn->vtSema) { 659706f2543Smrg vgaHWBlankScreen(pScrn, on); 660706f2543Smrg } 661706f2543Smrg return TRUE; 662706f2543Smrg} 663706f2543Smrg 664706f2543Smrg 665706f2543Smrg/* 666706f2543Smrg * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode 667706f2543Smrg * 668706f2543Smrg * This generic VGA function can only set the Off and On modes. If the 669706f2543Smrg * Standby and Suspend modes are to be supported, a chip specific replacement 670706f2543Smrg * for this function must be written. 671706f2543Smrg */ 672706f2543Smrg 673706f2543Smrgvoid 674706f2543SmrgvgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) 675706f2543Smrg{ 676706f2543Smrg unsigned char seq1 = 0, crtc17 = 0; 677706f2543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 678706f2543Smrg 679706f2543Smrg if (!pScrn->vtSema) return; 680706f2543Smrg 681706f2543Smrg switch (PowerManagementMode) { 682706f2543Smrg case DPMSModeOn: 683706f2543Smrg /* Screen: On; HSync: On, VSync: On */ 684706f2543Smrg seq1 = 0x00; 685706f2543Smrg crtc17 = 0x80; 686706f2543Smrg break; 687706f2543Smrg case DPMSModeStandby: 688706f2543Smrg /* Screen: Off; HSync: Off, VSync: On -- Not Supported */ 689706f2543Smrg seq1 = 0x20; 690706f2543Smrg crtc17 = 0x80; 691706f2543Smrg break; 692706f2543Smrg case DPMSModeSuspend: 693706f2543Smrg /* Screen: Off; HSync: On, VSync: Off -- Not Supported */ 694706f2543Smrg seq1 = 0x20; 695706f2543Smrg crtc17 = 0x80; 696706f2543Smrg break; 697706f2543Smrg case DPMSModeOff: 698706f2543Smrg /* Screen: Off; HSync: Off, VSync: Off */ 699706f2543Smrg seq1 = 0x20; 700706f2543Smrg crtc17 = 0x00; 701706f2543Smrg break; 702706f2543Smrg } 703706f2543Smrg hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */ 704706f2543Smrg seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20; 705706f2543Smrg hwp->writeSeq(hwp, 0x01, seq1); 706706f2543Smrg crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80; 707706f2543Smrg usleep(10000); 708706f2543Smrg hwp->writeCrtc(hwp, 0x17, crtc17); 709706f2543Smrg hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */ 710706f2543Smrg} 711706f2543Smrg 712706f2543Smrg 713706f2543Smrg/* 714706f2543Smrg * vgaHWSeqReset 715706f2543Smrg * perform a sequencer reset. 716706f2543Smrg */ 717706f2543Smrg 718706f2543Smrgvoid 719706f2543SmrgvgaHWSeqReset(vgaHWPtr hwp, Bool start) 720706f2543Smrg{ 721706f2543Smrg if (start) 722706f2543Smrg hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */ 723706f2543Smrg else 724706f2543Smrg hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */ 725706f2543Smrg} 726706f2543Smrg 727706f2543Smrg 728706f2543Smrgvoid 729706f2543SmrgvgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) 730706f2543Smrg{ 731706f2543Smrg#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 732706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 733706f2543Smrg int savedIOBase; 734706f2543Smrg unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4; 735706f2543Smrg Bool doMap = FALSE; 736706f2543Smrg 737706f2543Smrg /* If nothing to do, return now */ 738706f2543Smrg if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo) 739706f2543Smrg return; 740706f2543Smrg 741706f2543Smrg if (hwp->Base == NULL) { 742706f2543Smrg doMap = TRUE; 743706f2543Smrg if (!vgaHWMapMem(scrninfp)) { 744706f2543Smrg xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, 745706f2543Smrg "vgaHWRestoreFonts: vgaHWMapMem() failed\n"); 746706f2543Smrg return; 747706f2543Smrg } 748706f2543Smrg } 749706f2543Smrg 750706f2543Smrg /* save the registers that are needed here */ 751706f2543Smrg miscOut = hwp->readMiscOut(hwp); 752706f2543Smrg attr10 = hwp->readAttr(hwp, 0x10); 753706f2543Smrg gr1 = hwp->readGr(hwp, 0x01); 754706f2543Smrg gr3 = hwp->readGr(hwp, 0x03); 755706f2543Smrg gr4 = hwp->readGr(hwp, 0x04); 756706f2543Smrg gr5 = hwp->readGr(hwp, 0x05); 757706f2543Smrg gr6 = hwp->readGr(hwp, 0x06); 758706f2543Smrg gr8 = hwp->readGr(hwp, 0x08); 759706f2543Smrg seq2 = hwp->readSeq(hwp, 0x02); 760706f2543Smrg seq4 = hwp->readSeq(hwp, 0x04); 761706f2543Smrg 762706f2543Smrg /* save hwp->IOBase and temporarily set it for colour mode */ 763706f2543Smrg savedIOBase = hwp->IOBase; 764706f2543Smrg hwp->IOBase = VGA_IOBASE_COLOR; 765706f2543Smrg 766706f2543Smrg /* Force into colour mode */ 767706f2543Smrg hwp->writeMiscOut(hwp, miscOut | 0x01); 768706f2543Smrg 769706f2543Smrg vgaHWBlankScreen(scrninfp, FALSE); 770706f2543Smrg 771706f2543Smrg /* 772706f2543Smrg * here we temporarily switch to 16 colour planar mode, to simply 773706f2543Smrg * copy the font-info and saved text. 774706f2543Smrg * 775706f2543Smrg * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! 776706f2543Smrg */ 777706f2543Smrg#if 0 778706f2543Smrg hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ 779706f2543Smrg#endif 780706f2543Smrg 781706f2543Smrg hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ 782706f2543Smrg hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ 783706f2543Smrg hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ 784706f2543Smrg 785706f2543Smrg if (scrninfp->depth == 4) { 786706f2543Smrg /* GJA */ 787706f2543Smrg hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */ 788706f2543Smrg hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */ 789706f2543Smrg hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */ 790706f2543Smrg } 791706f2543Smrg 792706f2543Smrg#if SAVE_FONT1 793706f2543Smrg if (hwp->FontInfo1) { 794706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ 795706f2543Smrg hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ 796706f2543Smrg slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT); 797706f2543Smrg } 798706f2543Smrg#endif 799706f2543Smrg 800706f2543Smrg#if SAVE_FONT2 801706f2543Smrg if (hwp->FontInfo2) { 802706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ 803706f2543Smrg hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ 804706f2543Smrg slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT); 805706f2543Smrg } 806706f2543Smrg#endif 807706f2543Smrg 808706f2543Smrg#if SAVE_TEXT 809706f2543Smrg if (hwp->TextInfo) { 810706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ 811706f2543Smrg hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ 812706f2543Smrg slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT); 813706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ 814706f2543Smrg hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ 815706f2543Smrg slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT, 816706f2543Smrg hwp->Base, TEXT_AMOUNT); 817706f2543Smrg } 818706f2543Smrg#endif 819706f2543Smrg 820706f2543Smrg vgaHWBlankScreen(scrninfp, TRUE); 821706f2543Smrg 822706f2543Smrg /* restore the registers that were changed */ 823706f2543Smrg hwp->writeMiscOut(hwp, miscOut); 824706f2543Smrg hwp->writeAttr(hwp, 0x10, attr10); 825706f2543Smrg hwp->writeGr(hwp, 0x01, gr1); 826706f2543Smrg hwp->writeGr(hwp, 0x03, gr3); 827706f2543Smrg hwp->writeGr(hwp, 0x04, gr4); 828706f2543Smrg hwp->writeGr(hwp, 0x05, gr5); 829706f2543Smrg hwp->writeGr(hwp, 0x06, gr6); 830706f2543Smrg hwp->writeGr(hwp, 0x08, gr8); 831706f2543Smrg hwp->writeSeq(hwp, 0x02, seq2); 832706f2543Smrg hwp->writeSeq(hwp, 0x04, seq4); 833706f2543Smrg hwp->IOBase = savedIOBase; 834706f2543Smrg 835706f2543Smrg if (doMap) 836706f2543Smrg vgaHWUnmapMem(scrninfp); 837706f2543Smrg 838706f2543Smrg#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */ 839706f2543Smrg} 840706f2543Smrg 841706f2543Smrg 842706f2543Smrgvoid 843706f2543SmrgvgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore) 844706f2543Smrg{ 845706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 846706f2543Smrg int i; 847706f2543Smrg 848706f2543Smrg if (restore->MiscOutReg & 0x01) 849706f2543Smrg hwp->IOBase = VGA_IOBASE_COLOR; 850706f2543Smrg else 851706f2543Smrg hwp->IOBase = VGA_IOBASE_MONO; 852706f2543Smrg 853706f2543Smrg hwp->writeMiscOut(hwp, restore->MiscOutReg); 854706f2543Smrg 855706f2543Smrg for (i = 1; i < restore->numSequencer; i++) 856706f2543Smrg hwp->writeSeq(hwp, i, restore->Sequencer[i]); 857706f2543Smrg 858706f2543Smrg /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */ 859706f2543Smrg hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80); 860706f2543Smrg 861706f2543Smrg for (i = 0; i < restore->numCRTC; i++) 862706f2543Smrg hwp->writeCrtc(hwp, i, restore->CRTC[i]); 863706f2543Smrg 864706f2543Smrg for (i = 0; i < restore->numGraphics; i++) 865706f2543Smrg hwp->writeGr(hwp, i, restore->Graphics[i]); 866706f2543Smrg 867706f2543Smrg hwp->enablePalette(hwp); 868706f2543Smrg for (i = 0; i < restore->numAttribute; i++) 869706f2543Smrg hwp->writeAttr(hwp, i, restore->Attribute[i]); 870706f2543Smrg hwp->disablePalette(hwp); 871706f2543Smrg} 872706f2543Smrg 873706f2543Smrg 874706f2543Smrgvoid 875706f2543SmrgvgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore) 876706f2543Smrg{ 877706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 878706f2543Smrg int i; 879706f2543Smrg 880706f2543Smrg#if 0 881706f2543Smrg hwp->enablePalette(hwp); 882706f2543Smrg#endif 883706f2543Smrg 884706f2543Smrg hwp->writeDacMask(hwp, 0xFF); 885706f2543Smrg hwp->writeDacWriteAddr(hwp, 0x00); 886706f2543Smrg for (i = 0; i < 768; i++) { 887706f2543Smrg hwp->writeDacData(hwp, restore->DAC[i]); 888706f2543Smrg DACDelay(hwp); 889706f2543Smrg } 890706f2543Smrg 891706f2543Smrg hwp->disablePalette(hwp); 892706f2543Smrg} 893706f2543Smrg 894706f2543Smrg 895706f2543Smrg/* 896706f2543Smrg * vgaHWRestore -- 897706f2543Smrg * restore the VGA state 898706f2543Smrg */ 899706f2543Smrg 900706f2543Smrgvoid 901706f2543SmrgvgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags) 902706f2543Smrg{ 903706f2543Smrg if (flags & VGA_SR_MODE) 904706f2543Smrg vgaHWRestoreMode(scrninfp, restore); 905706f2543Smrg 906706f2543Smrg if (flags & VGA_SR_FONTS) 907706f2543Smrg vgaHWRestoreFonts(scrninfp, restore); 908706f2543Smrg 909706f2543Smrg if (flags & VGA_SR_CMAP) 910706f2543Smrg vgaHWRestoreColormap(scrninfp, restore); 911706f2543Smrg} 912706f2543Smrg 913706f2543Smrgvoid 914706f2543SmrgvgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) 915706f2543Smrg{ 916706f2543Smrg#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 917706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 918706f2543Smrg int savedIOBase; 919706f2543Smrg unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4; 920706f2543Smrg Bool doMap = FALSE; 921706f2543Smrg 922706f2543Smrg if (hwp->Base == NULL) { 923706f2543Smrg doMap = TRUE; 924706f2543Smrg if (!vgaHWMapMem(scrninfp)) { 925706f2543Smrg xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, 926706f2543Smrg "vgaHWSaveFonts: vgaHWMapMem() failed\n"); 927706f2543Smrg return; 928706f2543Smrg } 929706f2543Smrg } 930706f2543Smrg 931706f2543Smrg /* If in graphics mode, don't save anything */ 932706f2543Smrg attr10 = hwp->readAttr(hwp, 0x10); 933706f2543Smrg if (attr10 & 0x01) 934706f2543Smrg return; 935706f2543Smrg 936706f2543Smrg /* save the registers that are needed here */ 937706f2543Smrg miscOut = hwp->readMiscOut(hwp); 938706f2543Smrg gr4 = hwp->readGr(hwp, 0x04); 939706f2543Smrg gr5 = hwp->readGr(hwp, 0x05); 940706f2543Smrg gr6 = hwp->readGr(hwp, 0x06); 941706f2543Smrg seq2 = hwp->readSeq(hwp, 0x02); 942706f2543Smrg seq4 = hwp->readSeq(hwp, 0x04); 943706f2543Smrg 944706f2543Smrg /* save hwp->IOBase and temporarily set it for colour mode */ 945706f2543Smrg savedIOBase = hwp->IOBase; 946706f2543Smrg hwp->IOBase = VGA_IOBASE_COLOR; 947706f2543Smrg 948706f2543Smrg /* Force into colour mode */ 949706f2543Smrg hwp->writeMiscOut(hwp, miscOut | 0x01); 950706f2543Smrg 951706f2543Smrg vgaHWBlankScreen(scrninfp, FALSE); 952706f2543Smrg 953706f2543Smrg /* 954706f2543Smrg * get the character sets, and text screen if required 955706f2543Smrg */ 956706f2543Smrg /* 957706f2543Smrg * Here we temporarily switch to 16 colour planar mode, to simply 958706f2543Smrg * copy the font-info 959706f2543Smrg * 960706f2543Smrg * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! 961706f2543Smrg */ 962706f2543Smrg#if 0 963706f2543Smrg hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ 964706f2543Smrg#endif 965706f2543Smrg 966706f2543Smrg hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ 967706f2543Smrg hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ 968706f2543Smrg hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ 969706f2543Smrg 970706f2543Smrg#if SAVE_FONT1 971706f2543Smrg if (hwp->FontInfo1 || (hwp->FontInfo1 = malloc(FONT_AMOUNT))) { 972706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ 973706f2543Smrg hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ 974706f2543Smrg slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT); 975706f2543Smrg } 976706f2543Smrg#endif /* SAVE_FONT1 */ 977706f2543Smrg#if SAVE_FONT2 978706f2543Smrg if (hwp->FontInfo2 || (hwp->FontInfo2 = malloc(FONT_AMOUNT))) { 979706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ 980706f2543Smrg hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ 981706f2543Smrg slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT); 982706f2543Smrg } 983706f2543Smrg#endif /* SAVE_FONT2 */ 984706f2543Smrg#if SAVE_TEXT 985706f2543Smrg if (hwp->TextInfo || (hwp->TextInfo = malloc(2 * TEXT_AMOUNT))) { 986706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ 987706f2543Smrg hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ 988706f2543Smrg slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT); 989706f2543Smrg hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ 990706f2543Smrg hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ 991706f2543Smrg slowbcopy_frombus(hwp->Base, 992706f2543Smrg (unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT); 993706f2543Smrg } 994706f2543Smrg#endif /* SAVE_TEXT */ 995706f2543Smrg 996706f2543Smrg /* Restore clobbered registers */ 997706f2543Smrg hwp->writeAttr(hwp, 0x10, attr10); 998706f2543Smrg hwp->writeSeq(hwp, 0x02, seq2); 999706f2543Smrg hwp->writeSeq(hwp, 0x04, seq4); 1000706f2543Smrg hwp->writeGr(hwp, 0x04, gr4); 1001706f2543Smrg hwp->writeGr(hwp, 0x05, gr5); 1002706f2543Smrg hwp->writeGr(hwp, 0x06, gr6); 1003706f2543Smrg hwp->writeMiscOut(hwp, miscOut); 1004706f2543Smrg hwp->IOBase = savedIOBase; 1005706f2543Smrg 1006706f2543Smrg vgaHWBlankScreen(scrninfp, TRUE); 1007706f2543Smrg 1008706f2543Smrg if (doMap) 1009706f2543Smrg vgaHWUnmapMem(scrninfp); 1010706f2543Smrg 1011706f2543Smrg#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */ 1012706f2543Smrg} 1013706f2543Smrg 1014706f2543Smrgvoid 1015706f2543SmrgvgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save) 1016706f2543Smrg{ 1017706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 1018706f2543Smrg int i; 1019706f2543Smrg 1020706f2543Smrg save->MiscOutReg = hwp->readMiscOut(hwp); 1021706f2543Smrg if (save->MiscOutReg & 0x01) 1022706f2543Smrg hwp->IOBase = VGA_IOBASE_COLOR; 1023706f2543Smrg else 1024706f2543Smrg hwp->IOBase = VGA_IOBASE_MONO; 1025706f2543Smrg 1026706f2543Smrg for (i = 0; i < save->numCRTC; i++) { 1027706f2543Smrg save->CRTC[i] = hwp->readCrtc(hwp, i); 1028706f2543Smrg DebugF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]); 1029706f2543Smrg } 1030706f2543Smrg 1031706f2543Smrg hwp->enablePalette(hwp); 1032706f2543Smrg for (i = 0; i < save->numAttribute; i++) { 1033706f2543Smrg save->Attribute[i] = hwp->readAttr(hwp, i); 1034706f2543Smrg DebugF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]); 1035706f2543Smrg } 1036706f2543Smrg hwp->disablePalette(hwp); 1037706f2543Smrg 1038706f2543Smrg for (i = 0; i < save->numGraphics; i++) { 1039706f2543Smrg save->Graphics[i] = hwp->readGr(hwp, i); 1040706f2543Smrg DebugF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]); 1041706f2543Smrg } 1042706f2543Smrg 1043706f2543Smrg for (i = 1; i < save->numSequencer; i++) { 1044706f2543Smrg save->Sequencer[i] = hwp->readSeq(hwp, i); 1045706f2543Smrg DebugF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]); 1046706f2543Smrg } 1047706f2543Smrg} 1048706f2543Smrg 1049706f2543Smrg 1050706f2543Smrgvoid 1051706f2543SmrgvgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save) 1052706f2543Smrg{ 1053706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrninfp); 1054706f2543Smrg Bool readError = FALSE; 1055706f2543Smrg int i; 1056706f2543Smrg 1057706f2543Smrg#ifdef NEED_SAVED_CMAP 1058706f2543Smrg /* 1059706f2543Smrg * Some ET4000 chips from 1991 have a HW bug that prevents the reading 1060706f2543Smrg * of the color lookup table. Mask rev 9042EAI is known to have this bug. 1061706f2543Smrg * 1062706f2543Smrg * If the colourmap is not readable, we set the saved map to a default 1063706f2543Smrg * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA 1064706f2543Smrg * Cards" 2nd ed). 1065706f2543Smrg */ 1066706f2543Smrg 1067706f2543Smrg /* Only save it once */ 1068706f2543Smrg if (hwp->cmapSaved) 1069706f2543Smrg return; 1070706f2543Smrg 1071706f2543Smrg#if 0 1072706f2543Smrg hwp->enablePalette(hwp); 1073706f2543Smrg#endif 1074706f2543Smrg 1075706f2543Smrg hwp->writeDacMask(hwp, 0xFF); 1076706f2543Smrg 1077706f2543Smrg /* 1078706f2543Smrg * check if we can read the lookup table 1079706f2543Smrg */ 1080706f2543Smrg hwp->writeDacReadAddr(hwp, 0x00); 1081706f2543Smrg for (i = 0; i < 6; i++) { 1082706f2543Smrg save->DAC[i] = hwp->readDacData(hwp); 1083706f2543Smrg switch (i % 3) { 1084706f2543Smrg case 0: 1085706f2543Smrg DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]); 1086706f2543Smrg break; 1087706f2543Smrg case 1: 1088706f2543Smrg DebugF("0x%02x, ", save->DAC[i]); 1089706f2543Smrg break; 1090706f2543Smrg case 2: 1091706f2543Smrg DebugF("0x%02x\n", save->DAC[i]); 1092706f2543Smrg } 1093706f2543Smrg } 1094706f2543Smrg 1095706f2543Smrg /* 1096706f2543Smrg * Check if we can read the palette - 1097706f2543Smrg * use foreground color to prevent flashing. 1098706f2543Smrg */ 1099706f2543Smrg hwp->writeDacWriteAddr(hwp, 0x01); 1100706f2543Smrg for (i = 3; i < 6; i++) 1101706f2543Smrg hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK); 1102706f2543Smrg hwp->writeDacReadAddr(hwp, 0x01); 1103706f2543Smrg for (i = 3; i < 6; i++) { 1104706f2543Smrg if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK)) 1105706f2543Smrg readError = TRUE; 1106706f2543Smrg } 1107706f2543Smrg hwp->writeDacWriteAddr(hwp, 0x01); 1108706f2543Smrg for (i = 3; i < 6; i++) 1109706f2543Smrg hwp->writeDacData(hwp, save->DAC[i]); 1110706f2543Smrg 1111706f2543Smrg if (readError) { 1112706f2543Smrg /* 1113706f2543Smrg * save the default lookup table 1114706f2543Smrg */ 1115706f2543Smrg memmove(save->DAC, defaultDAC, 768); 1116706f2543Smrg xf86DrvMsg(scrninfp->scrnIndex, X_WARNING, 1117706f2543Smrg "Cannot read colourmap from VGA. Will restore with default\n"); 1118706f2543Smrg } else { 1119706f2543Smrg /* save the colourmap */ 1120706f2543Smrg hwp->writeDacReadAddr(hwp, 0x02); 1121706f2543Smrg for (i = 6; i < 768; i++) { 1122706f2543Smrg save->DAC[i] = hwp->readDacData(hwp); 1123706f2543Smrg DACDelay(hwp); 1124706f2543Smrg switch (i % 3) { 1125706f2543Smrg case 0: 1126706f2543Smrg DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]); 1127706f2543Smrg break; 1128706f2543Smrg case 1: 1129706f2543Smrg DebugF("0x%02x, ", save->DAC[i]); 1130706f2543Smrg break; 1131706f2543Smrg case 2: 1132706f2543Smrg DebugF("0x%02x\n", save->DAC[i]); 1133706f2543Smrg } 1134706f2543Smrg } 1135706f2543Smrg } 1136706f2543Smrg 1137706f2543Smrg hwp->disablePalette(hwp); 1138706f2543Smrg hwp->cmapSaved = TRUE; 1139706f2543Smrg#endif 1140706f2543Smrg} 1141706f2543Smrg 1142706f2543Smrg/* 1143706f2543Smrg * vgaHWSave -- 1144706f2543Smrg * save the current VGA state 1145706f2543Smrg */ 1146706f2543Smrg 1147706f2543Smrgvoid 1148706f2543SmrgvgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags) 1149706f2543Smrg{ 1150706f2543Smrg if (save == NULL) 1151706f2543Smrg return; 1152706f2543Smrg 1153706f2543Smrg if (flags & VGA_SR_CMAP) 1154706f2543Smrg vgaHWSaveColormap(scrninfp, save); 1155706f2543Smrg 1156706f2543Smrg if (flags & VGA_SR_MODE) 1157706f2543Smrg vgaHWSaveMode(scrninfp, save); 1158706f2543Smrg 1159706f2543Smrg if (flags & VGA_SR_FONTS) 1160706f2543Smrg vgaHWSaveFonts(scrninfp, save); 1161706f2543Smrg} 1162706f2543Smrg 1163706f2543Smrg 1164706f2543Smrg/* 1165706f2543Smrg * vgaHWInit -- 1166706f2543Smrg * Handle the initialization, etc. of a screen. 1167706f2543Smrg * Return FALSE on failure. 1168706f2543Smrg */ 1169706f2543Smrg 1170706f2543SmrgBool 1171706f2543SmrgvgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode) 1172706f2543Smrg{ 1173706f2543Smrg unsigned int i; 1174706f2543Smrg vgaHWPtr hwp; 1175706f2543Smrg vgaRegPtr regp; 1176706f2543Smrg int depth = scrninfp->depth; 1177706f2543Smrg 1178706f2543Smrg /* 1179706f2543Smrg * make sure the vgaHWRec is allocated 1180706f2543Smrg */ 1181706f2543Smrg if (!vgaHWGetHWRec(scrninfp)) 1182706f2543Smrg return FALSE; 1183706f2543Smrg hwp = VGAHWPTR(scrninfp); 1184706f2543Smrg regp = &hwp->ModeReg; 1185706f2543Smrg 1186706f2543Smrg /* 1187706f2543Smrg * compute correct Hsync & Vsync polarity 1188706f2543Smrg */ 1189706f2543Smrg if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) 1190706f2543Smrg && (mode->Flags & (V_PVSYNC | V_NVSYNC))) 1191706f2543Smrg { 1192706f2543Smrg regp->MiscOutReg = 0x23; 1193706f2543Smrg if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40; 1194706f2543Smrg if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80; 1195706f2543Smrg } 1196706f2543Smrg else 1197706f2543Smrg { 1198706f2543Smrg int VDisplay = mode->VDisplay; 1199706f2543Smrg if (mode->Flags & V_DBLSCAN) 1200706f2543Smrg VDisplay *= 2; 1201706f2543Smrg if (mode->VScan > 1) 1202706f2543Smrg VDisplay *= mode->VScan; 1203706f2543Smrg if (VDisplay < 400) 1204706f2543Smrg regp->MiscOutReg = 0xA3; /* +hsync -vsync */ 1205706f2543Smrg else if (VDisplay < 480) 1206706f2543Smrg regp->MiscOutReg = 0x63; /* -hsync +vsync */ 1207706f2543Smrg else if (VDisplay < 768) 1208706f2543Smrg regp->MiscOutReg = 0xE3; /* -hsync -vsync */ 1209706f2543Smrg else 1210706f2543Smrg regp->MiscOutReg = 0x23; /* +hsync +vsync */ 1211706f2543Smrg } 1212706f2543Smrg 1213706f2543Smrg regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2; 1214706f2543Smrg 1215706f2543Smrg /* 1216706f2543Smrg * Time Sequencer 1217706f2543Smrg */ 1218706f2543Smrg if (depth == 4) 1219706f2543Smrg regp->Sequencer[0] = 0x02; 1220706f2543Smrg else 1221706f2543Smrg regp->Sequencer[0] = 0x00; 1222706f2543Smrg if (mode->Flags & V_CLKDIV2) 1223706f2543Smrg regp->Sequencer[1] = 0x09; 1224706f2543Smrg else 1225706f2543Smrg regp->Sequencer[1] = 0x01; 1226706f2543Smrg if (depth == 1) 1227706f2543Smrg regp->Sequencer[2] = 1 << BIT_PLANE; 1228706f2543Smrg else 1229706f2543Smrg regp->Sequencer[2] = 0x0F; 1230706f2543Smrg regp->Sequencer[3] = 0x00; /* Font select */ 1231706f2543Smrg if (depth < 8) 1232706f2543Smrg regp->Sequencer[4] = 0x06; /* Misc */ 1233706f2543Smrg else 1234706f2543Smrg regp->Sequencer[4] = 0x0E; /* Misc */ 1235706f2543Smrg 1236706f2543Smrg /* 1237706f2543Smrg * CRTC Controller 1238706f2543Smrg */ 1239706f2543Smrg regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5; 1240706f2543Smrg regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1; 1241706f2543Smrg regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1; 1242706f2543Smrg regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80; 1243706f2543Smrg i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F); 1244706f2543Smrg if (i < 0x80) 1245706f2543Smrg regp->CRTC[3] |= i; 1246706f2543Smrg regp->CRTC[4] = (mode->CrtcHSyncStart >> 3); 1247706f2543Smrg regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2) 1248706f2543Smrg | (((mode->CrtcHSyncEnd >> 3)) & 0x1F); 1249706f2543Smrg regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF; 1250706f2543Smrg regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8) 1251706f2543Smrg | (((mode->CrtcVDisplay - 1) & 0x100) >> 7) 1252706f2543Smrg | ((mode->CrtcVSyncStart & 0x100) >> 6) 1253706f2543Smrg | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5) 1254706f2543Smrg | 0x10 1255706f2543Smrg | (((mode->CrtcVTotal - 2) & 0x200) >> 4) 1256706f2543Smrg | (((mode->CrtcVDisplay - 1) & 0x200) >> 3) 1257706f2543Smrg | ((mode->CrtcVSyncStart & 0x200) >> 2); 1258706f2543Smrg regp->CRTC[8] = 0x00; 1259706f2543Smrg regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40; 1260706f2543Smrg if (mode->Flags & V_DBLSCAN) 1261706f2543Smrg regp->CRTC[9] |= 0x80; 1262706f2543Smrg if (mode->VScan >= 32) 1263706f2543Smrg regp->CRTC[9] |= 0x1F; 1264706f2543Smrg else if (mode->VScan > 1) 1265706f2543Smrg regp->CRTC[9] |= mode->VScan - 1; 1266706f2543Smrg regp->CRTC[10] = 0x00; 1267706f2543Smrg regp->CRTC[11] = 0x00; 1268706f2543Smrg regp->CRTC[12] = 0x00; 1269706f2543Smrg regp->CRTC[13] = 0x00; 1270706f2543Smrg regp->CRTC[14] = 0x00; 1271706f2543Smrg regp->CRTC[15] = 0x00; 1272706f2543Smrg regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF; 1273706f2543Smrg regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20; 1274706f2543Smrg regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF; 1275706f2543Smrg regp->CRTC[19] = scrninfp->displayWidth >> 4; /* just a guess */ 1276706f2543Smrg regp->CRTC[20] = 0x00; 1277706f2543Smrg regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF; 1278706f2543Smrg regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; 1279706f2543Smrg if (depth < 8) 1280706f2543Smrg regp->CRTC[23] = 0xE3; 1281706f2543Smrg else 1282706f2543Smrg regp->CRTC[23] = 0xC3; 1283706f2543Smrg regp->CRTC[24] = 0xFF; 1284706f2543Smrg 1285706f2543Smrg vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO); 1286706f2543Smrg vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO); 1287706f2543Smrg 1288706f2543Smrg /* 1289706f2543Smrg * Theory resumes here.... 1290706f2543Smrg */ 1291706f2543Smrg 1292706f2543Smrg /* 1293706f2543Smrg * Graphics Display Controller 1294706f2543Smrg */ 1295706f2543Smrg regp->Graphics[0] = 0x00; 1296706f2543Smrg regp->Graphics[1] = 0x00; 1297706f2543Smrg regp->Graphics[2] = 0x00; 1298706f2543Smrg regp->Graphics[3] = 0x00; 1299706f2543Smrg if (depth == 1) { 1300706f2543Smrg regp->Graphics[4] = BIT_PLANE; 1301706f2543Smrg regp->Graphics[5] = 0x00; 1302706f2543Smrg } else { 1303706f2543Smrg regp->Graphics[4] = 0x00; 1304706f2543Smrg if (depth == 4) 1305706f2543Smrg regp->Graphics[5] = 0x02; 1306706f2543Smrg else 1307706f2543Smrg regp->Graphics[5] = 0x40; 1308706f2543Smrg } 1309706f2543Smrg regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */ 1310706f2543Smrg regp->Graphics[7] = 0x0F; 1311706f2543Smrg regp->Graphics[8] = 0xFF; 1312706f2543Smrg 1313706f2543Smrg if (depth == 1) { 1314706f2543Smrg /* Initialise the Mono map according to which bit-plane gets used */ 1315706f2543Smrg 1316706f2543Smrg Bool flipPixels = xf86GetFlipPixels(); 1317706f2543Smrg 1318706f2543Smrg for (i=0; i<16; i++) 1319706f2543Smrg if (((i & (1 << BIT_PLANE)) != 0) != flipPixels) 1320706f2543Smrg regp->Attribute[i] = WHITE_VALUE; 1321706f2543Smrg else 1322706f2543Smrg regp->Attribute[i] = BLACK_VALUE; 1323706f2543Smrg 1324706f2543Smrg regp->Attribute[16] = 0x01; /* -VGA2- */ /* wrong for the ET4000 */ 1325706f2543Smrg if (!hwp->ShowOverscan) 1326706f2543Smrg regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */ 1327706f2543Smrg } else { 1328706f2543Smrg regp->Attribute[0] = 0x00; /* standard colormap translation */ 1329706f2543Smrg regp->Attribute[1] = 0x01; 1330706f2543Smrg regp->Attribute[2] = 0x02; 1331706f2543Smrg regp->Attribute[3] = 0x03; 1332706f2543Smrg regp->Attribute[4] = 0x04; 1333706f2543Smrg regp->Attribute[5] = 0x05; 1334706f2543Smrg regp->Attribute[6] = 0x06; 1335706f2543Smrg regp->Attribute[7] = 0x07; 1336706f2543Smrg regp->Attribute[8] = 0x08; 1337706f2543Smrg regp->Attribute[9] = 0x09; 1338706f2543Smrg regp->Attribute[10] = 0x0A; 1339706f2543Smrg regp->Attribute[11] = 0x0B; 1340706f2543Smrg regp->Attribute[12] = 0x0C; 1341706f2543Smrg regp->Attribute[13] = 0x0D; 1342706f2543Smrg regp->Attribute[14] = 0x0E; 1343706f2543Smrg regp->Attribute[15] = 0x0F; 1344706f2543Smrg if (depth == 4) 1345706f2543Smrg regp->Attribute[16] = 0x81; /* wrong for the ET4000 */ 1346706f2543Smrg else 1347706f2543Smrg regp->Attribute[16] = 0x41; /* wrong for the ET4000 */ 1348706f2543Smrg /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */ 1349706f2543Smrg } 1350706f2543Smrg regp->Attribute[18] = 0x0F; 1351706f2543Smrg regp->Attribute[19] = 0x00; 1352706f2543Smrg regp->Attribute[20] = 0x00; 1353706f2543Smrg 1354706f2543Smrg return TRUE; 1355706f2543Smrg} 1356706f2543Smrg 1357706f2543Smrg /* 1358706f2543Smrg * OK, so much for theory. Now, let's deal with the >real< world... 1359706f2543Smrg * 1360706f2543Smrg * The above CRTC settings are precise in theory, except that many, if not 1361706f2543Smrg * most, VGA clones fail to reset the blanking signal when the character or 1362706f2543Smrg * line counter reaches [HV]Total. In this case, the signal is only 1363706f2543Smrg * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as 1364706f2543Smrg * the case may be) at the start of the >next< scanline or frame, which 1365706f2543Smrg * means only part of the screen shows. This affects how null overscans 1366706f2543Smrg * are to be implemented on such adapters. 1367706f2543Smrg * 1368706f2543Smrg * Henceforth, VGA cores that implement this broken, but unfortunately 1369706f2543Smrg * common, behaviour are to be designated as KGA's, in honour of Koen 1370706f2543Smrg * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion 1371706f2543Smrg * a series of events that led to the discovery of this problem. 1372706f2543Smrg * 1373706f2543Smrg * Some VGA's are KGA's only in the horizontal, or only in the vertical, 1374706f2543Smrg * some in both, others in neither. Don't let anyone tell you there is 1375706f2543Smrg * such a thing as a VGA "standard"... And, thank the Creator for the fact 1376706f2543Smrg * that Hilbert spaces are not yet implemented in this industry. 1377706f2543Smrg * 1378706f2543Smrg * The following implements a trick suggested by David Dawes. This sets 1379706f2543Smrg * [HV]BlankEnd to zero if the blanking interval does not already contain a 1380706f2543Smrg * 0-point, and decrements it by one otherwise. In the latter case, this 1381706f2543Smrg * will produce a left and/or top overscan which the colourmap code will 1382706f2543Smrg * (still) need to ensure is as close to black as possible. This will make 1383706f2543Smrg * the behaviour consistent across all chipsets, while allowing all 1384706f2543Smrg * chipsets to display the entire screen. Non-KGA drivers can ignore the 1385706f2543Smrg * following in their own copy of this code. 1386706f2543Smrg * 1387706f2543Smrg * -- TSI @ UQV, 1998.08.21 1388706f2543Smrg */ 1389706f2543Smrg 1390706f2543SmrgCARD32 1391706f2543SmrgvgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 1392706f2543Smrg unsigned int Flags) 1393706f2543Smrg{ 1394706f2543Smrg int nExtBits = (nBits < 6) ? 0 : nBits - 6; 1395706f2543Smrg CARD32 ExtBits; 1396706f2543Smrg CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6; 1397706f2543Smrg 1398706f2543Smrg regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) 1399706f2543Smrg | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F); 1400706f2543Smrg regp->CRTC[5] = (regp->CRTC[5] & ~0x80) 1401706f2543Smrg | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2); 1402706f2543Smrg ExtBits = ((mode->CrtcHBlankEnd >> 3) - 1) & ExtBitMask; 1403706f2543Smrg 1404706f2543Smrg /* First the horizontal case */ 1405706f2543Smrg if ((Flags & KGA_FIX_OVERSCAN) 1406706f2543Smrg && ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3))) 1407706f2543Smrg { 1408706f2543Smrg int i = (regp->CRTC[3] & 0x1F) 1409706f2543Smrg | ((regp->CRTC[5] & 0x80) >> 2) 1410706f2543Smrg | ExtBits; 1411706f2543Smrg if (Flags & KGA_ENABLE_ON_ZERO) { 1412706f2543Smrg if ((i-- > (((mode->CrtcHBlankStart >> 3) - 1) 1413706f2543Smrg & (0x3F | ExtBitMask))) 1414706f2543Smrg && (mode->CrtcHBlankEnd == mode->CrtcHTotal)) 1415706f2543Smrg i = 0; 1416706f2543Smrg } else if (Flags & KGA_BE_TOT_DEC) 1417706f2543Smrg i--; 1418706f2543Smrg regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F); 1419706f2543Smrg regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80); 1420706f2543Smrg ExtBits = i & ExtBitMask; 1421706f2543Smrg } 1422706f2543Smrg return ExtBits >> 6; 1423706f2543Smrg} 1424706f2543Smrg 1425706f2543Smrg /* 1426706f2543Smrg * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of 1427706f2543Smrg * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the 1428706f2543Smrg * very first scanline in a double- or multi-scanned mode. This last case 1429706f2543Smrg * needs further investigation. 1430706f2543Smrg */ 1431706f2543SmrgCARD32 1432706f2543SmrgvgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 1433706f2543Smrg unsigned int Flags) 1434706f2543Smrg{ 1435706f2543Smrg CARD32 ExtBits; 1436706f2543Smrg CARD32 nExtBits = (nBits < 8) ? 0 : (nBits - 8); 1437706f2543Smrg CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 8; 1438706f2543Smrg /* If width is not known nBits should be 0. In this 1439706f2543Smrg * case BitMask is set to 0 so we can check for it. */ 1440706f2543Smrg CARD32 BitMask = (nBits < 7) ? 0 : ((1 << nExtBits) - 1); 1441706f2543Smrg int VBlankStart = (mode->CrtcVBlankStart - 1) & 0xFF; 1442706f2543Smrg regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; 1443706f2543Smrg ExtBits = (mode->CrtcVBlankEnd - 1) & ExtBitMask; 1444706f2543Smrg 1445706f2543Smrg if ((Flags & KGA_FIX_OVERSCAN) 1446706f2543Smrg && (mode->CrtcVBlankEnd == mode->CrtcVTotal)) 1447706f2543Smrg /* Null top overscan */ 1448706f2543Smrg { 1449706f2543Smrg int i = regp->CRTC[22] | ExtBits; 1450706f2543Smrg if (Flags & KGA_ENABLE_ON_ZERO) { 1451706f2543Smrg if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask))) 1452706f2543Smrg || ((i > VBlankStart) && /* 8-bit case */ 1453706f2543Smrg ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */ 1454706f2543Smrg !(regp->CRTC[9] & 0x9F)) /* 1 scanline/row */ 1455706f2543Smrg i = 0; 1456706f2543Smrg else 1457706f2543Smrg i = (i - 1); 1458706f2543Smrg } else if (Flags & KGA_BE_TOT_DEC) 1459706f2543Smrg i = (i - 1); 1460706f2543Smrg 1461706f2543Smrg regp->CRTC[22] = i & 0xFF; 1462706f2543Smrg ExtBits = i & 0xFF00; 1463706f2543Smrg } 1464706f2543Smrg return ExtBits >> 8; 1465706f2543Smrg} 1466706f2543Smrg 1467706f2543Smrg/* 1468706f2543Smrg * these are some more hardware specific helpers, formerly in vga.c 1469706f2543Smrg */ 1470706f2543Smrgstatic void 1471706f2543SmrgvgaHWGetHWRecPrivate(void) 1472706f2543Smrg{ 1473706f2543Smrg if (vgaHWPrivateIndex < 0) 1474706f2543Smrg vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); 1475706f2543Smrg return; 1476706f2543Smrg} 1477706f2543Smrg 1478706f2543Smrg 1479706f2543Smrgstatic void 1480706f2543SmrgvgaHWFreeRegs(vgaRegPtr regp) 1481706f2543Smrg{ 1482706f2543Smrg free(regp->CRTC); 1483706f2543Smrg 1484706f2543Smrg regp->CRTC = 1485706f2543Smrg regp->Sequencer = 1486706f2543Smrg regp->Graphics = 1487706f2543Smrg regp->Attribute = NULL; 1488706f2543Smrg 1489706f2543Smrg regp->numCRTC = 1490706f2543Smrg regp->numSequencer = 1491706f2543Smrg regp->numGraphics = 1492706f2543Smrg regp->numAttribute = 0; 1493706f2543Smrg} 1494706f2543Smrg 1495706f2543Smrg 1496706f2543Smrg 1497706f2543Smrgstatic Bool 1498706f2543SmrgvgaHWAllocRegs(vgaRegPtr regp) 1499706f2543Smrg{ 1500706f2543Smrg unsigned char *buf; 1501706f2543Smrg 1502706f2543Smrg if ((regp->numCRTC + regp->numSequencer + regp->numGraphics + 1503706f2543Smrg regp->numAttribute) == 0) 1504706f2543Smrg return FALSE; 1505706f2543Smrg 1506706f2543Smrg buf = calloc(regp->numCRTC + 1507706f2543Smrg regp->numSequencer + 1508706f2543Smrg regp->numGraphics + 1509706f2543Smrg regp->numAttribute, 1); 1510706f2543Smrg if (!buf) 1511706f2543Smrg return FALSE; 1512706f2543Smrg 1513706f2543Smrg regp->CRTC = buf; 1514706f2543Smrg regp->Sequencer = regp->CRTC + regp->numCRTC; 1515706f2543Smrg regp->Graphics = regp->Sequencer + regp->numSequencer; 1516706f2543Smrg regp->Attribute = regp->Graphics + regp->numGraphics; 1517706f2543Smrg 1518706f2543Smrg return TRUE; 1519706f2543Smrg} 1520706f2543Smrg 1521706f2543Smrg 1522706f2543SmrgBool 1523706f2543SmrgvgaHWAllocDefaultRegs(vgaRegPtr regp) 1524706f2543Smrg{ 1525706f2543Smrg regp->numCRTC = VGA_NUM_CRTC; 1526706f2543Smrg regp->numSequencer = VGA_NUM_SEQ; 1527706f2543Smrg regp->numGraphics = VGA_NUM_GFX; 1528706f2543Smrg regp->numAttribute = VGA_NUM_ATTR; 1529706f2543Smrg 1530706f2543Smrg return vgaHWAllocRegs(regp); 1531706f2543Smrg} 1532706f2543Smrg 1533706f2543Smrg 1534706f2543SmrgBool 1535706f2543SmrgvgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer, 1536706f2543Smrg int numGraphics, int numAttribute) 1537706f2543Smrg{ 1538706f2543Smrg#define VGAHWMINNUM(regtype) \ 1539706f2543Smrg ((newMode.num##regtype < regp->num##regtype) ? \ 1540706f2543Smrg (newMode.num##regtype) : (regp->num##regtype)) 1541706f2543Smrg#define VGAHWCOPYREGSET(regtype) \ 1542706f2543Smrg memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype)) 1543706f2543Smrg 1544706f2543Smrg vgaRegRec newMode, newSaved; 1545706f2543Smrg vgaRegPtr regp; 1546706f2543Smrg 1547706f2543Smrg regp = &VGAHWPTR(scrp)->ModeReg; 1548706f2543Smrg memcpy (&newMode, regp, sizeof(vgaRegRec)); 1549706f2543Smrg 1550706f2543Smrg /* allocate space for new registers */ 1551706f2543Smrg 1552706f2543Smrg regp = &newMode; 1553706f2543Smrg regp->numCRTC = numCRTC; 1554706f2543Smrg regp->numSequencer = numSequencer; 1555706f2543Smrg regp->numGraphics = numGraphics; 1556706f2543Smrg regp->numAttribute = numAttribute; 1557706f2543Smrg if (!vgaHWAllocRegs(regp)) 1558706f2543Smrg return FALSE; 1559706f2543Smrg 1560706f2543Smrg regp = &VGAHWPTR(scrp)->SavedReg; 1561706f2543Smrg memcpy (&newSaved, regp, sizeof(vgaRegRec)); 1562706f2543Smrg 1563706f2543Smrg regp = &newSaved; 1564706f2543Smrg regp->numCRTC = numCRTC; 1565706f2543Smrg regp->numSequencer = numSequencer; 1566706f2543Smrg regp->numGraphics = numGraphics; 1567706f2543Smrg regp->numAttribute = numAttribute; 1568706f2543Smrg if (!vgaHWAllocRegs(regp)) { 1569706f2543Smrg vgaHWFreeRegs(&newMode); 1570706f2543Smrg return FALSE; 1571706f2543Smrg } 1572706f2543Smrg 1573706f2543Smrg /* allocations succeeded, copy register data into new space */ 1574706f2543Smrg 1575706f2543Smrg regp = &VGAHWPTR(scrp)->ModeReg; 1576706f2543Smrg VGAHWCOPYREGSET(CRTC); 1577706f2543Smrg VGAHWCOPYREGSET(Sequencer); 1578706f2543Smrg VGAHWCOPYREGSET(Graphics); 1579706f2543Smrg VGAHWCOPYREGSET(Attribute); 1580706f2543Smrg 1581706f2543Smrg regp = &VGAHWPTR(scrp)->SavedReg; 1582706f2543Smrg VGAHWCOPYREGSET(CRTC); 1583706f2543Smrg VGAHWCOPYREGSET(Sequencer); 1584706f2543Smrg VGAHWCOPYREGSET(Graphics); 1585706f2543Smrg VGAHWCOPYREGSET(Attribute); 1586706f2543Smrg 1587706f2543Smrg /* free old register arrays */ 1588706f2543Smrg 1589706f2543Smrg regp = &VGAHWPTR(scrp)->ModeReg; 1590706f2543Smrg vgaHWFreeRegs(regp); 1591706f2543Smrg memcpy(regp, &newMode, sizeof(vgaRegRec)); 1592706f2543Smrg 1593706f2543Smrg regp = &VGAHWPTR(scrp)->SavedReg; 1594706f2543Smrg vgaHWFreeRegs(regp); 1595706f2543Smrg memcpy(regp, &newSaved, sizeof(vgaRegRec)); 1596706f2543Smrg 1597706f2543Smrg return TRUE; 1598706f2543Smrg 1599706f2543Smrg#undef VGAHWMINNUM 1600706f2543Smrg#undef VGAHWCOPYREGSET 1601706f2543Smrg} 1602706f2543Smrg 1603706f2543Smrg 1604706f2543SmrgBool 1605706f2543SmrgvgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src) 1606706f2543Smrg{ 1607706f2543Smrg vgaHWFreeRegs(dst); 1608706f2543Smrg 1609706f2543Smrg memcpy(dst, src, sizeof(vgaRegRec)); 1610706f2543Smrg 1611706f2543Smrg if (!vgaHWAllocRegs(dst)) 1612706f2543Smrg return FALSE; 1613706f2543Smrg 1614706f2543Smrg memcpy(dst->CRTC, src->CRTC, src->numCRTC); 1615706f2543Smrg memcpy(dst->Sequencer, src->Sequencer, src->numSequencer); 1616706f2543Smrg memcpy(dst->Graphics, src->Graphics, src->numGraphics); 1617706f2543Smrg memcpy(dst->Attribute, src->Attribute, src->numAttribute); 1618706f2543Smrg 1619706f2543Smrg return TRUE; 1620706f2543Smrg} 1621706f2543Smrg 1622706f2543Smrg 1623706f2543SmrgBool 1624706f2543SmrgvgaHWGetHWRec(ScrnInfoPtr scrp) 1625706f2543Smrg{ 1626706f2543Smrg vgaRegPtr regp; 1627706f2543Smrg vgaHWPtr hwp; 1628706f2543Smrg int i; 1629706f2543Smrg 1630706f2543Smrg /* 1631706f2543Smrg * Let's make sure that the private exists and allocate one. 1632706f2543Smrg */ 1633706f2543Smrg vgaHWGetHWRecPrivate(); 1634706f2543Smrg /* 1635706f2543Smrg * New privates are always set to NULL, so we can check if the allocation 1636706f2543Smrg * has already been done. 1637706f2543Smrg */ 1638706f2543Smrg if (VGAHWPTR(scrp)) 1639706f2543Smrg return TRUE; 1640706f2543Smrg hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1); 1641706f2543Smrg regp = &VGAHWPTR(scrp)->ModeReg; 1642706f2543Smrg 1643706f2543Smrg if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) || 1644706f2543Smrg (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) { 1645706f2543Smrg free(hwp); 1646706f2543Smrg return FALSE; 1647706f2543Smrg } 1648706f2543Smrg 1649706f2543Smrg if (scrp->bitsPerPixel == 1) { 1650706f2543Smrg rgb blackColour = scrp->display->blackColour, 1651706f2543Smrg whiteColour = scrp->display->whiteColour; 1652706f2543Smrg 1653706f2543Smrg if (blackColour.red > 0x3F) blackColour.red = 0x3F; 1654706f2543Smrg if (blackColour.green > 0x3F) blackColour.green = 0x3F; 1655706f2543Smrg if (blackColour.blue > 0x3F) blackColour.blue = 0x3F; 1656706f2543Smrg 1657706f2543Smrg if (whiteColour.red > 0x3F) whiteColour.red = 0x3F; 1658706f2543Smrg if (whiteColour.green > 0x3F) whiteColour.green = 0x3F; 1659706f2543Smrg if (whiteColour.blue > 0x3F) whiteColour.blue = 0x3F; 1660706f2543Smrg 1661706f2543Smrg if ((blackColour.red == whiteColour.red ) && 1662706f2543Smrg (blackColour.green == whiteColour.green) && 1663706f2543Smrg (blackColour.blue == whiteColour.blue )) { 1664706f2543Smrg blackColour.red ^= 0x3F; 1665706f2543Smrg blackColour.green ^= 0x3F; 1666706f2543Smrg blackColour.blue ^= 0x3F; 1667706f2543Smrg } 1668706f2543Smrg 1669706f2543Smrg /* 1670706f2543Smrg * initialize default colormap for monochrome 1671706f2543Smrg */ 1672706f2543Smrg for (i=0; i<3; i++) regp->DAC[i] = 0x00; 1673706f2543Smrg for (i=3; i<768; i++) regp->DAC[i] = 0x3F; 1674706f2543Smrg i = BLACK_VALUE * 3; 1675706f2543Smrg regp->DAC[i++] = blackColour.red; 1676706f2543Smrg regp->DAC[i++] = blackColour.green; 1677706f2543Smrg regp->DAC[i] = blackColour.blue; 1678706f2543Smrg i = WHITE_VALUE * 3; 1679706f2543Smrg regp->DAC[i++] = whiteColour.red; 1680706f2543Smrg regp->DAC[i++] = whiteColour.green; 1681706f2543Smrg regp->DAC[i] = whiteColour.blue; 1682706f2543Smrg i = OVERSCAN_VALUE * 3; 1683706f2543Smrg regp->DAC[i++] = 0x00; 1684706f2543Smrg regp->DAC[i++] = 0x00; 1685706f2543Smrg regp->DAC[i] = 0x00; 1686706f2543Smrg } else { 1687706f2543Smrg /* Set all colours to black */ 1688706f2543Smrg for (i=0; i<768; i++) regp->DAC[i] = 0x00; 1689706f2543Smrg /* ... and the overscan */ 1690706f2543Smrg if (scrp->depth >= 4) 1691706f2543Smrg regp->Attribute[OVERSCAN] = 0xFF; 1692706f2543Smrg } 1693706f2543Smrg if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) { 1694706f2543Smrg xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan"); 1695706f2543Smrg xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n"); 1696706f2543Smrg regp->DAC[765] = 0x3F; 1697706f2543Smrg regp->DAC[766] = 0x00; 1698706f2543Smrg regp->DAC[767] = 0x3F; 1699706f2543Smrg regp->Attribute[OVERSCAN] = 0xFF; 1700706f2543Smrg hwp->ShowOverscan = TRUE; 1701706f2543Smrg } else 1702706f2543Smrg hwp->ShowOverscan = FALSE; 1703706f2543Smrg 1704706f2543Smrg hwp->paletteEnabled = FALSE; 1705706f2543Smrg hwp->cmapSaved = FALSE; 1706706f2543Smrg hwp->MapSize = 0; 1707706f2543Smrg hwp->pScrn = scrp; 1708706f2543Smrg 1709706f2543Smrg /* Initialise the function pointers with the standard VGA versions */ 1710706f2543Smrg vgaHWSetStdFuncs(hwp); 1711706f2543Smrg 1712706f2543Smrg hwp->PIOOffset = scrp->domainIOBase; 1713706f2543Smrg hwp->dev = xf86GetPciInfoForEntity(scrp->entityList[0]); 1714706f2543Smrg 1715706f2543Smrg return TRUE; 1716706f2543Smrg} 1717706f2543Smrg 1718706f2543Smrg 1719706f2543Smrgvoid 1720706f2543SmrgvgaHWFreeHWRec(ScrnInfoPtr scrp) 1721706f2543Smrg{ 1722706f2543Smrg if (vgaHWPrivateIndex >= 0) { 1723706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrp); 1724706f2543Smrg 1725706f2543Smrg if (!hwp) 1726706f2543Smrg return; 1727706f2543Smrg 1728706f2543Smrg free(hwp->FontInfo1); 1729706f2543Smrg free(hwp->FontInfo2); 1730706f2543Smrg free(hwp->TextInfo); 1731706f2543Smrg 1732706f2543Smrg vgaHWFreeRegs (&hwp->ModeReg); 1733706f2543Smrg vgaHWFreeRegs (&hwp->SavedReg); 1734706f2543Smrg 1735706f2543Smrg free(hwp); 1736706f2543Smrg VGAHWPTRLVAL(scrp) = NULL; 1737706f2543Smrg } 1738706f2543Smrg} 1739706f2543Smrg 1740706f2543Smrg 1741706f2543SmrgBool 1742706f2543SmrgvgaHWMapMem(ScrnInfoPtr scrp) 1743706f2543Smrg{ 1744706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrp); 1745706f2543Smrg int scr_index = scrp->scrnIndex; 1746706f2543Smrg 1747706f2543Smrg if (hwp->Base) 1748706f2543Smrg return TRUE; 1749706f2543Smrg 1750706f2543Smrg /* If not set, initialise with the defaults */ 1751706f2543Smrg if (hwp->MapSize == 0) 1752706f2543Smrg hwp->MapSize = VGA_DEFAULT_MEM_SIZE; 1753706f2543Smrg if (hwp->MapPhys == 0) 1754706f2543Smrg hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR; 1755706f2543Smrg 1756706f2543Smrg /* 1757706f2543Smrg * Map as VIDMEM_MMIO_32BIT because WC 1758706f2543Smrg * is bad when there is page flipping. 1759706f2543Smrg * XXX This is not correct but we do it 1760706f2543Smrg * for now. 1761706f2543Smrg */ 1762706f2543Smrg DebugF("Mapping VGAMem\n"); 1763706f2543Smrg hwp->Base = xf86MapDomainMemory(scr_index, VIDMEM_MMIO_32BIT, hwp->dev, 1764706f2543Smrg hwp->MapPhys, hwp->MapSize); 1765706f2543Smrg return hwp->Base != NULL; 1766706f2543Smrg} 1767706f2543Smrg 1768706f2543Smrg 1769706f2543Smrgvoid 1770706f2543SmrgvgaHWUnmapMem(ScrnInfoPtr scrp) 1771706f2543Smrg{ 1772706f2543Smrg vgaHWPtr hwp = VGAHWPTR(scrp); 1773706f2543Smrg int scr_index = scrp->scrnIndex; 1774706f2543Smrg 1775706f2543Smrg if (hwp->Base == NULL) 1776706f2543Smrg return; 1777706f2543Smrg 1778706f2543Smrg DebugF("Unmapping VGAMem\n"); 1779706f2543Smrg xf86UnMapVidMem(scr_index, hwp->Base, hwp->MapSize); 1780706f2543Smrg hwp->Base = NULL; 1781706f2543Smrg} 1782706f2543Smrg 1783706f2543Smrgint 1784706f2543SmrgvgaHWGetIndex(void) 1785706f2543Smrg{ 1786706f2543Smrg return vgaHWPrivateIndex; 1787706f2543Smrg} 1788706f2543Smrg 1789706f2543Smrg 1790706f2543Smrgvoid 1791706f2543SmrgvgaHWGetIOBase(vgaHWPtr hwp) 1792706f2543Smrg{ 1793706f2543Smrg hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ? 1794706f2543Smrg VGA_IOBASE_COLOR : VGA_IOBASE_MONO; 1795706f2543Smrg xf86DrvMsgVerb(hwp->pScrn->scrnIndex, X_INFO, 3, 1796706f2543Smrg "vgaHWGetIOBase: hwp->IOBase is 0x%04x, hwp->PIOOffset is 0x%04lx\n", 1797706f2543Smrg hwp->IOBase, hwp->PIOOffset); 1798706f2543Smrg} 1799706f2543Smrg 1800706f2543Smrg 1801706f2543Smrgvoid 1802706f2543SmrgvgaHWLock(vgaHWPtr hwp) 1803706f2543Smrg{ 1804706f2543Smrg /* Protect CRTC[0-7] */ 1805706f2543Smrg hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80); 1806706f2543Smrg} 1807706f2543Smrg 1808706f2543Smrgvoid 1809706f2543SmrgvgaHWUnlock(vgaHWPtr hwp) 1810706f2543Smrg{ 1811706f2543Smrg /* Unprotect CRTC[0-7] */ 1812706f2543Smrg hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80); 1813706f2543Smrg} 1814706f2543Smrg 1815706f2543Smrg 1816706f2543Smrgvoid 1817706f2543SmrgvgaHWEnable(vgaHWPtr hwp) 1818706f2543Smrg{ 1819706f2543Smrg hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01); 1820706f2543Smrg} 1821706f2543Smrg 1822706f2543Smrg 1823706f2543Smrgvoid 1824706f2543SmrgvgaHWDisable(vgaHWPtr hwp) 1825706f2543Smrg{ 1826706f2543Smrg hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01); 1827706f2543Smrg} 1828706f2543Smrg 1829706f2543Smrg 1830706f2543Smrgstatic void 1831706f2543SmrgvgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, 1832706f2543Smrg VisualPtr pVisual) 1833706f2543Smrg{ 1834706f2543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1835706f2543Smrg int i, index; 1836706f2543Smrg 1837706f2543Smrg for (i = 0; i < numColors; i++) { 1838706f2543Smrg index = indices[i]; 1839706f2543Smrg hwp->writeDacWriteAddr(hwp, index); 1840706f2543Smrg DACDelay(hwp); 1841706f2543Smrg hwp->writeDacData(hwp, colors[index].red); 1842706f2543Smrg DACDelay(hwp); 1843706f2543Smrg hwp->writeDacData(hwp, colors[index].green); 1844706f2543Smrg DACDelay(hwp); 1845706f2543Smrg hwp->writeDacData(hwp, colors[index].blue); 1846706f2543Smrg DACDelay(hwp); 1847706f2543Smrg } 1848706f2543Smrg 1849706f2543Smrg /* This shouldn't be necessary, but we'll play safe. */ 1850706f2543Smrg hwp->disablePalette(hwp); 1851706f2543Smrg} 1852706f2543Smrg 1853706f2543Smrg 1854706f2543Smrgstatic void 1855706f2543SmrgvgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan) 1856706f2543Smrg{ 1857706f2543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1858706f2543Smrg 1859706f2543Smrg if (overscan < 0 || overscan > 255) 1860706f2543Smrg return; 1861706f2543Smrg 1862706f2543Smrg hwp->enablePalette(hwp); 1863706f2543Smrg hwp->writeAttr(hwp, OVERSCAN, overscan); 1864706f2543Smrg 1865706f2543Smrg#ifdef DEBUGOVERSCAN 1866706f2543Smrg { 1867706f2543Smrg int ov = hwp->readAttr(hwp, OVERSCAN); 1868706f2543Smrg int red, green, blue; 1869706f2543Smrg 1870706f2543Smrg hwp->writeDacReadAddr(hwp, ov); 1871706f2543Smrg red = hwp->readDacData(hwp); 1872706f2543Smrg green = hwp->readDacData(hwp); 1873706f2543Smrg blue = hwp->readDacData(hwp); 1874706f2543Smrg ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n", 1875706f2543Smrg ov, red, green, blue); 1876706f2543Smrg } 1877706f2543Smrg#endif 1878706f2543Smrg 1879706f2543Smrg hwp->disablePalette(hwp); 1880706f2543Smrg} 1881706f2543Smrg 1882706f2543Smrg 1883706f2543SmrgBool 1884706f2543SmrgvgaHWHandleColormaps(ScreenPtr pScreen) 1885706f2543Smrg{ 1886706f2543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1887706f2543Smrg 1888706f2543Smrg if (pScrn->depth > 1 && pScrn->depth <= 8) { 1889706f2543Smrg return xf86HandleColormaps(pScreen, 1 << pScrn->depth, 1890706f2543Smrg pScrn->rgbBits, vgaHWLoadPalette, 1891706f2543Smrg pScrn->depth > 4 ? vgaHWSetOverscan : NULL, 1892706f2543Smrg CMAP_RELOAD_ON_MODE_SWITCH); 1893706f2543Smrg } 1894706f2543Smrg return TRUE; 1895706f2543Smrg} 1896706f2543Smrg 1897706f2543Smrg/* ----------------------- DDC support ------------------------*/ 1898706f2543Smrg/* 1899706f2543Smrg * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total 1900706f2543Smrg * to read out EDID at a faster rate. Allowed maximum is 25kHz with 1901706f2543Smrg * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen 1902706f2543Smrg * readback, enable access to cr00-cr07. 1903706f2543Smrg */ 1904706f2543Smrg 1905706f2543Smrg/* vertical timings */ 1906706f2543Smrg#define DISPLAY_END 0x04 1907706f2543Smrg#define BLANK_START DISPLAY_END 1908706f2543Smrg#define SYNC_START BLANK_START 1909706f2543Smrg#define SYNC_END 0x09 1910706f2543Smrg#define BLANK_END SYNC_END 1911706f2543Smrg#define V_TOTAL BLANK_END 1912706f2543Smrg/* this function doesn't have to be reentrant for our purposes */ 1913706f2543Smrgstruct _vgaDdcSave { 1914706f2543Smrg unsigned char cr03; 1915706f2543Smrg unsigned char cr06; 1916706f2543Smrg unsigned char cr07; 1917706f2543Smrg unsigned char cr09; 1918706f2543Smrg unsigned char cr10; 1919706f2543Smrg unsigned char cr11; 1920706f2543Smrg unsigned char cr12; 1921706f2543Smrg unsigned char cr15; 1922706f2543Smrg unsigned char cr16; 1923706f2543Smrg unsigned char msr; 1924706f2543Smrg}; 1925706f2543Smrg 1926706f2543Smrgvoid 1927706f2543SmrgvgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed) 1928706f2543Smrg{ 1929706f2543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1930706f2543Smrg unsigned char tmp; 1931706f2543Smrg struct _vgaDdcSave* save; 1932706f2543Smrg switch (speed) { 1933706f2543Smrg case DDC_FAST: 1934706f2543Smrg 1935706f2543Smrg if (hwp->ddc != NULL) break; 1936706f2543Smrg hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave),1); 1937706f2543Smrg save = (struct _vgaDdcSave *)hwp->ddc; 1938706f2543Smrg /* Lightpen register disable - allow access to cr10 & 11; just in case */ 1939706f2543Smrg save->cr03 = hwp->readCrtc(hwp, 0x03); 1940706f2543Smrg hwp->writeCrtc(hwp,0x03,(save->cr03 |0x80)); 1941706f2543Smrg save->cr12 = hwp->readCrtc(hwp, 0x12); 1942706f2543Smrg hwp->writeCrtc(hwp,0x12,DISPLAY_END); 1943706f2543Smrg save->cr15 = hwp->readCrtc(hwp, 0x15); 1944706f2543Smrg hwp->writeCrtc(hwp,0x15,BLANK_START); 1945706f2543Smrg save->cr10 = hwp->readCrtc(hwp, 0x10); 1946706f2543Smrg hwp->writeCrtc(hwp,0x10,SYNC_START); 1947706f2543Smrg save->cr11 = hwp->readCrtc(hwp, 0x11); 1948706f2543Smrg /* unprotect group 1 registers; just in case ...*/ 1949706f2543Smrg hwp->writeCrtc(hwp,0x11,((save->cr11 & 0x70) | SYNC_END)); 1950706f2543Smrg save->cr16 = hwp->readCrtc(hwp, 0x16); 1951706f2543Smrg hwp->writeCrtc(hwp,0x16,BLANK_END); 1952706f2543Smrg save->cr06 = hwp->readCrtc(hwp, 0x06); 1953706f2543Smrg hwp->writeCrtc(hwp,0x06,V_TOTAL); 1954706f2543Smrg /* all values have less than 8 bit - mask out 9th and 10th bits */ 1955706f2543Smrg save->cr09 = hwp->readCrtc(hwp, 0x09); 1956706f2543Smrg hwp->writeCrtc(hwp,0x09,(save->cr09 &0xDF)); 1957706f2543Smrg save->cr07 = hwp->readCrtc(hwp, 0x07); 1958706f2543Smrg hwp->writeCrtc(hwp,0x07,(save->cr07 &0x10)); 1959706f2543Smrg /* vsync polarity negativ & ensure a 25MHz clock */ 1960706f2543Smrg save->msr = hwp->readMiscOut(hwp); 1961706f2543Smrg hwp->writeMiscOut(hwp,((save->msr & 0xF3) | 0x80)); 1962706f2543Smrg break; 1963706f2543Smrg case DDC_SLOW: 1964706f2543Smrg if (hwp->ddc == NULL) break; 1965706f2543Smrg save = (struct _vgaDdcSave *)hwp->ddc; 1966706f2543Smrg hwp->writeMiscOut(hwp,save->msr); 1967706f2543Smrg hwp->writeCrtc(hwp,0x07,save->cr07); 1968706f2543Smrg tmp = hwp->readCrtc(hwp, 0x09); 1969706f2543Smrg hwp->writeCrtc(hwp,0x09,((save->cr09 & 0x20) | (tmp & 0xDF))); 1970706f2543Smrg hwp->writeCrtc(hwp,0x06,save->cr06); 1971706f2543Smrg hwp->writeCrtc(hwp,0x16,save->cr16); 1972706f2543Smrg hwp->writeCrtc(hwp,0x11,save->cr11); 1973706f2543Smrg hwp->writeCrtc(hwp,0x10,save->cr10); 1974706f2543Smrg hwp->writeCrtc(hwp,0x15,save->cr15); 1975706f2543Smrg hwp->writeCrtc(hwp,0x12,save->cr12); 1976706f2543Smrg hwp->writeCrtc(hwp,0x03,save->cr03); 1977706f2543Smrg free(save); 1978706f2543Smrg hwp->ddc = NULL; 1979706f2543Smrg break; 1980706f2543Smrg default: 1981706f2543Smrg break; 1982706f2543Smrg } 1983706f2543Smrg} 1984706f2543Smrg 1985706f2543SmrgDDC1SetSpeedProc 1986706f2543SmrgvgaHWddc1SetSpeedWeak(void) 1987706f2543Smrg{ 1988706f2543Smrg return vgaHWddc1SetSpeed; 1989706f2543Smrg} 1990706f2543Smrg 1991706f2543SmrgSaveScreenProcPtr vgaHWSaveScreenWeak(void) 1992706f2543Smrg{ 1993706f2543Smrg return vgaHWSaveScreen; 1994706f2543Smrg} 1995