132b578d3Smrg/*
232b578d3Smrg * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
332b578d3Smrg *
432b578d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its
532b578d3Smrg * documentation for any purpose is hereby granted without fee, provided that
632b578d3Smrg * the above copyright notice appear in all copies and that both that copyright
732b578d3Smrg * notice and this permission notice appear in supporting documentation, and
832b578d3Smrg * that the name of Marc Aurele La France not be used in advertising or
932b578d3Smrg * publicity pertaining to distribution of the software without specific,
1032b578d3Smrg * written prior permission.  Marc Aurele La France makes no representations
1132b578d3Smrg * about the suitability of this software for any purpose.  It is provided
1232b578d3Smrg * "as-is" without express or implied warranty.
1332b578d3Smrg *
1432b578d3Smrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1532b578d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
1632b578d3Smrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1732b578d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1832b578d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1932b578d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2032b578d3Smrg * PERFORMANCE OF THIS SOFTWARE.
2132b578d3Smrg */
2232b578d3Smrg
2332b578d3Smrg#ifdef HAVE_CONFIG_H
2432b578d3Smrg#include "config.h"
2532b578d3Smrg#endif
2632b578d3Smrg
2732b578d3Smrg/*
2832b578d3Smrg * The ATI x8800 chips use special registers for their extended VGA features.
2932b578d3Smrg * These registers are accessible through an index I/O port and a data I/O
3032b578d3Smrg * port.  BIOS initialisation stores the index port number in the Graphics
3132b578d3Smrg * register bank (0x03CE), indices 0x50 and 0x51.  Unfortunately, for all but
3232b578d3Smrg * the 18800-x series of adapters, these registers are write-only (a.k.a. black
3332b578d3Smrg * holes).  On all but 88800's, the index port number can be found in the short
3432b578d3Smrg * integer at offset 0x10 in the BIOS.  For 88800's, this driver will use
3532b578d3Smrg * 0x01CE or 0x03CE as the index port number, depending on the I/O port
3632b578d3Smrg * decoding used.  The data port number is one more than the index port number
3732b578d3Smrg * (i.e. 0x01CF).  These ports differ slightly in their I/O behaviour from the
3832b578d3Smrg * normal VGA ones:
3932b578d3Smrg *
4032b578d3Smrg *    write:  outw(0x01CE, (data << 8) | index);        (16-bit, not used)
4132b578d3Smrg *            outb(0x01CE, index);  outb(0x01CF, data); (8-bit)
4232b578d3Smrg *    read:   outb(0x01CE, index);  data = inb(0x01CF);
4332b578d3Smrg *
4432b578d3Smrg * Two consecutive byte-writes to the data port will not work.  Furthermore an
4532b578d3Smrg * index written to 0x01CE is usable only once.  Note also that the setting of
4632b578d3Smrg * ATI extended registers (especially those with clock selection bits) should
4732b578d3Smrg * be bracketed by a sequencer reset.
4832b578d3Smrg *
4932b578d3Smrg * The number of these extended VGA registers varies by chipset.  The 18800
5032b578d3Smrg * series have 16, the 28800 series have 32, while 68800's and 88800's have 64.
5132b578d3Smrg * The last 16 on each have almost identical definitions.  Thus, the BIOS sets
5232b578d3Smrg * up an indexing scheme whereby the last 16 extended VGA registers are
5332b578d3Smrg * accessed at indices 0xB0 through 0xBF on all chipsets.
5432b578d3Smrg */
5532b578d3Smrg
5632b578d3Smrg#include "ati.h"
5732b578d3Smrg#include "atichip.h"
5832b578d3Smrg#include "atiwonder.h"
5932b578d3Smrg#include "atiwonderio.h"
6032b578d3Smrg
6132b578d3Smrg#ifndef AVOID_CPIO
6232b578d3Smrg
6332b578d3Smrg/*
6432b578d3Smrg * ATIVGAWonderPreInit --
6532b578d3Smrg *
6632b578d3Smrg * This function is called to initialise the VGA Wonder part of an ATIHWRec
6732b578d3Smrg * that is common to all modes generated by the driver.
6832b578d3Smrg */
6932b578d3Smrgvoid
7032b578d3SmrgATIVGAWonderPreInit
7132b578d3Smrg(
7232b578d3Smrg    ATIPtr      pATI,
7332b578d3Smrg    ATIHWPtr    pATIHW
7432b578d3Smrg)
7532b578d3Smrg{
7632b578d3Smrg    pATIHW->b3 = ATIGetExtReg(0xB3U) & 0x20U;
7732b578d3Smrg        pATIHW->b6 = 0x04U;
7832b578d3Smrg        pATIHW->b6 |= 0x01U;
7932b578d3Smrg        pATIHW->bf = ATIGetExtReg(0xBFU) & 0x5FU;
8032b578d3Smrg        pATIHW->a3 = ATIGetExtReg(0xA3U) & 0x67U;
8132b578d3Smrg        pATIHW->ab = ATIGetExtReg(0xABU) & 0xE7U;
8232b578d3Smrg        pATIHW->ae = ATIGetExtReg(0xAEU) & 0xE0U;
8332b578d3Smrg}
8432b578d3Smrg
8532b578d3Smrg/*
8632b578d3Smrg * ATIVGAWonderSave --
8732b578d3Smrg *
8832b578d3Smrg * This function is called to save the VGA Wonder portion of the current video
8932b578d3Smrg * state.
9032b578d3Smrg */
9132b578d3Smrgvoid
9232b578d3SmrgATIVGAWonderSave
9332b578d3Smrg(
9432b578d3Smrg    ATIPtr      pATI,
9532b578d3Smrg    ATIHWPtr    pATIHW
9632b578d3Smrg)
9732b578d3Smrg{
9832b578d3Smrg    pATIHW->b0 = ATIGetExtReg(0xB0U);
9932b578d3Smrg    pATIHW->b1 = ATIGetExtReg(0xB1U);
10032b578d3Smrg    pATIHW->b2 = ATIGetExtReg(0xB2U);
10132b578d3Smrg    pATIHW->b3 = ATIGetExtReg(0xB3U);
10232b578d3Smrg    pATIHW->b5 = ATIGetExtReg(0xB5U);
10332b578d3Smrg    pATIHW->b6 = ATIGetExtReg(0xB6U);
10432b578d3Smrg    pATIHW->b8 = ATIGetExtReg(0xB8U);
10532b578d3Smrg    pATIHW->b9 = ATIGetExtReg(0xB9U);
10632b578d3Smrg    pATIHW->ba = ATIGetExtReg(0xBAU);
10732b578d3Smrg    pATIHW->bd = ATIGetExtReg(0xBDU);
10832b578d3Smrg    {
10932b578d3Smrg        pATIHW->be = ATIGetExtReg(0xBEU);
11032b578d3Smrg        {
11132b578d3Smrg            pATIHW->bf = ATIGetExtReg(0xBFU);
11232b578d3Smrg            pATIHW->a3 = ATIGetExtReg(0xA3U);
11332b578d3Smrg            pATIHW->a6 = ATIGetExtReg(0xA6U);
11432b578d3Smrg            pATIHW->a7 = ATIGetExtReg(0xA7U);
11532b578d3Smrg            pATIHW->ab = ATIGetExtReg(0xABU);
11632b578d3Smrg            pATIHW->ac = ATIGetExtReg(0xACU);
11732b578d3Smrg            pATIHW->ad = ATIGetExtReg(0xADU);
11832b578d3Smrg            pATIHW->ae = ATIGetExtReg(0xAEU);
11932b578d3Smrg        }
12032b578d3Smrg    }
12132b578d3Smrg}
12232b578d3Smrg
12332b578d3Smrg/*
12432b578d3Smrg * ATIVGAWonderSet --
12532b578d3Smrg *
12632b578d3Smrg * This function loads the VGA Wonder portion of a video state.
12732b578d3Smrg */
12832b578d3Smrgvoid
12932b578d3SmrgATIVGAWonderSet
13032b578d3Smrg(
13132b578d3Smrg    ATIPtr      pATI,
13232b578d3Smrg    ATIHWPtr    pATIHW
13332b578d3Smrg)
13432b578d3Smrg{
13532b578d3Smrg    {
13632b578d3Smrg        ATIModifyExtReg(pATI, 0xBEU, -1, 0x00U, pATIHW->be);
13732b578d3Smrg        {
13832b578d3Smrg            ATIModifyExtReg(pATI, 0xBFU, -1, 0x00U, pATIHW->bf);
13932b578d3Smrg            ATIModifyExtReg(pATI, 0xA3U, -1, 0x00U, pATIHW->a3);
14032b578d3Smrg            ATIModifyExtReg(pATI, 0xA6U, -1, 0x00U, pATIHW->a6);
14132b578d3Smrg            ATIModifyExtReg(pATI, 0xA7U, -1, 0x00U, pATIHW->a7);
14232b578d3Smrg            ATIModifyExtReg(pATI, 0xABU, -1, 0x00U, pATIHW->ab);
14332b578d3Smrg            ATIModifyExtReg(pATI, 0xACU, -1, 0x00U, pATIHW->ac);
14432b578d3Smrg            ATIModifyExtReg(pATI, 0xADU, -1, 0x00U, pATIHW->ad);
14532b578d3Smrg            ATIModifyExtReg(pATI, 0xAEU, -1, 0x00U, pATIHW->ae);
14632b578d3Smrg        }
14732b578d3Smrg    }
14832b578d3Smrg    ATIModifyExtReg(pATI, 0xB0U, -1, 0x00U, pATIHW->b0);
14932b578d3Smrg    ATIModifyExtReg(pATI, 0xB1U, -1, 0x00U, pATIHW->b1);
15032b578d3Smrg    ATIModifyExtReg(pATI, 0xB3U, -1, 0x00U, pATIHW->b3);
15132b578d3Smrg    ATIModifyExtReg(pATI, 0xB5U, -1, 0x00U, pATIHW->b5);
15232b578d3Smrg    ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6);
15332b578d3Smrg    ATIModifyExtReg(pATI, 0xB8U, -1, 0x00U, pATIHW->b8);
15432b578d3Smrg    ATIModifyExtReg(pATI, 0xB9U, -1, 0x00U, pATIHW->b9);
15532b578d3Smrg    ATIModifyExtReg(pATI, 0xBAU, -1, 0x00U, pATIHW->ba);
15632b578d3Smrg    ATIModifyExtReg(pATI, 0xBDU, -1, 0x00U, pATIHW->bd);
15732b578d3Smrg}
15832b578d3Smrg
15932b578d3Smrg#endif /* AVOID_CPIO */
160