tvga_dac.c revision 95b296d0
1/* 2 * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Alan Hourihane not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Alan Hourihane makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 23 */ 24/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tvga_dac.c,v 1.7tsi Exp $ */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "xf86.h" 31#include "xf86_OSproc.h" 32#include "xf86Version.h" 33#include "xf86PciInfo.h" 34#include "xf86Pci.h" 35 36#include "vgaHW.h" 37 38#include "trident.h" 39#include "trident_regs.h" 40 41Bool 42TVGAInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 43{ 44 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 45 TRIDENTRegPtr pReg = &pTrident->ModeReg; 46 int vgaIOBase; 47 int offset = 0; 48 int clock = mode->Clock; 49 vgaIOBase = VGAHWPTR(pScrn)->IOBase; 50 51 OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */ 52 53 pReg->tridentRegsDAC[0x00] = 0x00; 54 OUTB(0x3C4, ConfPort2); 55 pReg->tridentRegs3C4[ConfPort2] = INB(0x3C5); 56 OUTB(0x3CE, MiscExtFunc); 57 pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0; 58 OUTB(vgaIOBase + 4, FIFOControl); 59 pReg->tridentRegs3x4[FIFOControl] = INB(vgaIOBase + 5) | 0x24; 60 61 /* YUK ! here we have to mess with old mode operation */ 62 OUTB(0x3C4, 0x0B); OUTB(0x3C5, 0x00); /* Goto Old Mode */ 63 OUTB(0x3C4, OldMode2 + NewMode2); 64 pReg->tridentRegs3C4[OldMode2] = 0x10; 65 OUTB(0x3C4, 0x0B); INB(0x3C5); /* Back to New Mode */ 66 pReg->tridentRegs3x4[Underline] = 0x40; 67 if (pTrident->Chipset < TGUI9440AGi) 68 pReg->tridentRegs3x4[CRTCMode] = 0xA3; 69 70 if (pScrn->videoRam > 512) 71 pReg->tridentRegs3C4[ConfPort2] |= 0x20; 72 else 73 pReg->tridentRegs3C4[ConfPort2] &= 0xDF; 74 75 switch (pScrn->bitsPerPixel) { 76 case 8: 77 if (pScrn->videoRam < 1024) 78 offset = pScrn->displayWidth >> 3; 79 else 80 offset = pScrn->displayWidth >> 4; 81 pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 82 break; 83 case 16: 84 pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 85 offset = pScrn->displayWidth >> 3; 86 /* Reload with any chipset specific stuff here */ 87 if (pTrident->Chipset == TVGA8900D) { 88 if (pScrn->depth == 15) 89 pReg->tridentRegsDAC[0x00] = 0xA0; 90 else 91 pReg->tridentRegsDAC[0x00] = 0xE0; 92 pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Div by 2*/ 93 clock *= 2; /* Double the clock */ 94 } 95 break; 96 case 24: 97 pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 98 offset = (pScrn->displayWidth * 3) >> 3; 99 pReg->tridentRegsDAC[0x00] = 0xD0; 100 break; 101 case 32: 102 pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 103 pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Division by 2*/ 104 clock *= 2; /* Double the clock */ 105 offset = pScrn->displayWidth >> 1; 106 pReg->tridentRegsDAC[0x00] = 0x42; 107 break; 108 } 109 pReg->tridentRegs3x4[Offset] = offset & 0xFF; 110 111 pReg->tridentRegsClock[0x00] = mode->ClockIndex; 112 113 pReg->tridentRegs3C4[NewMode1] = 0x80; 114 115 if (pTrident->Linear) 116 pReg->tridentRegs3x4[LinearAddReg] = ((pTrident->FbAddress >> 24) << 6)| 117 ((pTrident->FbAddress >> 20) & 0x0F)| 118 0x20; 119 else { 120 pReg->tridentRegs3CE[MiscExtFunc] |= 0x04; 121 pReg->tridentRegs3x4[LinearAddReg] = 0; 122 } 123 124 pReg->tridentRegs3x4[CRTCModuleTest] = 125 (mode->Flags & V_INTERLACE ? 0x84 : 0x80); 126 OUTB(vgaIOBase+ 4, AddColReg); 127 pReg->tridentRegs3x4[AddColReg] = (INB(vgaIOBase + 5) & 0xCF) | 128 ((offset & 0x100) >> 4); 129 130 return(TRUE); 131} 132 133void 134TVGARestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) 135{ 136 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 137 int vgaIOBase; 138 vgaIOBase = VGAHWPTR(pScrn)->IOBase; 139 140 /* Goto Old Mode */ 141 OUTB(0x3C4, 0x0B); 142 OUTB(0x3C5, 0x00); 143 OUTB(0x3C4, OldMode2 + NewMode2); 144 OUTB(0x3C5, tridentReg->tridentRegs3C4[OldMode2]); 145 146 /* Goto New Mode */ 147 OUTB(0x3C4, 0x0B); 148 (void) INB(0x3C5); 149 150 /* Unprotect registers */ 151 OUTW(0x3C4, (0x80 << 8) | NewMode1); 152 153 (void) INB(0x3C8); 154 (void) INB(0x3C6); 155 (void) INB(0x3C6); 156 (void) INB(0x3C6); 157 (void) INB(0x3C6); 158 OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]); 159 (void) INB(0x3C8); 160 161 OUTW_3x4(CRTCModuleTest); 162 OUTW_3x4(LinearAddReg); 163 OUTW_3x4(FIFOControl); 164 OUTW_3C4(ConfPort2); 165 OUTW_3x4(Underline); 166 if (pTrident->Chipset < TGUI9440AGi) 167 OUTW_3x4(CRTCMode); 168 OUTW_3x4(AddColReg); 169 OUTW_3CE(MiscExtFunc); 170 OUTW_3x4(Offset); 171 172 TRIDENTClockSelect(pScrn, tridentReg->tridentRegsClock[0x00]); 173 174 OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1]) << 8)| NewMode1); 175} 176 177void 178TVGASave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) 179{ 180 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 181 int vgaIOBase; 182 vgaIOBase = VGAHWPTR(pScrn)->IOBase; 183 184 (void) INB(0x3C8); 185 (void) INB(0x3C6); 186 (void) INB(0x3C6); 187 (void) INB(0x3C6); 188 (void) INB(0x3C6); 189 tridentReg->tridentRegsDAC[0x00] = INB(0x3C6); 190 (void) INB(0x3C8); 191 192 /* Goto Old Mode */ 193 OUTB(0x3C4, 0x0B); 194 OUTB(0x3C5, 0x00); 195 OUTB(0x3C4, OldMode2 + NewMode2); 196 tridentReg->tridentRegs3C4[OldMode2] = INB(0x3C5); 197 198 /* Goto New Mode */ 199 OUTB(0x3C4, 0x0B); 200 (void) INB(0x3C5); 201 202 INB_3C4(NewMode1); 203 204 /* Unprotect registers */ 205 OUTW(0x3C4, ((0x80 ^ 0x02) << 8) | NewMode1); 206 OUTW(vgaIOBase + 4, (0x92 << 8) | NewMode1); 207 208 INB_3x4(Underline); 209 if (pTrident->Chipset < TGUI9440AGi) 210 INB_3x4(CRTCMode); 211 INB_3x4(LinearAddReg); 212 INB_3x4(FIFOControl); 213 INB_3x4(CRTCModuleTest); 214 INB_3x4(AddColReg); 215 INB_3CE(MiscExtFunc); 216 INB_3C4(ConfPort2); 217 218 TRIDENTClockSelect(pScrn, CLK_REG_SAVE); 219 220 /* Protect registers */ 221 OUTW_3C4(NewMode1); 222} 223