132b578d3Smrg/*
232b578d3Smrg * Copyright 2000 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#include "ati.h"
2832b578d3Smrg#include "atichip.h"
2932b578d3Smrg#include "atimach64io.h"
3032b578d3Smrg
3132b578d3Smrg/*
3232b578d3Smrg * ATIMach64AccessPLLReg --
3332b578d3Smrg *
3432b578d3Smrg * This function sets up the addressing required to access, for read or write,
3532b578d3Smrg * a 264xT's PLL registers.
3632b578d3Smrg */
3732b578d3Smrgvoid
3832b578d3SmrgATIMach64AccessPLLReg
3932b578d3Smrg(
4032b578d3Smrg    ATIPtr      pATI,
4132b578d3Smrg    const CARD8 Index,
4232b578d3Smrg    const Bool  Write
4332b578d3Smrg)
4432b578d3Smrg{
4532b578d3Smrg    CARD8 clock_cntl1 = in8(CLOCK_CNTL + 1) &
4632b578d3Smrg        ~GetByte(PLL_WR_EN | PLL_ADDR, 1);
4732b578d3Smrg
4832b578d3Smrg    /* Set PLL register to be read or written */
4932b578d3Smrg    out8(CLOCK_CNTL + 1, clock_cntl1 |
5032b578d3Smrg        GetByte(SetBits(Index, PLL_ADDR) | SetBits(Write, PLL_WR_EN), 1));
5132b578d3Smrg}
5232b578d3Smrg
5332b578d3Smrg/*
5432b578d3Smrg * ATIMach64PollEngineStatus --
5532b578d3Smrg *
5632b578d3Smrg * This function refreshes the driver's view of the draw engine's status.  This
5732b578d3Smrg * has been moved into a separate compilation unit to prevent inlining.
5832b578d3Smrg */
5932b578d3Smrgvoid
6032b578d3SmrgATIMach64PollEngineStatus
6132b578d3Smrg(
6232b578d3Smrg    ATIPtr pATI
6332b578d3Smrg)
6432b578d3Smrg{
6532b578d3Smrg    CARD32 IOValue;
6632b578d3Smrg    int    Count;
6732b578d3Smrg
6832b578d3Smrg    if (pATI->Chip < ATI_CHIP_264VTB)
6932b578d3Smrg    {
7032b578d3Smrg        /*
7132b578d3Smrg         * TODO:  Deal with locked engines.
7232b578d3Smrg         */
7332b578d3Smrg        IOValue = inm(FIFO_STAT);
7432b578d3Smrg        pATI->EngineIsLocked = GetBits(IOValue, FIFO_ERR);
7532b578d3Smrg
7632b578d3Smrg        /*
7732b578d3Smrg         * The following counts the number of bits in FIFO_STAT_BITS, and is
7832b578d3Smrg         * derived from miSetVisualTypes().
7932b578d3Smrg         */
8032b578d3Smrg        IOValue = GetBits(IOValue, FIFO_STAT_BITS);
8132b578d3Smrg        Count = (IOValue >> 1) & 0x36DBU;
8232b578d3Smrg        Count = IOValue - Count - ((Count >> 1) & 0x36DBU);
8332b578d3Smrg        Count = ((Count + (Count >> 3)) & 0x71C7U) % 0x3FU;
8432b578d3Smrg        Count = pATI->nFIFOEntries - Count;
8532b578d3Smrg        if (Count > pATI->nAvailableFIFOEntries)
8632b578d3Smrg            pATI->nAvailableFIFOEntries = Count;
8732b578d3Smrg
8832b578d3Smrg        /*
8932b578d3Smrg         * If the command FIFO is non-empty, then the engine isn't idle.
9032b578d3Smrg         */
9132b578d3Smrg        if (pATI->nAvailableFIFOEntries < pATI->nFIFOEntries)
9232b578d3Smrg        {
9332b578d3Smrg            pATI->EngineIsBusy = TRUE;
9432b578d3Smrg            return;
9532b578d3Smrg        }
9632b578d3Smrg    }
9732b578d3Smrg
9832b578d3Smrg    IOValue = inm(GUI_STAT);
9932b578d3Smrg    pATI->EngineIsBusy = GetBits(IOValue, GUI_ACTIVE);
10032b578d3Smrg    Count = GetBits(IOValue, GUI_FIFO);
10132b578d3Smrg    if (Count > pATI->nAvailableFIFOEntries)
10232b578d3Smrg        pATI->nAvailableFIFOEntries = Count;
10332b578d3Smrg}
104