atiwonder.c revision 32b578d3
1/* 2 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 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 copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of Marc Aurele La France not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. Marc Aurele La France 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 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 16 * EVENT SHALL MARC AURELE LA FRANCE 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 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27/* 28 * The ATI x8800 chips use special registers for their extended VGA features. 29 * These registers are accessible through an index I/O port and a data I/O 30 * port. BIOS initialisation stores the index port number in the Graphics 31 * register bank (0x03CE), indices 0x50 and 0x51. Unfortunately, for all but 32 * the 18800-x series of adapters, these registers are write-only (a.k.a. black 33 * holes). On all but 88800's, the index port number can be found in the short 34 * integer at offset 0x10 in the BIOS. For 88800's, this driver will use 35 * 0x01CE or 0x03CE as the index port number, depending on the I/O port 36 * decoding used. The data port number is one more than the index port number 37 * (i.e. 0x01CF). These ports differ slightly in their I/O behaviour from the 38 * normal VGA ones: 39 * 40 * write: outw(0x01CE, (data << 8) | index); (16-bit, not used) 41 * outb(0x01CE, index); outb(0x01CF, data); (8-bit) 42 * read: outb(0x01CE, index); data = inb(0x01CF); 43 * 44 * Two consecutive byte-writes to the data port will not work. Furthermore an 45 * index written to 0x01CE is usable only once. Note also that the setting of 46 * ATI extended registers (especially those with clock selection bits) should 47 * be bracketed by a sequencer reset. 48 * 49 * The number of these extended VGA registers varies by chipset. The 18800 50 * series have 16, the 28800 series have 32, while 68800's and 88800's have 64. 51 * The last 16 on each have almost identical definitions. Thus, the BIOS sets 52 * up an indexing scheme whereby the last 16 extended VGA registers are 53 * accessed at indices 0xB0 through 0xBF on all chipsets. 54 */ 55 56#include "ati.h" 57#include "atichip.h" 58#include "atiwonder.h" 59#include "atiwonderio.h" 60 61#ifndef AVOID_CPIO 62 63/* 64 * ATIVGAWonderPreInit -- 65 * 66 * This function is called to initialise the VGA Wonder part of an ATIHWRec 67 * that is common to all modes generated by the driver. 68 */ 69void 70ATIVGAWonderPreInit 71( 72 ATIPtr pATI, 73 ATIHWPtr pATIHW 74) 75{ 76 pATIHW->b3 = ATIGetExtReg(0xB3U) & 0x20U; 77 pATIHW->b6 = 0x04U; 78 pATIHW->b6 |= 0x01U; 79 pATIHW->bf = ATIGetExtReg(0xBFU) & 0x5FU; 80 pATIHW->a3 = ATIGetExtReg(0xA3U) & 0x67U; 81 pATIHW->ab = ATIGetExtReg(0xABU) & 0xE7U; 82 pATIHW->ae = ATIGetExtReg(0xAEU) & 0xE0U; 83} 84 85/* 86 * ATIVGAWonderSave -- 87 * 88 * This function is called to save the VGA Wonder portion of the current video 89 * state. 90 */ 91void 92ATIVGAWonderSave 93( 94 ATIPtr pATI, 95 ATIHWPtr pATIHW 96) 97{ 98 pATIHW->b0 = ATIGetExtReg(0xB0U); 99 pATIHW->b1 = ATIGetExtReg(0xB1U); 100 pATIHW->b2 = ATIGetExtReg(0xB2U); 101 pATIHW->b3 = ATIGetExtReg(0xB3U); 102 pATIHW->b5 = ATIGetExtReg(0xB5U); 103 pATIHW->b6 = ATIGetExtReg(0xB6U); 104 pATIHW->b8 = ATIGetExtReg(0xB8U); 105 pATIHW->b9 = ATIGetExtReg(0xB9U); 106 pATIHW->ba = ATIGetExtReg(0xBAU); 107 pATIHW->bd = ATIGetExtReg(0xBDU); 108 { 109 pATIHW->be = ATIGetExtReg(0xBEU); 110 { 111 pATIHW->bf = ATIGetExtReg(0xBFU); 112 pATIHW->a3 = ATIGetExtReg(0xA3U); 113 pATIHW->a6 = ATIGetExtReg(0xA6U); 114 pATIHW->a7 = ATIGetExtReg(0xA7U); 115 pATIHW->ab = ATIGetExtReg(0xABU); 116 pATIHW->ac = ATIGetExtReg(0xACU); 117 pATIHW->ad = ATIGetExtReg(0xADU); 118 pATIHW->ae = ATIGetExtReg(0xAEU); 119 } 120 } 121} 122 123/* 124 * ATIVGAWonderSet -- 125 * 126 * This function loads the VGA Wonder portion of a video state. 127 */ 128void 129ATIVGAWonderSet 130( 131 ATIPtr pATI, 132 ATIHWPtr pATIHW 133) 134{ 135 { 136 ATIModifyExtReg(pATI, 0xBEU, -1, 0x00U, pATIHW->be); 137 { 138 ATIModifyExtReg(pATI, 0xBFU, -1, 0x00U, pATIHW->bf); 139 ATIModifyExtReg(pATI, 0xA3U, -1, 0x00U, pATIHW->a3); 140 ATIModifyExtReg(pATI, 0xA6U, -1, 0x00U, pATIHW->a6); 141 ATIModifyExtReg(pATI, 0xA7U, -1, 0x00U, pATIHW->a7); 142 ATIModifyExtReg(pATI, 0xABU, -1, 0x00U, pATIHW->ab); 143 ATIModifyExtReg(pATI, 0xACU, -1, 0x00U, pATIHW->ac); 144 ATIModifyExtReg(pATI, 0xADU, -1, 0x00U, pATIHW->ad); 145 ATIModifyExtReg(pATI, 0xAEU, -1, 0x00U, pATIHW->ae); 146 } 147 } 148 ATIModifyExtReg(pATI, 0xB0U, -1, 0x00U, pATIHW->b0); 149 ATIModifyExtReg(pATI, 0xB1U, -1, 0x00U, pATIHW->b1); 150 ATIModifyExtReg(pATI, 0xB3U, -1, 0x00U, pATIHW->b3); 151 ATIModifyExtReg(pATI, 0xB5U, -1, 0x00U, pATIHW->b5); 152 ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6); 153 ATIModifyExtReg(pATI, 0xB8U, -1, 0x00U, pATIHW->b8); 154 ATIModifyExtReg(pATI, 0xB9U, -1, 0x00U, pATIHW->b9); 155 ATIModifyExtReg(pATI, 0xBAU, -1, 0x00U, pATIHW->ba); 156 ATIModifyExtReg(pATI, 0xBDU, -1, 0x00U, pATIHW->bd); 157} 158 159#endif /* AVOID_CPIO */ 160