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 * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas.
2432b578d3Smrg * All Rights Reserved.
2532b578d3Smrg *
2632b578d3Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
2732b578d3Smrg * of this software and associated documentation files (the "Software"), to
2832b578d3Smrg * deal in the Software without restriction, including without limitation the
2932b578d3Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
3032b578d3Smrg * sell copies of the Software, and to permit persons to whom the Software is
3132b578d3Smrg * furnished to do so, subject to the following conditions:
3232b578d3Smrg *
3332b578d3Smrg * The above copyright notice and this permission notice (including the next
3432b578d3Smrg * paragraph) shall be included in all copies or substantial portions of the
3532b578d3Smrg * Software.
3632b578d3Smrg *
3732b578d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3832b578d3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3932b578d3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
4032b578d3Smrg * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
4132b578d3Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
4232b578d3Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
4332b578d3Smrg * DEALINGS IN THE SOFTWARE.
4432b578d3Smrg */
4532b578d3Smrg/*
4632b578d3Smrg * DRI support by:
4732b578d3Smrg *    Manuel Teira
4832b578d3Smrg *    Leif Delgass <ldelgass@retinalburn.net>
4932b578d3Smrg */
5032b578d3Smrg
5132b578d3Smrg#ifdef HAVE_CONFIG_H
5232b578d3Smrg#include "config.h"
5332b578d3Smrg#endif
5432b578d3Smrg
5532b578d3Smrg#include <string.h>
5632b578d3Smrg
5732b578d3Smrg#include "ati.h"
5832b578d3Smrg#include "atibus.h"
5932b578d3Smrg#include "atichip.h"
6032b578d3Smrg#include "atidac.h"
6132b578d3Smrg#include "atimach64.h"
6232b578d3Smrg#include "atimach64accel.h"
6332b578d3Smrg#include "atimach64io.h"
6432b578d3Smrg#include "atirgb514.h"
6532b578d3Smrg
662a51b5beSmrg#ifdef HAVE_XEXTPROTO_71
672a51b5beSmrg#include <X11/extensions/dpmsconst.h>
682a51b5beSmrg#else
6932b578d3Smrg#ifndef DPMS_SERVER
7032b578d3Smrg# define DPMS_SERVER
7132b578d3Smrg#endif
7232b578d3Smrg#include <X11/extensions/dpms.h>
732a51b5beSmrg#endif
742a51b5beSmrg
7532b578d3Smrg
7632b578d3Smrg/*
7732b578d3Smrg * ATIMach64PreInit --
7832b578d3Smrg *
7932b578d3Smrg * This function fills in the Mach64 portion of an ATIHWRec that is common to
8032b578d3Smrg * all video modes generated by the driver.
8132b578d3Smrg */
8232b578d3Smrgvoid
8332b578d3SmrgATIMach64PreInit
8432b578d3Smrg(
8532b578d3Smrg    ScrnInfoPtr pScreenInfo,
8632b578d3Smrg    ATIPtr      pATI,
8732b578d3Smrg    ATIHWPtr    pATIHW
8832b578d3Smrg)
8932b578d3Smrg{
9032b578d3Smrg    if ((pATI->LockData.crtc_gen_cntl & CRTC_CSYNC_EN) && !pATI->OptionCSync)
9132b578d3Smrg    {
9232b578d3Smrg        xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
9332b578d3Smrg            "Using composite sync to match input timing.\n");
9432b578d3Smrg        pATI->OptionCSync = TRUE;
9532b578d3Smrg    }
9632b578d3Smrg
9732b578d3Smrg    pATIHW->bus_cntl = inr(BUS_CNTL);
9832b578d3Smrg    if (pATI->Chip < ATI_CHIP_264VT4)
9932b578d3Smrg        pATIHW->bus_cntl = (pATIHW->bus_cntl & ~BUS_HOST_ERR_INT_EN) |
10032b578d3Smrg            BUS_HOST_ERR_INT;
10132b578d3Smrg    if (pATI->Chip < ATI_CHIP_264VTB)
10232b578d3Smrg    {
10332b578d3Smrg        pATIHW->bus_cntl &= ~(BUS_FIFO_ERR_INT_EN | BUS_ROM_DIS);
10432b578d3Smrg        pATIHW->bus_cntl |= SetBits(15, BUS_FIFO_WS) | BUS_FIFO_ERR_INT;
10532b578d3Smrg    }
10632b578d3Smrg    else if (pATI->MMIOInLinear)
10732b578d3Smrg    {
10832b578d3Smrg        pATIHW->bus_cntl &= ~BUS_APER_REG_DIS;
10932b578d3Smrg    }
11032b578d3Smrg    else
11132b578d3Smrg    {
11232b578d3Smrg        pATIHW->bus_cntl |= BUS_APER_REG_DIS;
11332b578d3Smrg    }
11432b578d3Smrg    if (pATI->Chip >= ATI_CHIP_264VT)
11532b578d3Smrg        pATIHW->bus_cntl |= BUS_EXT_REG_EN;     /* Enable Block 1 */
11632b578d3Smrg
11732b578d3Smrg#ifdef AVOID_CPIO
11832b578d3Smrg
11932b578d3Smrg    pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) |
12032b578d3Smrg        SetBits(1, MEM_VGA_WPS1);
12132b578d3Smrg    pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) |
12232b578d3Smrg        SetBits(1, MEM_VGA_RPS1);
12332b578d3Smrg
12432b578d3Smrg#else /* AVOID_CPIO */
12532b578d3Smrg
12632b578d3Smrg    pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) |
12732b578d3Smrg        SetBits(pATIHW->nPlane, MEM_VGA_WPS1);
12832b578d3Smrg    pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) |
12932b578d3Smrg        SetBits(pATIHW->nPlane, MEM_VGA_RPS1);
13032b578d3Smrg
13132b578d3Smrg#endif /* AVOID_CPIO */
13232b578d3Smrg
13332b578d3Smrg    pATIHW->dac_cntl = inr(DAC_CNTL) &
13432b578d3Smrg        ~(DAC1_CLK_SEL | DAC_PALETTE_ACCESS_CNTL | DAC_8BIT_EN);
13532b578d3Smrg    if (pATI->Chip >= ATI_CHIP_264CT)
13632b578d3Smrg        pATIHW->dac_cntl &= ~DAC_FEA_CON_EN;
13732b578d3Smrg    if (pATI->rgbBits == 8)
13832b578d3Smrg        pATIHW->dac_cntl |= DAC_8BIT_EN;
13932b578d3Smrg
14032b578d3Smrg    pATIHW->gen_test_cntl = pATI->LockData.gen_test_cntl & ~GEN_CUR_EN;
14132b578d3Smrg    if (pATI->DAC == ATI_DAC_IBMRGB514)
14232b578d3Smrg        pATIHW->gen_test_cntl |= GEN_OVR_OUTPUT_EN;
14332b578d3Smrg
14432b578d3Smrg    pATIHW->config_cntl = inr(CONFIG_CNTL);
14532b578d3Smrg
14632b578d3Smrg#ifndef AVOID_CPIO
14732b578d3Smrg
14832b578d3Smrg    if (pATI->VGAAdapter)
14932b578d3Smrg    {
15032b578d3Smrg        pATIHW->config_cntl |= CFG_MEM_VGA_AP_EN;
15132b578d3Smrg    }
15232b578d3Smrg    else
15332b578d3Smrg
15432b578d3Smrg#endif /* AVOID_CPIO */
15532b578d3Smrg
15632b578d3Smrg    {
15732b578d3Smrg        pATIHW->config_cntl &= ~CFG_MEM_VGA_AP_EN;
15832b578d3Smrg    }
15932b578d3Smrg
16032b578d3Smrg    if ((pATI->Chip < ATI_CHIP_264CT))
16132b578d3Smrg    {
16232b578d3Smrg        /* Replace linear aperture size and address */
16332b578d3Smrg        pATIHW->config_cntl &= ~(CFG_MEM_AP_LOC | CFG_MEM_AP_SIZE);
16432b578d3Smrg        pATIHW->config_cntl |= SetBits(pATI->LinearBase >> 22, CFG_MEM_AP_LOC);
16532b578d3Smrg        if ((pATI->Chip < ATI_CHIP_264CT) && (pATI->VideoRAM < 4096))
16632b578d3Smrg            pATIHW->config_cntl |= SetBits(1, CFG_MEM_AP_SIZE);
16732b578d3Smrg        else
16832b578d3Smrg            pATIHW->config_cntl |= SetBits(2, CFG_MEM_AP_SIZE);
16932b578d3Smrg    }
17032b578d3Smrg
17132b578d3Smrg    if (pATI->Chip >= ATI_CHIP_264VTB)
17232b578d3Smrg    {
17332b578d3Smrg        pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE;
17432b578d3Smrg        pATIHW->mem_cntl = (pATI->LockData.mem_cntl &
17532b578d3Smrg            ~(CTL_MEM_LOWER_APER_ENDIAN | CTL_MEM_UPPER_APER_ENDIAN)) |
17632b578d3Smrg            SetBits(CTL_MEM_APER_BYTE_ENDIAN, CTL_MEM_LOWER_APER_ENDIAN);
17732b578d3Smrg
17832b578d3Smrg        switch (pATI->bitsPerPixel)
17932b578d3Smrg        {
18032b578d3Smrg            default:
18132b578d3Smrg                pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_BYTE_ENDIAN,
18232b578d3Smrg                    CTL_MEM_UPPER_APER_ENDIAN);
18332b578d3Smrg                break;
18432b578d3Smrg
18532b578d3Smrg            case 16:
18632b578d3Smrg                pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_WORD_ENDIAN,
18732b578d3Smrg                    CTL_MEM_UPPER_APER_ENDIAN);
18832b578d3Smrg                break;
18932b578d3Smrg
19032b578d3Smrg            case 32:
19132b578d3Smrg                pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_LONG_ENDIAN,
19232b578d3Smrg                    CTL_MEM_UPPER_APER_ENDIAN);
19332b578d3Smrg                break;
19432b578d3Smrg        }
19532b578d3Smrg
19632b578d3Smrg        pATIHW->mpp_config = inr(MPP_CONFIG);
19732b578d3Smrg        pATIHW->mpp_config &=
19832b578d3Smrg            ~(MPP_PRESCALE | MPP_NSTATES | MPP_FORMAT | MPP_WAIT_STATE |
19932b578d3Smrg              MPP_INSERT_WAIT | MPP_TRISTATE_ADDR | MPP_AUTO_INC_EN |
20032b578d3Smrg              MPP_CHKREQ_EN | MPP_BUFFER_SIZE | MPP_BUFFER_MODE | MPP_BUSY);
20132b578d3Smrg        pATIHW->mpp_config |=
20232b578d3Smrg            (MPP_NSTATES_8 | MPP_FORMAT_DA8 | SetBits(4, MPP_WAIT_STATE) |
20332b578d3Smrg             MPP_CHKRDY_EN | MPP_READ_EARLY | MPP_RW_MODE | MPP_EN);
20432b578d3Smrg        pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ);
20532b578d3Smrg        pATIHW->mpp_strobe_seq &= ~(MPP_STB0_SEQ | MPP_STB1_SEQ);
20632b578d3Smrg        pATIHW->mpp_strobe_seq |=
20732b578d3Smrg            SetBits(0x0087U, MPP_STB0_SEQ) | SetBits(0x0083U, MPP_STB1_SEQ);
20832b578d3Smrg        pATIHW->tvo_cntl = 0;
20932b578d3Smrg    }
21032b578d3Smrg
21132b578d3Smrg    /* Draw engine setup */
21232b578d3Smrg    if (pATI->Block0Base)
21332b578d3Smrg    {
21432b578d3Smrg        CARD32 bus_cntl = inr(BUS_CNTL);
21532b578d3Smrg        CARD32 config_cntl = inr(CONFIG_CNTL);
21632b578d3Smrg
21732b578d3Smrg        /* Ensure apertures are enabled */
21832b578d3Smrg        outr(BUS_CNTL, pATIHW->bus_cntl);
21932b578d3Smrg        outr(CONFIG_CNTL, pATIHW->config_cntl);
22032b578d3Smrg
22132b578d3Smrg        /*
22232b578d3Smrg         * When possible, max out command FIFO size.
22332b578d3Smrg         */
22432b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264VT4)
22532b578d3Smrg
22632b578d3Smrg#ifdef XF86DRI_DEVEL
22732b578d3Smrg
22832b578d3Smrg	    /* Changing the FIFO depth seems to interfere with DMA, so use
22932b578d3Smrg	     * default of 128 entries (0x01)
23032b578d3Smrg	     */
23132b578d3Smrg	    pATIHW->gui_cntl = (inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE) | 0x01;
23232b578d3Smrg
23332b578d3Smrg#else /* XF86DRI_DEVEL */
23432b578d3Smrg
23532b578d3Smrg            pATIHW->gui_cntl = inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE;
23632b578d3Smrg
23732b578d3Smrg#endif /* XF86DRI_DEVEL */
23832b578d3Smrg
23932b578d3Smrg        /* Initialise destination registers */
24032b578d3Smrg        pATIHW->dst_off_pitch =
24132b578d3Smrg            SetBits((pATI->displayWidth * pATI->XModifier) >> 3, DST_PITCH);
24232b578d3Smrg        pATIHW->dst_cntl = DST_X_DIR | DST_Y_DIR | DST_LAST_PEL;
24332b578d3Smrg
24432b578d3Smrg        /* Initialise source registers */
24532b578d3Smrg        pATIHW->src_off_pitch = pATIHW->dst_off_pitch;
24632b578d3Smrg        pATIHW->src_width1 = pATIHW->src_height1 =
24732b578d3Smrg            pATIHW->src_width2 = pATIHW->src_height2 = 1;
24832b578d3Smrg        pATIHW->src_cntl = SRC_LINE_X_DIR;
24932b578d3Smrg
25032b578d3Smrg        /* Initialise scissor, allowing for offscreen areas */
25132b578d3Smrg#ifdef USE_XAA
25232b578d3Smrg        if (!pATI->useEXA)
25332b578d3Smrg        {
25432b578d3Smrg            int width, height, total;
25532b578d3Smrg
25632b578d3Smrg            pATIHW->sc_right = (pATI->displayWidth * pATI->XModifier) - 1;
25732b578d3Smrg            width = pATI->displayWidth * pATI->bitsPerPixel;
25832b578d3Smrg            total = pScreenInfo->videoRam * (1024 * 8);
25932b578d3Smrg            height = (total + width - 1) / width;
26032b578d3Smrg            if (height > ATIMach64MaxY + 1)
26132b578d3Smrg                height = ATIMach64MaxY + 1;
26232b578d3Smrg            pATIHW->sc_bottom = height - 1;
26332b578d3Smrg        }
26432b578d3Smrg#endif /* USE_XAA */
26532b578d3Smrg
26632b578d3Smrg#ifdef USE_EXA
26732b578d3Smrg        if (pATI->useEXA)
26832b578d3Smrg        {
26932b578d3Smrg            pATIHW->sc_right = ATIMach64MaxX;
27032b578d3Smrg            pATIHW->sc_bottom = ATIMach64MaxY;
27132b578d3Smrg        }
27232b578d3Smrg#endif /* USE_EXA */
27332b578d3Smrg
27432b578d3Smrg        pATI->sc_left_right = SetWord(pATI->NewHW.sc_right, 1) |
27532b578d3Smrg            SetWord(pATI->NewHW.sc_left, 0);
27632b578d3Smrg        pATI->sc_top_bottom = SetWord(pATI->NewHW.sc_bottom, 1) |
27732b578d3Smrg            SetWord(pATI->NewHW.sc_top, 0);
27832b578d3Smrg
27932b578d3Smrg        /* Initialise data path */
28032b578d3Smrg        pATIHW->dp_frgd_clr = (CARD32)(-1);
28132b578d3Smrg        pATIHW->dp_write_mask = (CARD32)(-1);
28232b578d3Smrg
28332b578d3Smrg        switch (pATI->depth)
28432b578d3Smrg        {
28532b578d3Smrg            case 8:
28632b578d3Smrg                pATIHW->dp_chain_mask = DP_CHAIN_8BPP;
28732b578d3Smrg                pATIHW->dp_pix_width =
28832b578d3Smrg                    SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
28932b578d3Smrg                    SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
29032b578d3Smrg                    SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
29132b578d3Smrg                break;
29232b578d3Smrg
29332b578d3Smrg            case 15:
29432b578d3Smrg                pATIHW->dp_chain_mask = DP_CHAIN_15BPP_1555;
29532b578d3Smrg                pATIHW->dp_pix_width =
29632b578d3Smrg                    SetBits(PIX_WIDTH_15BPP, DP_DST_PIX_WIDTH) |
29732b578d3Smrg                    SetBits(PIX_WIDTH_15BPP, DP_SRC_PIX_WIDTH) |
29832b578d3Smrg                    SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
29932b578d3Smrg                break;
30032b578d3Smrg
30132b578d3Smrg            case 16:
30232b578d3Smrg                pATIHW->dp_chain_mask = DP_CHAIN_16BPP_565;
30332b578d3Smrg                pATIHW->dp_pix_width =
30432b578d3Smrg                    SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) |
30532b578d3Smrg                    SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) |
30632b578d3Smrg                    SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
30732b578d3Smrg                break;
30832b578d3Smrg
30932b578d3Smrg            case 24:
31032b578d3Smrg                if (pATI->bitsPerPixel == 24)
31132b578d3Smrg                {
31232b578d3Smrg                    pATIHW->dp_chain_mask = DP_CHAIN_24BPP_888;
31332b578d3Smrg                    pATIHW->dp_pix_width =
31432b578d3Smrg                        SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
31532b578d3Smrg                        SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
31632b578d3Smrg                        SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
31732b578d3Smrg                }
31832b578d3Smrg                else
31932b578d3Smrg                {
32032b578d3Smrg                    pATIHW->dp_chain_mask = DP_CHAIN_32BPP_8888;
32132b578d3Smrg                    pATIHW->dp_pix_width =
32232b578d3Smrg                        SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) |
32332b578d3Smrg                        SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) |
32432b578d3Smrg                        SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
32532b578d3Smrg                }
32632b578d3Smrg                break;
32732b578d3Smrg
32832b578d3Smrg            default:
32932b578d3Smrg                break;
33032b578d3Smrg        }
33132b578d3Smrg
33232b578d3Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
33332b578d3Smrg
33432b578d3Smrg        pATIHW->dp_pix_width |= DP_BYTE_PIX_ORDER;
33532b578d3Smrg
33632b578d3Smrg#endif /* X_BYTE_ORDER */
33732b578d3Smrg
33832b578d3Smrg        pATIHW->dp_mix = SetBits(MIX_SRC, DP_FRGD_MIX) |
33932b578d3Smrg            SetBits(MIX_DST, DP_BKGD_MIX);
34032b578d3Smrg        pATIHW->dp_src = DP_MONO_SRC_ALLONES |
34132b578d3Smrg            SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC);
34232b578d3Smrg
34332b578d3Smrg        /* Initialise colour compare */
34432b578d3Smrg        pATIHW->clr_cmp_msk = (1 << pATI->depth) - 1;
34532b578d3Smrg
34632b578d3Smrg        if (pATI->Block1Base)
34732b578d3Smrg        {
34832b578d3Smrg            pATIHW->overlay_y_x_start = SetBits(0, OVERLAY_Y_START) |
34932b578d3Smrg                SetBits(0, OVERLAY_X_START) | OVERLAY_LOCK_START;
35032b578d3Smrg            pATIHW->overlay_y_x_end = SetBits(0, OVERLAY_Y_END) |
35132b578d3Smrg                SetBits(0, OVERLAY_X_END) | OVERLAY_LOCK_END;
35232b578d3Smrg
35332b578d3Smrg            pATIHW->overlay_graphics_key_clr =
35432b578d3Smrg                (3 << ((2 * pATI->depth) / 3)) |
35532b578d3Smrg                (2 << ((1 * pATI->depth) / 3)) |
35632b578d3Smrg                (1 << ((0 * pATI->depth) / 3));
35732b578d3Smrg            pATIHW->overlay_graphics_key_msk = (1 << pATI->depth) - 1;
35832b578d3Smrg
35932b578d3Smrg            pATIHW->overlay_key_cntl =
36032b578d3Smrg                SetBits(OVERLAY_MIX_FALSE, OVERLAY_VIDEO_FN) |
36132b578d3Smrg                SetBits(OVERLAY_MIX_EQUAL, OVERLAY_GRAPHICS_FN);
36232b578d3Smrg
36332b578d3Smrg            pATIHW->overlay_scale_cntl = SCALE_EN;
36432b578d3Smrg
36532b578d3Smrg            pATIHW->video_format = VIDEO_IN_VYUY422 | SCALER_IN_VYUY422;
36632b578d3Smrg
36732b578d3Smrg            if (pATI->Chip >= ATI_CHIP_264GTPRO)
36832b578d3Smrg            {
36932b578d3Smrg                /* These values are documented voodoo */
37032b578d3Smrg                pATIHW->scaler_h_coeff0 = SetByte(0x20U, 1);
37132b578d3Smrg                pATIHW->scaler_h_coeff1 = SetByte(0x0DU, 0) |
37232b578d3Smrg                    SetByte(0x20U, 1) | SetByte(0x06U, 2) | SetByte(0x0DU, 3);
37332b578d3Smrg                pATIHW->scaler_h_coeff2 = SetByte(0x0DU, 0) |
37432b578d3Smrg                    SetByte(0x1CU, 1) | SetByte(0x0AU, 2) | SetByte(0x0DU, 3);
37532b578d3Smrg                pATIHW->scaler_h_coeff3 = SetByte(0x0CU, 0) |
37632b578d3Smrg                    SetByte(0x1AU, 1) | SetByte(0x0EU, 2) | SetByte(0x0CU, 3);
37732b578d3Smrg                pATIHW->scaler_h_coeff4 = SetByte(0x0CU, 0) |
37832b578d3Smrg                    SetByte(0x14U, 1) | SetByte(0x14U, 2) | SetByte(0x0CU, 3);
37932b578d3Smrg            }
38032b578d3Smrg        }
38132b578d3Smrg
38232b578d3Smrg        /* Restore aperture enablement */
38332b578d3Smrg        outr(BUS_CNTL, bus_cntl);
38432b578d3Smrg        outr(CONFIG_CNTL, config_cntl);
38532b578d3Smrg    }
38632b578d3Smrg}
38732b578d3Smrg
38832b578d3Smrg/*
38932b578d3Smrg * ATIMach64Save --
39032b578d3Smrg *
39132b578d3Smrg * This function is called to save the Mach64 portion of the current video
39232b578d3Smrg * state.
39332b578d3Smrg */
39432b578d3Smrgvoid
39532b578d3SmrgATIMach64Save
39632b578d3Smrg(
39732b578d3Smrg    ATIPtr      pATI,
39832b578d3Smrg    ATIHWPtr    pATIHW
39932b578d3Smrg)
40032b578d3Smrg{
40132b578d3Smrg    pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
40232b578d3Smrg    pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
40332b578d3Smrg    pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
40432b578d3Smrg    pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
40532b578d3Smrg
40632b578d3Smrg    pATIHW->crtc_off_pitch = inr(CRTC_OFF_PITCH);
40732b578d3Smrg
40832b578d3Smrg    pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL);
40932b578d3Smrg
41032b578d3Smrg    pATIHW->ovr_clr = inr(OVR_CLR);
41132b578d3Smrg    pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT);
41232b578d3Smrg    pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM);
41332b578d3Smrg
41432b578d3Smrg    pATIHW->cur_clr0 = inr(CUR_CLR0);
41532b578d3Smrg    pATIHW->cur_clr1 = inr(CUR_CLR1);
41632b578d3Smrg    pATIHW->cur_offset = inr(CUR_OFFSET);
41732b578d3Smrg    pATIHW->cur_horz_vert_posn = inr(CUR_HORZ_VERT_POSN);
41832b578d3Smrg    pATIHW->cur_horz_vert_off = inr(CUR_HORZ_VERT_OFF);
41932b578d3Smrg
42032b578d3Smrg    pATIHW->clock_cntl = inr(CLOCK_CNTL);
42132b578d3Smrg
42232b578d3Smrg    pATIHW->bus_cntl = inr(BUS_CNTL);
42332b578d3Smrg
42432b578d3Smrg    pATIHW->mem_vga_wp_sel = inr(MEM_VGA_WP_SEL);
42532b578d3Smrg    pATIHW->mem_vga_rp_sel = inr(MEM_VGA_RP_SEL);
42632b578d3Smrg
42732b578d3Smrg    pATIHW->dac_cntl = inr(DAC_CNTL);
42832b578d3Smrg
42932b578d3Smrg    pATIHW->config_cntl = inr(CONFIG_CNTL);
43032b578d3Smrg
43132b578d3Smrg    pATIHW->gen_test_cntl = inr(GEN_TEST_CNTL) & ~GEN_CUR_EN;
43232b578d3Smrg
43332b578d3Smrg    if (pATI->Chip >= ATI_CHIP_264VTB)
43432b578d3Smrg    {
43532b578d3Smrg        pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE;
43632b578d3Smrg        pATIHW->mem_cntl = inr(MEM_CNTL);
43732b578d3Smrg        pATIHW->mpp_config = inr(MPP_CONFIG);
43832b578d3Smrg        pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ);
43932b578d3Smrg        pATIHW->tvo_cntl = inr(TVO_CNTL);
44032b578d3Smrg    }
44132b578d3Smrg
44232b578d3Smrg    /* Save draw engine state */
44332b578d3Smrg    if (pATI->Block0Base && (pATIHW == &pATI->OldHW))
44432b578d3Smrg    {
44532b578d3Smrg        /* Ensure apertures are enabled */
44632b578d3Smrg        outr(BUS_CNTL, pATI->NewHW.bus_cntl);
44732b578d3Smrg        outr(CONFIG_CNTL, pATI->NewHW.config_cntl);
44832b578d3Smrg
44932b578d3Smrg        ATIMach64WaitForIdle(pATI);
45032b578d3Smrg
45132b578d3Smrg        /* Save FIFO size */
45232b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264VT4)
45332b578d3Smrg            pATIHW->gui_cntl = inm(GUI_CNTL);
45432b578d3Smrg
45532b578d3Smrg        /* Save destination registers */
45632b578d3Smrg        pATIHW->dst_off_pitch = inm(DST_OFF_PITCH);
45732b578d3Smrg        pATIHW->dst_x = inm(DST_X);
45832b578d3Smrg        pATIHW->dst_y = inm(DST_Y);
45932b578d3Smrg        pATIHW->dst_height = inm(DST_HEIGHT);
46032b578d3Smrg        pATIHW->dst_bres_err = inm(DST_BRES_ERR);
46132b578d3Smrg        pATIHW->dst_bres_inc = inm(DST_BRES_INC);
46232b578d3Smrg        pATIHW->dst_bres_dec = inm(DST_BRES_DEC);
46332b578d3Smrg        pATIHW->dst_cntl = inm(DST_CNTL);
46432b578d3Smrg
46532b578d3Smrg        /* Save source registers */
46632b578d3Smrg        pATIHW->src_off_pitch = inm(SRC_OFF_PITCH);
46732b578d3Smrg        pATIHW->src_x = inm(SRC_X);
46832b578d3Smrg        pATIHW->src_y = inm(SRC_Y);
46932b578d3Smrg        pATIHW->src_width1 = inm(SRC_WIDTH1);
47032b578d3Smrg        pATIHW->src_height1 = inm(SRC_HEIGHT1);
47132b578d3Smrg        pATIHW->src_x_start = inm(SRC_X_START);
47232b578d3Smrg        pATIHW->src_y_start = inm(SRC_Y_START);
47332b578d3Smrg        pATIHW->src_width2 = inm(SRC_WIDTH2);
47432b578d3Smrg        pATIHW->src_height2 = inm(SRC_HEIGHT2);
47532b578d3Smrg        pATIHW->src_cntl = inm(SRC_CNTL);
47632b578d3Smrg
47732b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264GTPRO)
47832b578d3Smrg        {
47932b578d3Smrg            CARD32 offset = TEX_LEVEL(inm(TEX_SIZE_PITCH));
48032b578d3Smrg
48132b578d3Smrg            /* Save 3D control & texture registers */
48232b578d3Smrg            pATIHW->tex_offset = inm(TEX_0_OFF + offset);
48332b578d3Smrg            pATIHW->scale_3d_cntl = inm(SCALE_3D_CNTL);
48432b578d3Smrg        }
48532b578d3Smrg
48632b578d3Smrg        /* Save host data register */
48732b578d3Smrg        pATIHW->host_cntl = inm(HOST_CNTL);
48832b578d3Smrg
48932b578d3Smrg        /* Save pattern registers */
49032b578d3Smrg        pATIHW->pat_reg0 = inm(PAT_REG0);
49132b578d3Smrg        pATIHW->pat_reg1 = inm(PAT_REG1);
49232b578d3Smrg        pATIHW->pat_cntl = inm(PAT_CNTL);
49332b578d3Smrg
49432b578d3Smrg        /* Save scissor registers */
49532b578d3Smrg        pATIHW->sc_left = pATI->sc_left = inm(SC_LEFT);
49632b578d3Smrg        pATIHW->sc_right = pATI->sc_right = inm(SC_RIGHT);
49732b578d3Smrg        pATIHW->sc_top = pATI->sc_top = inm(SC_TOP);
49832b578d3Smrg        pATIHW->sc_bottom = pATI->sc_bottom = inm(SC_BOTTOM);
49932b578d3Smrg
50032b578d3Smrg        /* Save data path registers */
50132b578d3Smrg        pATIHW->dp_bkgd_clr = inm(DP_BKGD_CLR);
50232b578d3Smrg        pATIHW->dp_frgd_clr = inm(DP_FRGD_CLR);
50332b578d3Smrg        pATIHW->dp_write_mask = inm(DP_WRITE_MASK);
50432b578d3Smrg        pATIHW->dp_chain_mask = inm(DP_CHAIN_MASK);
50532b578d3Smrg        pATIHW->dp_pix_width = inm(DP_PIX_WIDTH);
50632b578d3Smrg        pATIHW->dp_mix = inm(DP_MIX);
50732b578d3Smrg        pATIHW->dp_src = inm(DP_SRC);
50832b578d3Smrg
50932b578d3Smrg        /* Save colour compare registers */
51032b578d3Smrg        pATIHW->clr_cmp_clr = inm(CLR_CMP_CLR);
51132b578d3Smrg        pATIHW->clr_cmp_msk = inm(CLR_CMP_MSK);
51232b578d3Smrg        pATIHW->clr_cmp_cntl = inm(CLR_CMP_CNTL);
51332b578d3Smrg
51432b578d3Smrg        /* Save context */
51532b578d3Smrg        pATIHW->context_mask = inm(CONTEXT_MASK);
51632b578d3Smrg
51732b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264GTPRO)
51832b578d3Smrg        {
51932b578d3Smrg            /* Save texture setup registers */
52032b578d3Smrg            pATIHW->tex_size_pitch = inm(TEX_SIZE_PITCH);
52132b578d3Smrg            pATIHW->tex_cntl = inm(TEX_CNTL);
52232b578d3Smrg        }
52332b578d3Smrg
52432b578d3Smrg        if (pATI->Block1Base)
52532b578d3Smrg        {
52632b578d3Smrg            /* Save overlay & scaler registers */
52732b578d3Smrg            pATIHW->overlay_y_x_start = inm(OVERLAY_Y_X_START);
52832b578d3Smrg            pATIHW->overlay_y_x_end = inm(OVERLAY_Y_X_END);
52932b578d3Smrg
53032b578d3Smrg            pATIHW->overlay_graphics_key_clr = inm(OVERLAY_GRAPHICS_KEY_CLR);
53132b578d3Smrg            pATIHW->overlay_graphics_key_msk = inm(OVERLAY_GRAPHICS_KEY_MSK);
53232b578d3Smrg
53332b578d3Smrg            pATIHW->overlay_key_cntl = inm(OVERLAY_KEY_CNTL);
53432b578d3Smrg
53532b578d3Smrg            pATIHW->overlay_scale_inc = inm(OVERLAY_SCALE_INC);
53632b578d3Smrg            pATIHW->overlay_scale_cntl = inm(OVERLAY_SCALE_CNTL);
53732b578d3Smrg
53832b578d3Smrg            pATIHW->scaler_height_width = inm(SCALER_HEIGHT_WIDTH);
53932b578d3Smrg
54032b578d3Smrg            pATIHW->scaler_test = inm(SCALER_TEST);
54132b578d3Smrg
54232b578d3Smrg            pATIHW->video_format = inm(VIDEO_FORMAT);
54332b578d3Smrg
54432b578d3Smrg            if (pATI->Chip < ATI_CHIP_264VTB)
54532b578d3Smrg            {
54632b578d3Smrg                pATIHW->buf0_offset = inm(BUF0_OFFSET);
54732b578d3Smrg                pATIHW->buf0_pitch = inm(BUF0_PITCH);
54832b578d3Smrg                pATIHW->buf1_offset = inm(BUF1_OFFSET);
54932b578d3Smrg                pATIHW->buf1_pitch = inm(BUF1_PITCH);
55032b578d3Smrg            }
55132b578d3Smrg            else
55232b578d3Smrg            {
55332b578d3Smrg                pATIHW->scaler_buf0_offset = inm(SCALER_BUF0_OFFSET);
55432b578d3Smrg                pATIHW->scaler_buf1_offset = inm(SCALER_BUF1_OFFSET);
55532b578d3Smrg                pATIHW->scaler_buf_pitch = inm(SCALER_BUF_PITCH);
55632b578d3Smrg
55732b578d3Smrg                pATIHW->overlay_exclusive_horz = inm(OVERLAY_EXCLUSIVE_HORZ);
55832b578d3Smrg                pATIHW->overlay_exclusive_vert = inm(OVERLAY_EXCLUSIVE_VERT);
55932b578d3Smrg
56032b578d3Smrg                if (pATI->Chip >= ATI_CHIP_264GTPRO)
56132b578d3Smrg                {
56232b578d3Smrg                    pATIHW->scaler_colour_cntl = inm(SCALER_COLOUR_CNTL);
56332b578d3Smrg
56432b578d3Smrg                    pATIHW->scaler_h_coeff0 = inm(SCALER_H_COEFF0);
56532b578d3Smrg                    pATIHW->scaler_h_coeff1 = inm(SCALER_H_COEFF1);
56632b578d3Smrg                    pATIHW->scaler_h_coeff2 = inm(SCALER_H_COEFF2);
56732b578d3Smrg                    pATIHW->scaler_h_coeff3 = inm(SCALER_H_COEFF3);
56832b578d3Smrg                    pATIHW->scaler_h_coeff4 = inm(SCALER_H_COEFF4);
56932b578d3Smrg
57032b578d3Smrg                    pATIHW->scaler_buf0_offset_u = inm(SCALER_BUF0_OFFSET_U);
57132b578d3Smrg                    pATIHW->scaler_buf0_offset_v = inm(SCALER_BUF0_OFFSET_V);
57232b578d3Smrg                    pATIHW->scaler_buf1_offset_u = inm(SCALER_BUF1_OFFSET_U);
57332b578d3Smrg                    pATIHW->scaler_buf1_offset_v = inm(SCALER_BUF1_OFFSET_V);
57432b578d3Smrg                }
57532b578d3Smrg            }
57632b578d3Smrg        }
57732b578d3Smrg
57832b578d3Smrg        /* Restore aperture enablement */
57932b578d3Smrg        outr(BUS_CNTL, pATIHW->bus_cntl);
58032b578d3Smrg        outr(CONFIG_CNTL, pATIHW->config_cntl);
58132b578d3Smrg    }
58232b578d3Smrg}
58332b578d3Smrg
58432b578d3Smrg/*
58532b578d3Smrg * ATIMach64ModeAdjust --
58632b578d3Smrg *
58732b578d3Smrg * This function is called to adjust horizontal and vertical timings.
58832b578d3Smrg */
58932b578d3Smrgstatic void
59032b578d3SmrgATIMach64ModeAdjust
59132b578d3Smrg(
59232b578d3Smrg    ATIPtr         pATI,
59332b578d3Smrg    ATIHWPtr       pATIHW,
59432b578d3Smrg    DisplayModePtr pMode
59532b578d3Smrg)
59632b578d3Smrg{
59732b578d3Smrg    int VDisplay;
59832b578d3Smrg
59932b578d3Smrg    /* Clobber mode timings */
60032b578d3Smrg    if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
60132b578d3Smrg    {
60232b578d3Smrg        if (!pMode->CrtcHAdjusted && !pMode->CrtcVAdjusted &&
60332b578d3Smrg            (!pATI->OptionLCDSync || (pMode->type & M_T_BUILTIN)))
60432b578d3Smrg        {
60532b578d3Smrg        int VScan;
60632b578d3Smrg
60732b578d3Smrg        pMode->Clock = pATI->LCDClock;
60832b578d3Smrg        pMode->Flags &= ~(V_DBLSCAN | V_INTERLACE | V_CLKDIV2);
60932b578d3Smrg
61032b578d3Smrg        pMode->VScan = 0;
61132b578d3Smrg
61232b578d3Smrg        /*
61332b578d3Smrg         * Use doublescanning or multiscanning to get around vertical blending
61432b578d3Smrg         * limitations.
61532b578d3Smrg         */
61632b578d3Smrg        VScan = pATI->LCDVertical / pMode->VDisplay;
61732b578d3Smrg        if (VScan > 1)
61832b578d3Smrg        {
61932b578d3Smrg            VScan = 2;
62032b578d3Smrg            pMode->Flags |= V_DBLSCAN;
62132b578d3Smrg        }
62232b578d3Smrg
62332b578d3Smrg        pMode->HSyncStart = pMode->HDisplay + pATI->LCDHSyncStart;
62432b578d3Smrg        pMode->HSyncEnd = pMode->HSyncStart + pATI->LCDHSyncWidth;
62532b578d3Smrg        pMode->HTotal = pMode->HDisplay + pATI->LCDHBlankWidth;
62632b578d3Smrg
62732b578d3Smrg        pMode->VSyncStart = pMode->VDisplay +
62832b578d3Smrg            ATIDivide(pATI->LCDVSyncStart, VScan, 0, 0);
62932b578d3Smrg        pMode->VSyncEnd = pMode->VSyncStart +
63032b578d3Smrg            ATIDivide(pATI->LCDVSyncWidth, VScan, 0, 1);
63132b578d3Smrg        pMode->VTotal = pMode->VDisplay +
63232b578d3Smrg            ATIDivide(pATI->LCDVBlankWidth, VScan, 0, 0);
63332b578d3Smrg        }
63432b578d3Smrg    }
63532b578d3Smrg
63632b578d3Smrg    /* If not already done adjust horizontal timings */
63732b578d3Smrg    if (!pMode->CrtcHAdjusted)
63832b578d3Smrg    {
63932b578d3Smrg        pMode->CrtcHAdjusted = TRUE;
64032b578d3Smrg        /* XXX Deal with Blank Start/End and overscan later */
64132b578d3Smrg        pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1;
64232b578d3Smrg        pMode->CrtcHSyncStart = (pMode->HSyncStart >> 3) - 1;
64332b578d3Smrg        pMode->CrtcHSyncEnd = (pMode->HSyncEnd >> 3) - 1;
64432b578d3Smrg        pMode->CrtcHTotal = (pMode->HTotal >> 3) - 1;
64532b578d3Smrg
64632b578d3Smrg        /* Make adjustments if sync pulse width is out-of-bounds */
64732b578d3Smrg        if ((pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart) >
64832b578d3Smrg            (int)MaxBits(CRTC_H_SYNC_WID))
64932b578d3Smrg        {
65032b578d3Smrg            pMode->CrtcHSyncEnd =
65132b578d3Smrg                pMode->CrtcHSyncStart + MaxBits(CRTC_H_SYNC_WID);
65232b578d3Smrg        }
65332b578d3Smrg        else if (pMode->CrtcHSyncStart == pMode->CrtcHSyncEnd)
65432b578d3Smrg        {
65532b578d3Smrg            if (pMode->CrtcHDisplay < pMode->CrtcHSyncStart)
65632b578d3Smrg                pMode->CrtcHSyncStart--;
65732b578d3Smrg            else if (pMode->CrtcHSyncEnd < pMode->CrtcHTotal)
65832b578d3Smrg                pMode->CrtcHSyncEnd++;
65932b578d3Smrg        }
66032b578d3Smrg    }
66132b578d3Smrg
66232b578d3Smrg    /*
66332b578d3Smrg     * Always re-do vertical adjustments.
66432b578d3Smrg     */
66532b578d3Smrg    pMode->CrtcVDisplay = pMode->VDisplay;
66632b578d3Smrg    pMode->CrtcVSyncStart = pMode->VSyncStart;
66732b578d3Smrg    pMode->CrtcVSyncEnd = pMode->VSyncEnd;
66832b578d3Smrg    pMode->CrtcVTotal = pMode->VTotal;
66932b578d3Smrg
67032b578d3Smrg    if ((pATI->Chip >= ATI_CHIP_264CT) &&
67132b578d3Smrg        ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1)))
67232b578d3Smrg    {
67332b578d3Smrg        pMode->CrtcVDisplay <<= 1;
67432b578d3Smrg        pMode->CrtcVSyncStart <<= 1;
67532b578d3Smrg        pMode->CrtcVSyncEnd <<= 1;
67632b578d3Smrg        pMode->CrtcVTotal <<= 1;
67732b578d3Smrg    }
67832b578d3Smrg
67932b578d3Smrg    /*
68032b578d3Smrg     * Might as well default to the same as VGA with respect to sync
68132b578d3Smrg     * polarities.
68232b578d3Smrg     */
68332b578d3Smrg    if ((!(pMode->Flags & (V_PHSYNC | V_NHSYNC))) ||
68432b578d3Smrg        (!(pMode->Flags & (V_PVSYNC | V_NVSYNC))))
68532b578d3Smrg    {
68632b578d3Smrg        pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC);
68732b578d3Smrg
68832b578d3Smrg        if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
68932b578d3Smrg            VDisplay = pATI->LCDVertical;
69032b578d3Smrg        else
69132b578d3Smrg            VDisplay = pMode->CrtcVDisplay;
69232b578d3Smrg
69332b578d3Smrg#ifdef TV_OUT
69432b578d3Smrg        if (pATI->tvActive)
69532b578d3Smrg            VDisplay = pMode->CrtcVDisplay;
69632b578d3Smrg#endif
69732b578d3Smrg
69832b578d3Smrg        if (VDisplay < 400)
69932b578d3Smrg            pMode->Flags |= V_PHSYNC | V_NVSYNC;
70032b578d3Smrg        else if (VDisplay < 480)
70132b578d3Smrg            pMode->Flags |= V_NHSYNC | V_PVSYNC;
70232b578d3Smrg        else if (VDisplay < 768)
70332b578d3Smrg            pMode->Flags |= V_NHSYNC | V_NVSYNC;
70432b578d3Smrg        else
70532b578d3Smrg            pMode->Flags |= V_PHSYNC | V_PVSYNC;
70632b578d3Smrg    }
70732b578d3Smrg
70832b578d3Smrg    pMode->CrtcVDisplay--;
70932b578d3Smrg    pMode->CrtcVSyncStart--;
71032b578d3Smrg    pMode->CrtcVSyncEnd--;
71132b578d3Smrg    pMode->CrtcVTotal--;
71232b578d3Smrg    /* Make sure sync pulse is not too wide */
71332b578d3Smrg    if ((pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart) >
71432b578d3Smrg         (int)MaxBits(CRTC_V_SYNC_WID))
71532b578d3Smrg        pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + MaxBits(CRTC_V_SYNC_WID);
71632b578d3Smrg    pMode->CrtcVAdjusted = TRUE;                /* Redundant */
71732b578d3Smrg}
71832b578d3Smrg
71932b578d3Smrg/*
72032b578d3Smrg * ATIMach64Calculate --
72132b578d3Smrg *
72232b578d3Smrg * This function is called to fill in the Mach64 portion of an ATIHWRec.
72332b578d3Smrg */
72432b578d3Smrgvoid
72532b578d3SmrgATIMach64Calculate
72632b578d3Smrg(
72732b578d3Smrg    ATIPtr         pATI,
72832b578d3Smrg    ATIHWPtr       pATIHW,
72932b578d3Smrg    DisplayModePtr pMode
73032b578d3Smrg)
73132b578d3Smrg{
73232b578d3Smrg    ATIMach64ModeAdjust(pATI, pATIHW, pMode);
73332b578d3Smrg
73432b578d3Smrg    /* Build register contents */
73532b578d3Smrg    pATIHW->crtc_h_total_disp =
73632b578d3Smrg        SetBits(pMode->CrtcHTotal, CRTC_H_TOTAL) |
73732b578d3Smrg        SetBits(pMode->CrtcHDisplay, CRTC_H_DISP);
73832b578d3Smrg
73932b578d3Smrg    pATIHW->crtc_h_sync_strt_wid =
74032b578d3Smrg        SetBits(pMode->CrtcHSyncStart, CRTC_H_SYNC_STRT) |
74132b578d3Smrg        SetBits(pMode->CrtcHSkew, CRTC_H_SYNC_DLY) |         /* ? */
74232b578d3Smrg        SetBits(GetBits(pMode->CrtcHSyncStart, 0x0100U), CRTC_H_SYNC_STRT_HI) |
74332b578d3Smrg        SetBits(pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart, CRTC_H_SYNC_WID);
74432b578d3Smrg    if (pMode->Flags & V_NHSYNC)
74532b578d3Smrg        pATIHW->crtc_h_sync_strt_wid |= CRTC_H_SYNC_POL;
74632b578d3Smrg
74732b578d3Smrg    pATIHW->crtc_v_total_disp =
74832b578d3Smrg        SetBits(pMode->CrtcVTotal, CRTC_V_TOTAL) |
74932b578d3Smrg        SetBits(pMode->CrtcVDisplay, CRTC_V_DISP);
75032b578d3Smrg
75132b578d3Smrg    pATIHW->crtc_v_sync_strt_wid =
75232b578d3Smrg        SetBits(pMode->CrtcVSyncStart, CRTC_V_SYNC_STRT) |
75332b578d3Smrg        SetBits(pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart, CRTC_V_SYNC_WID);
75432b578d3Smrg    if (pMode->Flags & V_NVSYNC)
75532b578d3Smrg        pATIHW->crtc_v_sync_strt_wid |= CRTC_V_SYNC_POL;
75632b578d3Smrg
75732b578d3Smrg    pATIHW->crtc_off_pitch = SetBits(pATI->displayWidth >> 3, CRTC_PITCH);
75832b578d3Smrg
75932b578d3Smrg    pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL) &
76032b578d3Smrg        ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN |
76132b578d3Smrg          CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN |
76232b578d3Smrg          CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS | CRTC_VGA_XOVERSCAN |
76332b578d3Smrg          CRTC_PIX_WIDTH | CRTC_BYTE_PIX_ORDER |
76432b578d3Smrg          CRTC_VGA_128KAP_PAGING | CRTC_VFC_SYNC_TRISTATE |
76532b578d3Smrg          CRTC_LOCK_REGS |              /* Already off, but ... */
76632b578d3Smrg          CRTC_SYNC_TRISTATE | CRTC_DISP_REQ_EN |
76732b578d3Smrg          CRTC_VGA_TEXT_132 | CRTC_CUR_B_TEST);
76832b578d3Smrg    pATIHW->crtc_gen_cntl |=
76932b578d3Smrg        CRTC_EXT_DISP_EN | CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN;
77032b578d3Smrg    switch (pATI->depth)
77132b578d3Smrg    {
77232b578d3Smrg        case 8:
77332b578d3Smrg            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_8BPP, CRTC_PIX_WIDTH);
77432b578d3Smrg            break;
77532b578d3Smrg
77632b578d3Smrg        case 15:
77732b578d3Smrg            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_15BPP, CRTC_PIX_WIDTH);
77832b578d3Smrg            break;
77932b578d3Smrg
78032b578d3Smrg        case 16:
78132b578d3Smrg            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_16BPP, CRTC_PIX_WIDTH);
78232b578d3Smrg            break;
78332b578d3Smrg
78432b578d3Smrg        case 24:
78532b578d3Smrg            if (pATI->bitsPerPixel == 24)
78632b578d3Smrg            {
78732b578d3Smrg                pATIHW->crtc_gen_cntl |=
78832b578d3Smrg                    SetBits(PIX_WIDTH_24BPP, CRTC_PIX_WIDTH);
78932b578d3Smrg                break;
79032b578d3Smrg            }
79132b578d3Smrg            if (pATI->bitsPerPixel != 32)
79232b578d3Smrg                break;
79332b578d3Smrg            /* Fall through */
79432b578d3Smrg
79532b578d3Smrg        case 32:
79632b578d3Smrg            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_32BPP, CRTC_PIX_WIDTH);
79732b578d3Smrg            break;
79832b578d3Smrg
79932b578d3Smrg        default:
80032b578d3Smrg            break;
80132b578d3Smrg    }
80232b578d3Smrg    if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1))
80332b578d3Smrg        pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN;
80432b578d3Smrg    if (pMode->Flags & V_INTERLACE)
80532b578d3Smrg        pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN;
80632b578d3Smrg    if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
80732b578d3Smrg        pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN;
80832b578d3Smrg    /* For now, set display FIFO low water mark as high as possible */
80932b578d3Smrg    if (pATI->Chip < ATI_CHIP_264VTB)
81032b578d3Smrg        pATIHW->crtc_gen_cntl |= CRTC_FIFO_LWM;
81132b578d3Smrg}
81232b578d3Smrg
81332b578d3Smrg/*
81432b578d3Smrg * ATIMach64Set --
81532b578d3Smrg *
81632b578d3Smrg * This function is called to load a Mach64's accelerator CRTC and draw engine.
81732b578d3Smrg */
81832b578d3Smrgvoid
81932b578d3SmrgATIMach64Set
82032b578d3Smrg(
82132b578d3Smrg    ATIPtr      pATI,
82232b578d3Smrg    ATIHWPtr    pATIHW
82332b578d3Smrg)
82432b578d3Smrg{
82532b578d3Smrg
82632b578d3Smrg#ifndef AVOID_CPIO
82732b578d3Smrg
82832b578d3Smrg    if (pATIHW->crtc == ATI_CRTC_MACH64)
82932b578d3Smrg
83032b578d3Smrg#endif /* AVOID_CPIO */
83132b578d3Smrg
83232b578d3Smrg    {
83332b578d3Smrg        if ((pATIHW->FeedbackDivider > 0))
83432b578d3Smrg            ATIClockSet(pATI, pATIHW);          /* Programme clock */
83532b578d3Smrg
83632b578d3Smrg        if (pATI->DAC == ATI_DAC_IBMRGB514)
83732b578d3Smrg            ATIRGB514Set(pATI, pATIHW);
83832b578d3Smrg
83932b578d3Smrg        /* Load Mach64 CRTC registers */
84032b578d3Smrg        outr(CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp);
84132b578d3Smrg        outr(CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid);
84232b578d3Smrg        outr(CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp);
84332b578d3Smrg        outr(CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid);
84432b578d3Smrg
84532b578d3Smrg        outr(CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
84632b578d3Smrg
84732b578d3Smrg        /* Load overscan registers */
84832b578d3Smrg        outr(OVR_CLR, pATIHW->ovr_clr);
84932b578d3Smrg        outr(OVR_WID_LEFT_RIGHT, pATIHW->ovr_wid_left_right);
85032b578d3Smrg        outr(OVR_WID_TOP_BOTTOM, pATIHW->ovr_wid_top_bottom);
85132b578d3Smrg
85232b578d3Smrg        /* Load hardware cursor registers */
85332b578d3Smrg        outr(CUR_CLR0, pATIHW->cur_clr0);
85432b578d3Smrg        outr(CUR_CLR1, pATIHW->cur_clr1);
85532b578d3Smrg        outr(CUR_OFFSET, pATIHW->cur_offset);
85632b578d3Smrg        outr(CUR_HORZ_VERT_POSN, pATIHW->cur_horz_vert_posn);
85732b578d3Smrg        outr(CUR_HORZ_VERT_OFF, pATIHW->cur_horz_vert_off);
85832b578d3Smrg
85932b578d3Smrg        /* Set pixel clock */
86032b578d3Smrg        outr(CLOCK_CNTL, pATIHW->clock_cntl | CLOCK_STROBE);
86132b578d3Smrg
86232b578d3Smrg        outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
86332b578d3Smrg        outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl);
86432b578d3Smrg        outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
86532b578d3Smrg
86632b578d3Smrg        /* Finalise CRTC setup and turn on the screen */
86732b578d3Smrg        outr(CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
86832b578d3Smrg    }
86932b578d3Smrg
87032b578d3Smrg    /* Load draw engine */
87132b578d3Smrg    if (pATI->Block0Base)
87232b578d3Smrg    {
87332b578d3Smrg        /* Clobber MMIO cache */
87432b578d3Smrg        (void)memset(pATI->MMIOCached, 0, SizeOf(pATI->MMIOCached));
87532b578d3Smrg
87632b578d3Smrg        /* Ensure apertures are enabled */
87732b578d3Smrg        outr(BUS_CNTL, pATI->NewHW.bus_cntl);
87832b578d3Smrg        outr(CONFIG_CNTL, pATI->NewHW.config_cntl);
87932b578d3Smrg
88032b578d3Smrg        pATI->EngineIsBusy = TRUE;      /* Force engine poll */
88132b578d3Smrg        ATIMach64WaitForIdle(pATI);
88232b578d3Smrg
88332b578d3Smrg        /* Load FIFO size */
88432b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264VT4)
88532b578d3Smrg        {
88632b578d3Smrg            outm(GUI_CNTL, pATIHW->gui_cntl);
88732b578d3Smrg            pATI->nAvailableFIFOEntries = 0;
88832b578d3Smrg            ATIMach64PollEngineStatus(pATI);
88932b578d3Smrg        }
89032b578d3Smrg
89132b578d3Smrg        /* Set FIFO depth */
89232b578d3Smrg        pATI->nFIFOEntries = pATI->nAvailableFIFOEntries;
89332b578d3Smrg
89432b578d3Smrg        /* Load destination registers */
89532b578d3Smrg        ATIMach64WaitForFIFO(pATI, 7);
89632b578d3Smrg        outf(DST_OFF_PITCH, pATIHW->dst_off_pitch);
89732b578d3Smrg        outf(DST_Y_X, SetWord(pATIHW->dst_x, 1) | SetWord(pATIHW->dst_y, 0));
89832b578d3Smrg        outf(DST_HEIGHT, pATIHW->dst_height);
89932b578d3Smrg        outf(DST_BRES_ERR, pATIHW->dst_bres_err);
90032b578d3Smrg        outf(DST_BRES_INC, pATIHW->dst_bres_inc);
90132b578d3Smrg        outf(DST_BRES_DEC, pATIHW->dst_bres_dec);
90232b578d3Smrg        outf(DST_CNTL, pATIHW->dst_cntl);
90332b578d3Smrg
90432b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264GTPRO)
90532b578d3Smrg        {
90632b578d3Smrg            /* Load ROP unit registers */
90732b578d3Smrg            ATIMach64WaitForFIFO(pATI, 2);
90832b578d3Smrg            outf(Z_CNTL, 0);
90932b578d3Smrg            outf(ALPHA_TST_CNTL, 0);
91032b578d3Smrg        }
91132b578d3Smrg
91232b578d3Smrg        /* Load source registers */
91332b578d3Smrg        ATIMach64WaitForFIFO(pATI, 6);
91432b578d3Smrg        outf(SRC_OFF_PITCH, pATIHW->src_off_pitch);
91532b578d3Smrg        outf(SRC_Y_X, SetWord(pATIHW->src_x, 1) | SetWord(pATIHW->src_y, 0));
91632b578d3Smrg        outf(SRC_HEIGHT1_WIDTH1,
91732b578d3Smrg            SetWord(pATIHW->src_width1, 1) | SetWord(pATIHW->src_height1, 0));
91832b578d3Smrg        outf(SRC_Y_X_START,
91932b578d3Smrg            SetWord(pATIHW->src_x_start, 1) | SetWord(pATIHW->src_y_start, 0));
92032b578d3Smrg        outf(SRC_HEIGHT2_WIDTH2,
92132b578d3Smrg            SetWord(pATIHW->src_width2, 1) | SetWord(pATIHW->src_height2, 0));
92232b578d3Smrg        outf(SRC_CNTL, pATIHW->src_cntl);
92332b578d3Smrg
92432b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264GTPRO)
92532b578d3Smrg        {
92632b578d3Smrg            CARD32 offset = TEX_LEVEL(pATIHW->tex_size_pitch);
92732b578d3Smrg
92832b578d3Smrg            /* Load 3D control & texture registers */
92932b578d3Smrg            ATIMach64WaitForFIFO(pATI, 2);
93032b578d3Smrg            outf(TEX_0_OFF + offset, pATIHW->tex_offset);
93132b578d3Smrg            outf(SCALE_3D_CNTL, pATIHW->scale_3d_cntl);
93232b578d3Smrg        }
93332b578d3Smrg
93432b578d3Smrg        /* Load host data register */
93532b578d3Smrg        ATIMach64WaitForFIFO(pATI, 1);
93632b578d3Smrg        outf(HOST_CNTL, pATIHW->host_cntl);
93732b578d3Smrg
93832b578d3Smrg        /* Set host transfer window address and size clamp */
93932b578d3Smrg        pATI->pHOST_DATA = ATIHostDataAddr(HOST_DATA_0);
94032b578d3Smrg        pATI->nHostFIFOEntries = pATI->nFIFOEntries >> 1;
94132b578d3Smrg        if (pATI->nHostFIFOEntries > 16)
94232b578d3Smrg            pATI->nHostFIFOEntries = 16;
94332b578d3Smrg
94432b578d3Smrg        /* Load pattern registers */
94532b578d3Smrg        ATIMach64WaitForFIFO(pATI, 3);
94632b578d3Smrg        outf(PAT_REG0, pATIHW->pat_reg0);
94732b578d3Smrg        outf(PAT_REG1, pATIHW->pat_reg1);
94832b578d3Smrg        outf(PAT_CNTL, pATIHW->pat_cntl);
94932b578d3Smrg
95032b578d3Smrg        /* Load scissor registers */
95132b578d3Smrg        ATIMach64WaitForFIFO(pATI, 2);
95232b578d3Smrg        outf(SC_LEFT_RIGHT,
95332b578d3Smrg            SetWord(pATIHW->sc_right, 1) | SetWord(pATIHW->sc_left, 0));
95432b578d3Smrg        outf(SC_TOP_BOTTOM,
95532b578d3Smrg            SetWord(pATIHW->sc_bottom, 1) | SetWord(pATIHW->sc_top, 0));
95632b578d3Smrg        pATI->sc_left = pATIHW->sc_left;
95732b578d3Smrg        pATI->sc_right = pATIHW->sc_right;
95832b578d3Smrg        pATI->sc_top = pATIHW->sc_top;
95932b578d3Smrg        pATI->sc_bottom = pATIHW->sc_bottom;
96032b578d3Smrg
96132b578d3Smrg        /* Load data path registers */
96232b578d3Smrg        ATIMach64WaitForFIFO(pATI, 7);
96332b578d3Smrg        outf(DP_BKGD_CLR, pATIHW->dp_bkgd_clr);
96432b578d3Smrg        outf(DP_FRGD_CLR, pATIHW->dp_frgd_clr);
96532b578d3Smrg        outf(DP_WRITE_MASK, pATIHW->dp_write_mask);
96632b578d3Smrg        outf(DP_CHAIN_MASK, pATIHW->dp_chain_mask);
96732b578d3Smrg        outf(DP_PIX_WIDTH, pATIHW->dp_pix_width);
96832b578d3Smrg        outf(DP_MIX, pATIHW->dp_mix);
96932b578d3Smrg        outf(DP_SRC, pATIHW->dp_src);
97032b578d3Smrg
97132b578d3Smrg        /* Load colour compare registers */
97232b578d3Smrg        ATIMach64WaitForFIFO(pATI, 3);
97332b578d3Smrg        outf(CLR_CMP_CLR, pATIHW->clr_cmp_clr);
97432b578d3Smrg        outf(CLR_CMP_MSK, pATIHW->clr_cmp_msk);
97532b578d3Smrg        outf(CLR_CMP_CNTL, pATIHW->clr_cmp_cntl);
97632b578d3Smrg
97732b578d3Smrg        /* Load context mask */
97832b578d3Smrg        ATIMach64WaitForFIFO(pATI, 1);
97932b578d3Smrg        outf(CONTEXT_MASK, pATIHW->context_mask);
98032b578d3Smrg
98132b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264GTPRO)
98232b578d3Smrg        {
98332b578d3Smrg            /* Load texture setup registers */
98432b578d3Smrg            ATIMach64WaitForFIFO(pATI, 2);
98532b578d3Smrg            outf(TEX_SIZE_PITCH, pATIHW->tex_size_pitch);
98632b578d3Smrg            outf(TEX_CNTL, pATIHW->tex_cntl);
98732b578d3Smrg        }
98832b578d3Smrg
98932b578d3Smrg        if (pATI->Block1Base)
99032b578d3Smrg        {
99132b578d3Smrg            /* Load overlay & scaler registers */
99232b578d3Smrg            ATIMach64WaitForFIFO(pATI, 10);
99332b578d3Smrg            outf(OVERLAY_Y_X_START, pATIHW->overlay_y_x_start);
99432b578d3Smrg            outf(OVERLAY_Y_X_END, pATIHW->overlay_y_x_end);
99532b578d3Smrg
99632b578d3Smrg            outf(OVERLAY_GRAPHICS_KEY_CLR, pATIHW->overlay_graphics_key_clr);
99732b578d3Smrg            outf(OVERLAY_GRAPHICS_KEY_MSK, pATIHW->overlay_graphics_key_msk);
99832b578d3Smrg
99932b578d3Smrg            outf(OVERLAY_KEY_CNTL, pATIHW->overlay_key_cntl);
100032b578d3Smrg
100132b578d3Smrg            outf(OVERLAY_SCALE_INC, pATIHW->overlay_scale_inc);
100232b578d3Smrg            outf(OVERLAY_SCALE_CNTL, pATIHW->overlay_scale_cntl);
100332b578d3Smrg
100432b578d3Smrg            outf(SCALER_HEIGHT_WIDTH, pATIHW->scaler_height_width);
100532b578d3Smrg
100632b578d3Smrg            outf(SCALER_TEST, pATIHW->scaler_test);
100732b578d3Smrg
100832b578d3Smrg            outf(VIDEO_FORMAT, pATIHW->video_format);
100932b578d3Smrg
101032b578d3Smrg            if (pATI->Chip < ATI_CHIP_264VTB)
101132b578d3Smrg            {
101232b578d3Smrg                ATIMach64WaitForFIFO(pATI, 4);
101332b578d3Smrg                outf(BUF0_OFFSET, pATIHW->buf0_offset);
101432b578d3Smrg                outf(BUF0_PITCH, pATIHW->buf0_pitch);
101532b578d3Smrg                outf(BUF1_OFFSET, pATIHW->buf1_offset);
101632b578d3Smrg                outf(BUF1_PITCH, pATIHW->buf1_pitch);
101732b578d3Smrg            }
101832b578d3Smrg            else
101932b578d3Smrg            {
102032b578d3Smrg                ATIMach64WaitForFIFO(pATI, 5);
102132b578d3Smrg                outf(SCALER_BUF0_OFFSET, pATIHW->scaler_buf0_offset);
102232b578d3Smrg                outf(SCALER_BUF1_OFFSET, pATIHW->scaler_buf1_offset);
102332b578d3Smrg                outf(SCALER_BUF_PITCH, pATIHW->scaler_buf_pitch);
102432b578d3Smrg
102532b578d3Smrg                outf(OVERLAY_EXCLUSIVE_HORZ, pATIHW->overlay_exclusive_horz);
102632b578d3Smrg                outf(OVERLAY_EXCLUSIVE_VERT, pATIHW->overlay_exclusive_vert);
102732b578d3Smrg
102832b578d3Smrg                if (pATI->Chip >= ATI_CHIP_264GTPRO)
102932b578d3Smrg                {
103032b578d3Smrg                    ATIMach64WaitForFIFO(pATI, 10);
103132b578d3Smrg                    outf(SCALER_COLOUR_CNTL, pATIHW->scaler_colour_cntl);
103232b578d3Smrg
103332b578d3Smrg                    outf(SCALER_H_COEFF0, pATIHW->scaler_h_coeff0);
103432b578d3Smrg                    outf(SCALER_H_COEFF1, pATIHW->scaler_h_coeff1);
103532b578d3Smrg                    outf(SCALER_H_COEFF2, pATIHW->scaler_h_coeff2);
103632b578d3Smrg                    outf(SCALER_H_COEFF3, pATIHW->scaler_h_coeff3);
103732b578d3Smrg                    outf(SCALER_H_COEFF4, pATIHW->scaler_h_coeff4);
103832b578d3Smrg
103932b578d3Smrg                    outf(SCALER_BUF0_OFFSET_U, pATIHW->scaler_buf0_offset_u);
104032b578d3Smrg                    outf(SCALER_BUF0_OFFSET_V, pATIHW->scaler_buf0_offset_v);
104132b578d3Smrg                    outf(SCALER_BUF1_OFFSET_U, pATIHW->scaler_buf1_offset_u);
104232b578d3Smrg                    outf(SCALER_BUF1_OFFSET_V, pATIHW->scaler_buf1_offset_v);
104332b578d3Smrg                }
104432b578d3Smrg            }
104532b578d3Smrg        }
104632b578d3Smrg
104732b578d3Smrg        ATIMach64WaitForIdle(pATI);
104832b578d3Smrg
104932b578d3Smrg        if (pATI->OptionMMIOCache)
105032b578d3Smrg        {
105132b578d3Smrg            /*
105232b578d3Smrg             * Enable write caching for selected MMIO registers.  This can only
105332b578d3Smrg             * be done for those registers whose value does not change without
105432b578d3Smrg             * driver intervention.
105532b578d3Smrg             */
105632b578d3Smrg
105732b578d3Smrg            CacheRegister(SRC_CNTL);
105832b578d3Smrg
105932b578d3Smrg            if (pATI->Chip >= ATI_CHIP_264GTPRO)
106032b578d3Smrg            {
106132b578d3Smrg                CacheRegister(SCALE_3D_CNTL);
106232b578d3Smrg            }
106332b578d3Smrg
106432b578d3Smrg            CacheRegister(HOST_CNTL);
106532b578d3Smrg
106632b578d3Smrg            CacheRegister(PAT_REG0);
106732b578d3Smrg            CacheRegister(PAT_REG1);
106832b578d3Smrg            CacheRegister(PAT_CNTL);
106932b578d3Smrg
107032b578d3Smrg            CacheRegister(SC_LEFT_RIGHT);
107132b578d3Smrg            CacheRegister(SC_TOP_BOTTOM);
107232b578d3Smrg
107332b578d3Smrg            CacheRegister(DP_BKGD_CLR);
107432b578d3Smrg            CacheRegister(DP_FRGD_CLR);
107532b578d3Smrg            CacheRegister(DP_PIX_WIDTH);
107632b578d3Smrg            CacheRegister(DP_MIX);
107732b578d3Smrg
107832b578d3Smrg            CacheRegister(CLR_CMP_CLR);
107932b578d3Smrg            CacheRegister(CLR_CMP_MSK);
108032b578d3Smrg            CacheRegister(CLR_CMP_CNTL);
108132b578d3Smrg
108232b578d3Smrg            if (pATI->Chip >= ATI_CHIP_264GTPRO)
108332b578d3Smrg            {
108432b578d3Smrg                CacheRegister(TEX_SIZE_PITCH);
108532b578d3Smrg            }
108632b578d3Smrg
108732b578d3Smrg            if (pATI->Block1Base)
108832b578d3Smrg            {
108932b578d3Smrg                CacheRegister(OVERLAY_Y_X_START);
109032b578d3Smrg                CacheRegister(OVERLAY_Y_X_END);
109132b578d3Smrg
109232b578d3Smrg                CacheRegister(OVERLAY_GRAPHICS_KEY_CLR);
109332b578d3Smrg                CacheRegister(OVERLAY_GRAPHICS_KEY_MSK);
109432b578d3Smrg
109532b578d3Smrg                CacheRegister(OVERLAY_KEY_CNTL);
109632b578d3Smrg
109732b578d3Smrg                CacheRegister(OVERLAY_SCALE_INC);
109832b578d3Smrg                CacheRegister(OVERLAY_SCALE_CNTL);
109932b578d3Smrg
110032b578d3Smrg                CacheRegister(SCALER_HEIGHT_WIDTH);
110132b578d3Smrg
110232b578d3Smrg                CacheRegister(SCALER_TEST);
110332b578d3Smrg
110432b578d3Smrg                CacheRegister(VIDEO_FORMAT);
110532b578d3Smrg
110632b578d3Smrg                if (pATI->Chip < ATI_CHIP_264VTB)
110732b578d3Smrg                {
110832b578d3Smrg                    CacheRegister(BUF0_OFFSET);
110932b578d3Smrg                    CacheRegister(BUF0_PITCH);
111032b578d3Smrg                    CacheRegister(BUF1_OFFSET);
111132b578d3Smrg                    CacheRegister(BUF1_PITCH);
111232b578d3Smrg                }
111332b578d3Smrg                else
111432b578d3Smrg                {
111532b578d3Smrg                    CacheRegister(SCALER_BUF0_OFFSET);
111632b578d3Smrg                    CacheRegister(SCALER_BUF1_OFFSET);
111732b578d3Smrg                    CacheRegister(SCALER_BUF_PITCH);
111832b578d3Smrg
111932b578d3Smrg                    CacheRegister(OVERLAY_EXCLUSIVE_HORZ);
112032b578d3Smrg                    CacheRegister(OVERLAY_EXCLUSIVE_VERT);
112132b578d3Smrg
112232b578d3Smrg                    if (pATI->Chip >= ATI_CHIP_264GTPRO)
112332b578d3Smrg                    {
112432b578d3Smrg                        CacheRegister(SCALER_COLOUR_CNTL);
112532b578d3Smrg
112632b578d3Smrg                        CacheRegister(SCALER_H_COEFF0);
112732b578d3Smrg                        CacheRegister(SCALER_H_COEFF1);
112832b578d3Smrg                        CacheRegister(SCALER_H_COEFF2);
112932b578d3Smrg                        CacheRegister(SCALER_H_COEFF3);
113032b578d3Smrg                        CacheRegister(SCALER_H_COEFF4);
113132b578d3Smrg
113232b578d3Smrg                        CacheRegister(SCALER_BUF0_OFFSET_U);
113332b578d3Smrg                        CacheRegister(SCALER_BUF0_OFFSET_V);
113432b578d3Smrg                        CacheRegister(SCALER_BUF1_OFFSET_U);
113532b578d3Smrg                        CacheRegister(SCALER_BUF1_OFFSET_V);
113632b578d3Smrg                    }
113732b578d3Smrg                }
113832b578d3Smrg            }
113932b578d3Smrg        }
114032b578d3Smrg    }
114132b578d3Smrg
114232b578d3Smrg#ifndef AVOID_CPIO
114332b578d3Smrg
114432b578d3Smrg    if (pATIHW->crtc == ATI_CRTC_MACH64)
114532b578d3Smrg
114632b578d3Smrg#endif /* AVOID_CPIO */
114732b578d3Smrg
114832b578d3Smrg    {
114932b578d3Smrg        /* Aperture setup */
115032b578d3Smrg        outr(MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
115132b578d3Smrg        outr(MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
115232b578d3Smrg
115332b578d3Smrg        outr(DAC_CNTL, pATIHW->dac_cntl);
115432b578d3Smrg
115532b578d3Smrg        outr(CONFIG_CNTL, pATIHW->config_cntl);
115632b578d3Smrg        outr(BUS_CNTL, pATIHW->bus_cntl);
115732b578d3Smrg
115832b578d3Smrg        if (pATI->Chip >= ATI_CHIP_264VTB)
115932b578d3Smrg        {
116032b578d3Smrg            outr(MEM_BUF_CNTL, pATIHW->mem_buf_cntl);
116132b578d3Smrg            outr(MEM_CNTL, pATIHW->mem_cntl);
116232b578d3Smrg            outr(MPP_CONFIG, pATIHW->mpp_config);
116332b578d3Smrg            outr(MPP_STROBE_SEQ, pATIHW->mpp_strobe_seq);
116432b578d3Smrg            outr(TVO_CNTL, pATIHW->tvo_cntl);
116532b578d3Smrg        }
116632b578d3Smrg    }
116732b578d3Smrg}
116832b578d3Smrg
116932b578d3Smrg/*
117032b578d3Smrg * ATIMach64SaveScreen --
117132b578d3Smrg *
117232b578d3Smrg * This function blanks or unblanks a Mach64 screen.
117332b578d3Smrg */
117432b578d3Smrgvoid
117532b578d3SmrgATIMach64SaveScreen
117632b578d3Smrg(
117732b578d3Smrg    ATIPtr pATI,
117832b578d3Smrg    int    Mode
117932b578d3Smrg)
118032b578d3Smrg{
118132b578d3Smrg    CARD32 crtc_gen_cntl = inr(CRTC_GEN_CNTL);
118232b578d3Smrg
118332b578d3Smrg    switch (Mode)
118432b578d3Smrg    {
118532b578d3Smrg        case SCREEN_SAVER_OFF:
118632b578d3Smrg        case SCREEN_SAVER_FORCER:
118732b578d3Smrg            outr(CRTC_GEN_CNTL, crtc_gen_cntl & ~CRTC_DISPLAY_DIS);
118832b578d3Smrg            break;
118932b578d3Smrg
119032b578d3Smrg        case SCREEN_SAVER_ON:
119132b578d3Smrg        case SCREEN_SAVER_CYCLE:
119232b578d3Smrg            outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_DISPLAY_DIS);
119332b578d3Smrg            break;
119432b578d3Smrg
119532b578d3Smrg        default:
119632b578d3Smrg            break;
119732b578d3Smrg    }
119832b578d3Smrg}
119932b578d3Smrg
120032b578d3Smrg/*
120132b578d3Smrg * ATIMach64SetDPMSMode --
120232b578d3Smrg *
120332b578d3Smrg * This function sets a Mach64's VESA Display Power Management Signaling mode.
120432b578d3Smrg */
120532b578d3Smrgvoid
120632b578d3SmrgATIMach64SetDPMSMode
120732b578d3Smrg(
120832b578d3Smrg    ScrnInfoPtr pScreenInfo,
120932b578d3Smrg    ATIPtr      pATI,
121032b578d3Smrg    int         DPMSMode
121132b578d3Smrg)
121232b578d3Smrg{
121332b578d3Smrg    CARD32 crtc_gen_cntl =
121432b578d3Smrg        inr(CRTC_GEN_CNTL) & ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS);
121532b578d3Smrg
121632b578d3Smrg    switch (DPMSMode)
121732b578d3Smrg    {
121832b578d3Smrg        case DPMSModeOn:        /* HSync on, VSync on */
121932b578d3Smrg            break;
122032b578d3Smrg
122132b578d3Smrg        case DPMSModeStandby:   /* HSync off, VSync on */
122232b578d3Smrg            crtc_gen_cntl |= CRTC_HSYNC_DIS;
122332b578d3Smrg            break;
122432b578d3Smrg
122532b578d3Smrg        case DPMSModeSuspend:   /* HSync on, VSync off */
122632b578d3Smrg            crtc_gen_cntl |= CRTC_VSYNC_DIS;
122732b578d3Smrg            break;
122832b578d3Smrg
122932b578d3Smrg        case DPMSModeOff:       /* HSync off, VSync off */
123032b578d3Smrg            crtc_gen_cntl |= CRTC_HSYNC_DIS | CRTC_VSYNC_DIS;
123132b578d3Smrg            break;
123232b578d3Smrg
123332b578d3Smrg        default:                /* Muffle compiler */
123432b578d3Smrg            return;
123532b578d3Smrg    }
123632b578d3Smrg
123732b578d3Smrg#ifdef XF86DRI_DEVEL
123832b578d3Smrg
123932b578d3Smrg    /* XAA Sync requires the DRM lock if DRI enabled */
124032b578d3Smrg    ATIDRILock(pScreenInfo);
124132b578d3Smrg
124232b578d3Smrg#endif /* XF86DRI_DEVEL */
124332b578d3Smrg
124432b578d3Smrg    ATIMach64Sync(pScreenInfo);
124532b578d3Smrg
124632b578d3Smrg    outr(CRTC_GEN_CNTL, crtc_gen_cntl);
124732b578d3Smrg
124832b578d3Smrg    if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
124932b578d3Smrg    {
125032b578d3Smrg        CARD32 lcd_index = 0;
125132b578d3Smrg
125232b578d3Smrg        /*
125332b578d3Smrg         * ATI's BIOS simply turns the panel on and off, so do the same by
125432b578d3Smrg         * default, but keep the previous behaviour around for reference.
125532b578d3Smrg         */
125632b578d3Smrg        if (pATI->OptionDevel)
125732b578d3Smrg        {
125832b578d3Smrg            CARD32 power_management;
125932b578d3Smrg
126032b578d3Smrg            if (pATI->Chip == ATI_CHIP_264LT)
126132b578d3Smrg            {
126232b578d3Smrg                power_management = inr(POWER_MANAGEMENT);
126332b578d3Smrg            }
126432b578d3Smrg            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
126532b578d3Smrg                        (pATI->Chip == ATI_CHIP_264XL) ||
126632b578d3Smrg                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
126732b578d3Smrg            {
126832b578d3Smrg                lcd_index = inr(LCD_INDEX);
126932b578d3Smrg                power_management = ATIMach64GetLCDReg(LCD_POWER_MANAGEMENT);
127032b578d3Smrg            }
127132b578d3Smrg
127232b578d3Smrg            power_management &= ~(STANDBY_NOW | SUSPEND_NOW);
127332b578d3Smrg
127432b578d3Smrg            switch (DPMSMode)
127532b578d3Smrg            {
127632b578d3Smrg                case DPMSModeOn:
127732b578d3Smrg                    break;
127832b578d3Smrg
127932b578d3Smrg                case DPMSModeStandby:
128032b578d3Smrg                    power_management |= STANDBY_NOW;
128132b578d3Smrg                    break;
128232b578d3Smrg
128332b578d3Smrg                case DPMSModeSuspend:
128432b578d3Smrg                    power_management |= SUSPEND_NOW;
128532b578d3Smrg                    break;
128632b578d3Smrg
128732b578d3Smrg                case DPMSModeOff:
128832b578d3Smrg                    power_management |= STANDBY_NOW | SUSPEND_NOW;  /* ? */
128932b578d3Smrg                    break;
129032b578d3Smrg
129132b578d3Smrg                default:        /* Muffle compiler */
129232b578d3Smrg                    return;
129332b578d3Smrg            }
129432b578d3Smrg
129532b578d3Smrg            if (pATI->Chip == ATI_CHIP_264LT)
129632b578d3Smrg            {
129732b578d3Smrg                outr(POWER_MANAGEMENT, power_management);
129832b578d3Smrg            }
129932b578d3Smrg            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
130032b578d3Smrg                        (pATI->Chip == ATI_CHIP_264XL) ||
130132b578d3Smrg                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
130232b578d3Smrg            {
130332b578d3Smrg                ATIMach64PutLCDReg(LCD_POWER_MANAGEMENT, power_management);
130432b578d3Smrg                outr(LCD_INDEX, lcd_index);
130532b578d3Smrg            }
130632b578d3Smrg        }
130732b578d3Smrg        else
130832b578d3Smrg        {
130932b578d3Smrg            CARD32 lcd_gen_ctrl;
131032b578d3Smrg
131132b578d3Smrg            if (pATI->Chip == ATI_CHIP_264LT)
131232b578d3Smrg            {
131332b578d3Smrg                lcd_gen_ctrl = inr(LCD_GEN_CTRL);
131432b578d3Smrg            }
131532b578d3Smrg            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
131632b578d3Smrg                        (pATI->Chip == ATI_CHIP_264XL) ||
131732b578d3Smrg                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
131832b578d3Smrg            {
131932b578d3Smrg                lcd_index = inr(LCD_INDEX);
132032b578d3Smrg                lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
132132b578d3Smrg            }
132232b578d3Smrg
132332b578d3Smrg            if (DPMSMode == DPMSModeOn)
132432b578d3Smrg                lcd_gen_ctrl |= LCD_ON;
132532b578d3Smrg            else
132632b578d3Smrg                lcd_gen_ctrl &= ~LCD_ON;
132732b578d3Smrg
132832b578d3Smrg            if (pATI->Chip == ATI_CHIP_264LT)
132932b578d3Smrg                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
133032b578d3Smrg            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
133132b578d3Smrg                        (pATI->Chip == ATI_CHIP_264XL) ||
133232b578d3Smrg                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
133332b578d3Smrg            {
133432b578d3Smrg                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
133532b578d3Smrg                outr(LCD_INDEX, lcd_index);
133632b578d3Smrg            }
133732b578d3Smrg        }
133832b578d3Smrg    }
133932b578d3Smrg
134032b578d3Smrg#ifdef XF86DRI_DEVEL
134132b578d3Smrg
134232b578d3Smrg    ATIDRIUnlock(pScreenInfo);
134332b578d3Smrg
134432b578d3Smrg#endif /* XF86DRI_DEVEL */
134532b578d3Smrg
134632b578d3Smrg}
1347