savage_accel.c revision ab47cfaa
1ab47cfaaSmrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.23 2003/12/22 17:48:10 tsi Exp $ */
2ab47cfaaSmrg
3ab47cfaaSmrg/*
4ab47cfaaSmrg *
5ab47cfaaSmrg * Copyright 1995-1997 The XFree86 Project, Inc.
6ab47cfaaSmrg *
7ab47cfaaSmrg */
8ab47cfaaSmrg
9ab47cfaaSmrg/*
10ab47cfaaSmrg * The accel file for the Savage driver.
11ab47cfaaSmrg *
12ab47cfaaSmrg * Created 20/03/97 by Sebastien Marineau for 3.3.6
13ab47cfaaSmrg * Modified 17-Nov-2000 by Tim Roberts for 4.0.1
14ab47cfaaSmrg * Modified Feb-2004 by Alex Deucher - integrating DRI support
15ab47cfaaSmrg * Revision:
16ab47cfaaSmrg *
17ab47cfaaSmrg */
18ab47cfaaSmrg
19ab47cfaaSmrg#ifdef HAVE_CONFIG_H
20ab47cfaaSmrg#include "config.h"
21ab47cfaaSmrg#endif
22ab47cfaaSmrg
23ab47cfaaSmrg#include "savage_driver.h"
24ab47cfaaSmrg#include "savage_regs.h"
25ab47cfaaSmrg#include "savage_bci.h"
26ab47cfaaSmrg#include "savage_streams.h"
27ab47cfaaSmrg
28ab47cfaaSmrg#ifdef XF86DRI
29ab47cfaaSmrg#define _XF86DRI_SERVER_
30ab47cfaaSmrg#include "savage_dri.h"
31ab47cfaaSmrg#endif
32ab47cfaaSmrg
33ab47cfaaSmrgextern int gSavageEntityIndex;
34ab47cfaaSmrg
35ab47cfaaSmrg/* Forward declaration of functions used in the driver */
36ab47cfaaSmrg
37ab47cfaaSmrgunsigned long writedw( unsigned long addr, unsigned long value );
38ab47cfaaSmrgunsigned long readdw( unsigned long addr );
39ab47cfaaSmrgunsigned long readfb( unsigned long addr );
40ab47cfaaSmrgunsigned long writefb( unsigned long addr, unsigned long value );
41ab47cfaaSmrgvoid writescan( unsigned long scan, unsigned long color );
42ab47cfaaSmrg
43ab47cfaaSmrgstatic int GetTileAperturePitch(unsigned long dwWidth, unsigned long dwBpp);
44ab47cfaaSmrgvoid SavageSetGBD_M7(ScrnInfoPtr pScrn);
45ab47cfaaSmrgvoid SavageSetGBD_3D(ScrnInfoPtr pScrn);
46ab47cfaaSmrgvoid SavageSetGBD_Twister(ScrnInfoPtr pScrn);
47ab47cfaaSmrgvoid SavageSetGBD_PM(ScrnInfoPtr pScrn);
48ab47cfaaSmrgvoid SavageSetGBD_2000(ScrnInfoPtr pScrn);
49ab47cfaaSmrg
50ab47cfaaSmrg/*
51ab47cfaaSmrg * This is used to cache the last known value for routines we want to
52ab47cfaaSmrg * call from the debugger.
53ab47cfaaSmrg */
54ab47cfaaSmrg
55ab47cfaaSmrgScrnInfoPtr gpScrn = 0;
56ab47cfaaSmrg
57ab47cfaaSmrg/*
58ab47cfaaSmrg *  returns the aperture pitch for tiled mode.
59ab47cfaaSmrg *  if MM850C_15 = 0 (use NB linear tile mode) the pitch is screen stride aligned to 128bytes
60ab47cfaaSmrg *  if MM850C_15 = 1 (use MS-1 128bit non-linear tile mode),we should do it as follows
61ab47cfaaSmrg *  we now only support the later, and don't use Y range flag,see tile surface register
62ab47cfaaSmrg*/
63ab47cfaaSmrgstatic int GetTileAperturePitch(unsigned long dwWidth, unsigned long dwBpp)
64ab47cfaaSmrg{
65ab47cfaaSmrg    switch (dwBpp) {
66ab47cfaaSmrg        case 4:
67ab47cfaaSmrg        case 8:
68ab47cfaaSmrg            return(0x2000);
69ab47cfaaSmrg            break;
70ab47cfaaSmrg        case 16:
71ab47cfaaSmrg            return(0x1000);
72ab47cfaaSmrg            break;
73ab47cfaaSmrg        case 32:
74ab47cfaaSmrg            return(0x2000);
75ab47cfaaSmrg            break;
76ab47cfaaSmrg        default:
77ab47cfaaSmrg            return(0x2000);
78ab47cfaaSmrg    }
79ab47cfaaSmrg}
80ab47cfaaSmrg
81ab47cfaaSmrgstatic int GetTileAperturePitch2000(unsigned long dwWidth, unsigned long dwBpp, int lDelta)
82ab47cfaaSmrg{
83ab47cfaaSmrg    switch (dwBpp) {
84ab47cfaaSmrg        case 4:
85ab47cfaaSmrg        case 8:
86ab47cfaaSmrg            return(0x2000);
87ab47cfaaSmrg            break;
88ab47cfaaSmrg        case 16:
89ab47cfaaSmrg	    if (lDelta > 0x800)
90ab47cfaaSmrg                return(0x1000);
91ab47cfaaSmrg	    else
92ab47cfaaSmrg	        return(0x800);
93ab47cfaaSmrg            break;
94ab47cfaaSmrg        case 32:
95ab47cfaaSmrg	    if (lDelta > 0x1000)
96ab47cfaaSmrg                return(0x2000);
97ab47cfaaSmrg	    else
98ab47cfaaSmrg	        return(0x1000);
99ab47cfaaSmrg            break;
100ab47cfaaSmrg        default:
101ab47cfaaSmrg            return(0x2000);
102ab47cfaaSmrg    }
103ab47cfaaSmrg}
104ab47cfaaSmrg
105ab47cfaaSmrgvoid
106ab47cfaaSmrgSavageInitialize2DEngine(ScrnInfoPtr pScrn)
107ab47cfaaSmrg{
108ab47cfaaSmrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
109ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
110ab47cfaaSmrg    unsigned int vgaCRIndex = hwp->IOBase + 4;
111ab47cfaaSmrg    unsigned int vgaCRReg = hwp->IOBase + 5;
112ab47cfaaSmrg
113ab47cfaaSmrg    gpScrn = pScrn;
114ab47cfaaSmrg
115ab47cfaaSmrg    VGAOUT16(vgaCRIndex, 0x0140);
116ab47cfaaSmrg    VGAOUT8(vgaCRIndex, 0x31);
117ab47cfaaSmrg    VGAOUT8(vgaCRReg, 0x0c);
118ab47cfaaSmrg
119ab47cfaaSmrg    /* Setup plane masks */
120ab47cfaaSmrg    OUTREG(0x8128, ~0); /* enable all write planes */
121ab47cfaaSmrg    OUTREG(0x812C, ~0); /* enable all read planes */
122ab47cfaaSmrg    OUTREG16(0x8134, 0x27);
123ab47cfaaSmrg    OUTREG16(0x8136, 0x07);
124ab47cfaaSmrg
125ab47cfaaSmrg    switch( psav->Chipset ) {
126ab47cfaaSmrg
127ab47cfaaSmrg    case S3_SAVAGE3D:
128ab47cfaaSmrg    case S3_SAVAGE_MX:
129ab47cfaaSmrg	/* Disable BCI */
130ab47cfaaSmrg	OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
131ab47cfaaSmrg	/* Setup BCI command overflow buffer */
132ab47cfaaSmrg	OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29)); /* tim */
133ab47cfaaSmrg    	/*OUTREG(S3_OVERFLOW_BUFFER, psav->cobOffset >> 11 | 0xE0000000);*/ /* S3 */
134ab47cfaaSmrg	/* Program shadow status update. */
135ab47cfaaSmrg	{
136ab47cfaaSmrg	    unsigned long thresholds = ((psav->bciThresholdLo & 0xffff) << 16) |
137ab47cfaaSmrg		(psav->bciThresholdHi & 0xffff);
138ab47cfaaSmrg	    OUTREG(0x48C10, thresholds);
139ab47cfaaSmrg	    /* used to be 0x78207220 */
140ab47cfaaSmrg	}
141ab47cfaaSmrg	if( psav->ShadowStatus )
142ab47cfaaSmrg	{
143ab47cfaaSmrg	    OUTREG(0x48C0C, psav->ShadowPhysical | 1 );
144ab47cfaaSmrg	    /* Enable BCI and command overflow buffer */
145ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x0E);
146ab47cfaaSmrg	}
147ab47cfaaSmrg	else
148ab47cfaaSmrg	{
149ab47cfaaSmrg	    OUTREG(0x48C0C, 0);
150ab47cfaaSmrg	    /* Enable BCI and command overflow buffer */
151ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x0C);
152ab47cfaaSmrg	}
153ab47cfaaSmrg	break;
154ab47cfaaSmrg
155ab47cfaaSmrg    case S3_SAVAGE4:
156ab47cfaaSmrg    case S3_TWISTER:
157ab47cfaaSmrg    case S3_PROSAVAGE:
158ab47cfaaSmrg    case S3_PROSAVAGEDDR:
159ab47cfaaSmrg    case S3_SUPERSAVAGE:
160ab47cfaaSmrg	/* Disable BCI */
161ab47cfaaSmrg	OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
162ab47cfaaSmrg	if (!psav->disableCOB) {
163ab47cfaaSmrg	    /* Setup BCI command overflow buffer */
164ab47cfaaSmrg	    OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29));
165ab47cfaaSmrg	}
166ab47cfaaSmrg	/* Program shadow status update */ /* AGD: what should this be? */
167ab47cfaaSmrg	{
168ab47cfaaSmrg	    unsigned long thresholds = ((psav->bciThresholdLo & 0x1fffe0) << 11) |
169ab47cfaaSmrg		((psav->bciThresholdHi & 0x1fffe0) >> 5);
170ab47cfaaSmrg	    OUTREG(0x48C10, thresholds);
171ab47cfaaSmrg	}
172ab47cfaaSmrg	/*OUTREG(0x48C10, 0x00700040);*/ /* tim */
173ab47cfaaSmrg        /*OUTREG(0x48C10, 0x0e440f04L);*/ /* S3 */
174ab47cfaaSmrg	if( psav->ShadowStatus )
175ab47cfaaSmrg	{
176ab47cfaaSmrg	    OUTREG(0x48C0C, psav->ShadowPhysical | 1 );
177ab47cfaaSmrg	    if (psav->disableCOB) {
178ab47cfaaSmrg	    	/* Enable BCI without the COB */
179ab47cfaaSmrg		OUTREG(0x48C18, INREG(0x48C18) | 0x0a);
180ab47cfaaSmrg	    } else {
181ab47cfaaSmrg		OUTREG32(0x48C18, INREG32(0x48C18) | 0x0E);
182ab47cfaaSmrg	    }
183ab47cfaaSmrg	}
184ab47cfaaSmrg	else
185ab47cfaaSmrg	{
186ab47cfaaSmrg	    OUTREG(0x48C0C, 0);
187ab47cfaaSmrg	    if (psav->disableCOB) {
188ab47cfaaSmrg	    	/* Enable BCI without the COB */
189ab47cfaaSmrg	    	OUTREG(0x48C18, INREG(0x48C18) | 0x08);
190ab47cfaaSmrg	    } else {
191ab47cfaaSmrg		OUTREG32(0x48C18, INREG32(0x48C18) | 0x0C);
192ab47cfaaSmrg	    }
193ab47cfaaSmrg	}
194ab47cfaaSmrg	break;
195ab47cfaaSmrg
196ab47cfaaSmrg    case S3_SAVAGE2000:
197ab47cfaaSmrg	/* Disable BCI */
198ab47cfaaSmrg	OUTREG(0x48C18, 0);
199ab47cfaaSmrg	/* Setup BCI command overflow buffer */
200ab47cfaaSmrg	OUTREG(0x48C18, (psav->cobOffset >> 7) | (psav->cobIndex));
201ab47cfaaSmrg	if( psav->ShadowStatus )
202ab47cfaaSmrg	{
203ab47cfaaSmrg	    /* Set shadow update threshholds. */
204ab47cfaaSmrg	    /*OUTREG(0x48C10, 0x6090 );
205ab47cfaaSmrg	      OUTREG(0x48C14, 0x70A8 );*/
206ab47cfaaSmrg	    OUTREG(0x48C10, psav->bciThresholdLo >> 2);
207ab47cfaaSmrg	    OUTREG(0x48C14, psav->bciThresholdHi >> 2);
208ab47cfaaSmrg	    /* Enable shadow status update */
209ab47cfaaSmrg	    OUTREG(0x48A30, psav->ShadowPhysical );
210ab47cfaaSmrg	    /* Enable BCI, command overflow buffer and shadow status. */
211ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x00380000 );
212ab47cfaaSmrg	}
213ab47cfaaSmrg	else
214ab47cfaaSmrg	{
215ab47cfaaSmrg	    /* Disable shadow status update */
216ab47cfaaSmrg	    OUTREG(0x48A30, 0);
217ab47cfaaSmrg	    /* Enable BCI and command overflow buffer */
218ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x00280000 );
219ab47cfaaSmrg	}
220ab47cfaaSmrg	break;
221ab47cfaaSmrg    }
222ab47cfaaSmrg
223ab47cfaaSmrg    /* Use and set global bitmap descriptor. */
224ab47cfaaSmrg
225ab47cfaaSmrg    /* For reasons I do not fully understand yet, on the Savage4, the */
226ab47cfaaSmrg    /* write to the GBD register, MM816C, does not "take" at this time. */
227ab47cfaaSmrg    /* Only the low-order byte is acknowledged, resulting in an incorrect */
228ab47cfaaSmrg    /* stride.  Writing the register later, after the mode switch, works */
229ab47cfaaSmrg    /* correctly.  This needs to get resolved. */
230ab47cfaaSmrg
231ab47cfaaSmrg    SavageSetGBD(pScrn);
232ab47cfaaSmrg}
233ab47cfaaSmrg
234ab47cfaaSmrgvoid
235ab47cfaaSmrgSavageSetGBD(ScrnInfoPtr pScrn)
236ab47cfaaSmrg{
237ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
238ab47cfaaSmrg
239ab47cfaaSmrg    UnProtectCRTC();
240ab47cfaaSmrg    UnLockExtRegs();
241ab47cfaaSmrg    VerticalRetraceWait();
242ab47cfaaSmrg
243ab47cfaaSmrg    psav->lDelta = pScrn->virtualX * (pScrn->bitsPerPixel >> 3);
244ab47cfaaSmrg
245ab47cfaaSmrg    /*
246ab47cfaaSmrg     * we can use Option "DisableTile" "TRUE" to disable tile mode
247ab47cfaaSmrg     * if don't disable tile,we only support tile mode under 16/32bpp
248ab47cfaaSmrg     */
249ab47cfaaSmrg    if ((!psav->bDisableTile) && ((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32))) {
250ab47cfaaSmrg        /* tileing in 16/32 BPP */
251ab47cfaaSmrg        psav->bTiled = TRUE;
252ab47cfaaSmrg        psav->lDelta = ((psav->lDelta + 127) >> 7) << 7;
253ab47cfaaSmrg
254ab47cfaaSmrg        if (S3_SAVAGE3D_SERIES(psav->Chipset))
255ab47cfaaSmrg            psav->ulAperturePitch = 0x2000;
256ab47cfaaSmrg	else if (psav->Chipset == S3_SAVAGE2000)
257ab47cfaaSmrg	    psav->ulAperturePitch = GetTileAperturePitch2000(pScrn->virtualX,
258ab47cfaaSmrg							     pScrn->bitsPerPixel,
259ab47cfaaSmrg							     psav->lDelta);
260ab47cfaaSmrg        else
261ab47cfaaSmrg            psav->ulAperturePitch = GetTileAperturePitch(pScrn->virtualX,pScrn->bitsPerPixel);
262ab47cfaaSmrg
263ab47cfaaSmrg        /* Use the aperture for linear screen */
264ab47cfaaSmrg        psav->FBStart = psav->ApertureMap;
265ab47cfaaSmrg    } else {
266ab47cfaaSmrg        psav->bTiled = FALSE;
267ab47cfaaSmrg        /* 32: Alignment for nontiled mode */
268ab47cfaaSmrg        psav->lDelta = ((psav->lDelta + 31) >> 5) << 5;
269ab47cfaaSmrg        psav->ulAperturePitch = psav->lDelta;
270ab47cfaaSmrg    }
271ab47cfaaSmrg
272ab47cfaaSmrg    psav->Bpp = pScrn->bitsPerPixel >> 3;
273ab47cfaaSmrg    psav->cxMemory = psav->lDelta / (psav->Bpp);
274ab47cfaaSmrg    psav->cyMemory = psav->endfb / psav->lDelta - 1;
275ab47cfaaSmrg    /* ??????????? */
276ab47cfaaSmrg    if (psav->cyMemory > 2048)
277ab47cfaaSmrg        psav->cyMemory = 2048;
278ab47cfaaSmrg
279ab47cfaaSmrg    /*
280ab47cfaaSmrg     * If tiling, adjust down psav->cyMemory to the last multiple
281ab47cfaaSmrg     * of a tileheight, so that we don't try to use partial tiles.
282ab47cfaaSmrg     */
283ab47cfaaSmrg    if (psav->bTiled)  {
284ab47cfaaSmrg        psav->cyMemory -= (psav->cyMemory % 16);
285ab47cfaaSmrg    }
286ab47cfaaSmrg
287ab47cfaaSmrg    /*
288ab47cfaaSmrg     *  Initialization per GX-3.
289ab47cfaaSmrg     *
290ab47cfaaSmrg     *  1. MM48C18 - Disable BCI.
291ab47cfaaSmrg     *  2. MM48C0C - Enable updating shadow status
292ab47cfaaSmrg     *              and initialize shadow memory address.
293ab47cfaaSmrg     *  2b. MM48C18 - bit 1 = 1, Enable Command Buffer status updates
294ab47cfaaSmrg     *              (S3_OVERFLOW_BUFFER_PTR)
295ab47cfaaSmrg     *  3. MM48C10 - Initialize command buffer threshold
296ab47cfaaSmrg     *              (S3_BUFFER_THRESHOLD)
297ab47cfaaSmrg     *  4. MM48C14 - Setup command buffer offset and size
298ab47cfaaSmrg     *              (S3_OVERFLOW_BUFFER)
299ab47cfaaSmrg     *  5. MM816C  - Enable BCI.
300ab47cfaaSmrg     *  6. MM48C40 - Setup tiled surface 0 register.
301ab47cfaaSmrg     *  7. CR31 - bit 0 = 0, Disable address offset bits(CR6A_6-0).
302ab47cfaaSmrg     *  8. CR50 - bit 7,6,0 = 111, Use Global Bitmap Descriptor.
303ab47cfaaSmrg     *  9. CR88 - bit 4 = 0, Block write on (linear mode) IFF we know we
304ab47cfaaSmrg     *                       have the right kind of SGRAM memory,
305ab47cfaaSmrg     *                       bit 4 = 1, Block write off (always off if tiling)
306ab47cfaaSmrg     *  10.CR69 - Bit 7 = 1, MM81C0 and 81C4 are used to control
307ab47cfaaSmrg     *                       primary stream.
308ab47cfaaSmrg     *  11.MM8128, MM812c - Setup read/write mask registers
309ab47cfaaSmrg     *  12.MM816C, MM8168 - Set up Global Bitmap Descriptor 1 and 2.
310ab47cfaaSmrg     */
311ab47cfaaSmrg    switch (psav->Chipset) {
312ab47cfaaSmrg        case S3_SAVAGE3D:
313ab47cfaaSmrg	    SavageSetGBD_3D(pScrn);
314ab47cfaaSmrg	    break;
315ab47cfaaSmrg        case S3_SAVAGE_MX:
316ab47cfaaSmrg            SavageSetGBD_M7(pScrn);
317ab47cfaaSmrg            break;
318ab47cfaaSmrg        case S3_SAVAGE4:
319ab47cfaaSmrg        case S3_TWISTER:
320ab47cfaaSmrg        case S3_PROSAVAGE:
321ab47cfaaSmrg        case S3_PROSAVAGEDDR:
322ab47cfaaSmrg            SavageSetGBD_Twister(pScrn);
323ab47cfaaSmrg            break;
324ab47cfaaSmrg        case S3_SUPERSAVAGE:
325ab47cfaaSmrg            SavageSetGBD_PM(pScrn);
326ab47cfaaSmrg            break;
327ab47cfaaSmrg        case S3_SAVAGE2000:
328ab47cfaaSmrg	    SavageSetGBD_2000(pScrn);
329ab47cfaaSmrg	    break;
330ab47cfaaSmrg    }
331ab47cfaaSmrg}
332ab47cfaaSmrg
333ab47cfaaSmrgvoid SavageSetGBD_Twister(ScrnInfoPtr pScrn)
334ab47cfaaSmrg{
335ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
336ab47cfaaSmrg    unsigned long       ulTmp;
337ab47cfaaSmrg    unsigned char byte;
338ab47cfaaSmrg    int bci_enable, tile16, tile32;
339ab47cfaaSmrg
340ab47cfaaSmrg    if (psav->Chipset == S3_SAVAGE4) {
341ab47cfaaSmrg	bci_enable = BCI_ENABLE;
342ab47cfaaSmrg	tile16 = TILE_FORMAT_16BPP;
343ab47cfaaSmrg	tile32 = TILE_FORMAT_32BPP;
344ab47cfaaSmrg    } else {
345ab47cfaaSmrg	bci_enable = BCI_ENABLE_TWISTER;
346ab47cfaaSmrg	tile16 = TILE_DESTINATION;
347ab47cfaaSmrg	tile32 = TILE_DESTINATION;
348ab47cfaaSmrg    }
349ab47cfaaSmrg
350ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
351ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR0_REG,0x00000000);
352ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR1_REG,0x00000000);
353ab47cfaaSmrg
354ab47cfaaSmrg    /*
355ab47cfaaSmrg     *  Program Primary Stream Stride Register.
356ab47cfaaSmrg     *
357ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
358ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
359ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
360ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
361ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
362ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
363ab47cfaaSmrg     */
364ab47cfaaSmrg    if (!psav->bTiled) {
365ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
366ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
367ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
368ab47cfaaSmrg    }
369ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
370ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
371ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
372ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
373ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
374ab47cfaaSmrg    }
375ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
376ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
377ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
378ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
379ab47cfaaSmrg    }
380ab47cfaaSmrg
381ab47cfaaSmrg    /*
382ab47cfaaSmrg     *  CR69, bit 7 = 1
383ab47cfaaSmrg     *  to use MM streams processor registers to control primary stream.
384ab47cfaaSmrg     */
385ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x69);
386ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0x80;
387ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
388ab47cfaaSmrg
389ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
390ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
391ab47cfaaSmrg
392ab47cfaaSmrg    OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
393ab47cfaaSmrg
394ab47cfaaSmrg
395ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
396ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
397ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
398ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
399ab47cfaaSmrg
400ab47cfaaSmrg    /*
401ab47cfaaSmrg     * if MS1NB style linear tiling mode.
402ab47cfaaSmrg     * bit MM850C[15] = 0 select NB linear tile mode.
403ab47cfaaSmrg     * bit MM850C[15] = 1 select MS-1 128-bit non-linear tile mode.
404ab47cfaaSmrg     */
405ab47cfaaSmrg    ulTmp = INREG32(ADVANCED_FUNC_CTRL) | 0x8000; /* use MS-s style tile mode*/
406ab47cfaaSmrg    OUTREG32(ADVANCED_FUNC_CTRL,ulTmp);
407ab47cfaaSmrg
408ab47cfaaSmrg    /*
409ab47cfaaSmrg     * Set up Tiled Surface Registers
410ab47cfaaSmrg     *  Bit 25:20 - Surface width in tiles.
411ab47cfaaSmrg     *  Bit 29 - Y Range Flag.
412ab47cfaaSmrg     *  Bit 31:30 = 00, 4 bpp.
413ab47cfaaSmrg     *            = 01, 8 bpp.
414ab47cfaaSmrg     *            = 10, 16 bpp.
415ab47cfaaSmrg     *            = 11, 32 bpp.
416ab47cfaaSmrg     */
417ab47cfaaSmrg    /*
418ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C - twister/prosavage
419ab47cfaaSmrg     *   bit 24~25: tile format
420ab47cfaaSmrg     *          00: linear
421ab47cfaaSmrg     *          01: destination tiling format
422ab47cfaaSmrg     *          10: texture tiling format
423ab47cfaaSmrg     *          11: reserved
424ab47cfaaSmrg     *   bit 28: block write disble/enable
425ab47cfaaSmrg     *          0: disable
426ab47cfaaSmrg     *          1: enable
427ab47cfaaSmrg     */
428ab47cfaaSmrg    /*
429ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C - savage4
430ab47cfaaSmrg     *   bit 24~25: tile format
431ab47cfaaSmrg     *          00: linear
432ab47cfaaSmrg     *          01: reserved
433ab47cfaaSmrg     *          10: 16 bpp tiles
434ab47cfaaSmrg     *          11: 32 bpp tiles
435ab47cfaaSmrg     *   bit 28: block write disable/enable
436ab47cfaaSmrg     *          0: enable
437ab47cfaaSmrg     *          1: disable
438ab47cfaaSmrg     */
439ab47cfaaSmrg    if (!psav->bTiled) {
440ab47cfaaSmrg        /*
441ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
442ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
443ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
444ab47cfaaSmrg         */
445ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
446ab47cfaaSmrg    }
447ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
448ab47cfaaSmrg	psav->GlobalBD.bd1.HighPart.ResBWTile = tile16; /* 16 bpp/destination tiling format */
449ab47cfaaSmrg
450ab47cfaaSmrg        ulTmp = (((pScrn->virtualX + 0x3F) & 0x0000FFC0) >> 6) << 20;
451ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
452ab47cfaaSmrg    }
453ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
454ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32; /* 32 bpp/destination tiling format */
455ab47cfaaSmrg
456ab47cfaaSmrg        ulTmp = ( ((pScrn->virtualX + 0x1F) & 0x0000FFE0) >> 5) << 20;
457ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
458ab47cfaaSmrg    }
459ab47cfaaSmrg
460ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write - was 0 */
461ab47cfaaSmrg    /* HW uses width */
462ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short) psav->lDelta / (pScrn->bitsPerPixel >> 3);
463ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
464ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
465ab47cfaaSmrg
466ab47cfaaSmrg
467ab47cfaaSmrg    /*
468ab47cfaaSmrg     * CR88, bit 4 - Block write enabled/disabled.
469ab47cfaaSmrg     *
470ab47cfaaSmrg     *      Note: Block write must be disabled when writing to tiled
471ab47cfaaSmrg     *            memory.  Even when writing to non-tiled memory, block
472ab47cfaaSmrg     *            write should only be enabled for certain types of SGRAM.
473ab47cfaaSmrg     */
474ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x88);
475ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | DISABLE_BLOCK_WRITE_2D;
476ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
477ab47cfaaSmrg
478ab47cfaaSmrg    /*
479ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
480ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
481ab47cfaaSmrg     *                  at A000:0.
482ab47cfaaSmrg     */
483ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
484ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
485ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte); /* perhaps this should be 0x0c */
486ab47cfaaSmrg
487ab47cfaaSmrg    /* turn on screen */
488ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
489ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
490ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
491ab47cfaaSmrg
492ab47cfaaSmrg    /* program the GBD and SBD's */
493ab47cfaaSmrg    OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart);
494ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
495ab47cfaaSmrg    OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
496ab47cfaaSmrg    OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
497ab47cfaaSmrg    OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
498ab47cfaaSmrg    OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
499ab47cfaaSmrg}
500ab47cfaaSmrg
501ab47cfaaSmrgvoid SavageSetGBD_3D(ScrnInfoPtr pScrn)
502ab47cfaaSmrg{
503ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
504ab47cfaaSmrg    unsigned long       ulTmp;
505ab47cfaaSmrg    unsigned char byte;
506ab47cfaaSmrg    int bci_enable, tile16, tile32;
507ab47cfaaSmrg
508ab47cfaaSmrg    bci_enable = BCI_ENABLE;
509ab47cfaaSmrg    tile16 = TILE_FORMAT_16BPP;
510ab47cfaaSmrg    tile32 = TILE_FORMAT_32BPP;
511ab47cfaaSmrg
512ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
513ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR0_REG,0x00000000);
514ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR1_REG,0x00000000);
515ab47cfaaSmrg
516ab47cfaaSmrg    /*
517ab47cfaaSmrg     *  Program Primary Stream Stride Register.
518ab47cfaaSmrg     *
519ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
520ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
521ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
522ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
523ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
524ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
525ab47cfaaSmrg     */
526ab47cfaaSmrg    if (!psav->bTiled) {
527ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
528ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
529ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
530ab47cfaaSmrg    }
531ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
532ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
533ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
534ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
535ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
536ab47cfaaSmrg    }
537ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
538ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
539ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
540ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
541ab47cfaaSmrg    }
542ab47cfaaSmrg
543ab47cfaaSmrg    /*
544ab47cfaaSmrg     *  CR69, bit 7 = 1
545ab47cfaaSmrg     *  to use MM streams processor registers to control primary stream.
546ab47cfaaSmrg     */
547ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x69);
548ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0x80;
549ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
550ab47cfaaSmrg
551ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
552ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
553ab47cfaaSmrg
554ab47cfaaSmrg    OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
555ab47cfaaSmrg
556ab47cfaaSmrg
557ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
558ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
559ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
560ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
561ab47cfaaSmrg
562ab47cfaaSmrg    /*
563ab47cfaaSmrg     * if MS1NB style linear tiling mode.
564ab47cfaaSmrg     * bit MM850C[15] = 0 select NB linear tile mode.
565ab47cfaaSmrg     * bit MM850C[15] = 1 select MS-1 128-bit non-linear tile mode.
566ab47cfaaSmrg     */
567ab47cfaaSmrg    ulTmp = INREG32(ADVANCED_FUNC_CTRL) | 0x8000; /* use MS-s style tile mode*/
568ab47cfaaSmrg    OUTREG32(ADVANCED_FUNC_CTRL,ulTmp);
569ab47cfaaSmrg
570ab47cfaaSmrg    /*
571ab47cfaaSmrg     * Tiled Surface 0 Registers MM48C40:
572ab47cfaaSmrg     *  bit 0~23: tile surface 0 frame buffer offset
573ab47cfaaSmrg     *  bit 24~29:tile surface 0 width
574ab47cfaaSmrg     *  bit 30~31:tile surface 0 bits/pixel
575ab47cfaaSmrg     *            00: reserved
576ab47cfaaSmrg     *            01, 8 bits
577ab47cfaaSmrg     *            10, 16 Bits.
578ab47cfaaSmrg     *            11, 32 Bits.
579ab47cfaaSmrg     */
580ab47cfaaSmrg    /*
581ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C
582ab47cfaaSmrg     *   bit 24~25: tile format
583ab47cfaaSmrg     *          00: linear
584ab47cfaaSmrg     *          01: reserved
585ab47cfaaSmrg     *          10: 16 bpp tiles
586ab47cfaaSmrg     *          11: 32 bpp tiles
587ab47cfaaSmrg     *   bit 28: block write disable/enable
588ab47cfaaSmrg     *          0: enable
589ab47cfaaSmrg     *          1: disable
590ab47cfaaSmrg     */
591ab47cfaaSmrg    if (!psav->bTiled) {
592ab47cfaaSmrg        /*
593ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
594ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
595ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
596ab47cfaaSmrg         */
597ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
598ab47cfaaSmrg    }
599ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
600ab47cfaaSmrg	psav->GlobalBD.bd1.HighPart.ResBWTile = tile16; /* 16 bpp/destination tiling format */
601ab47cfaaSmrg
602ab47cfaaSmrg        ulTmp = (((pScrn->virtualX + 0x3F) & 0x0000FFC0) >> 6) << 24;
603ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
604ab47cfaaSmrg    }
605ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
606ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32; /* 32 bpp/destination tiling format */
607ab47cfaaSmrg
608ab47cfaaSmrg        ulTmp = ( ((pScrn->virtualX + 0x1F) & 0x0000FFE0) >> 5) << 24;
609ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
610ab47cfaaSmrg    }
611ab47cfaaSmrg
612ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write - was 0 */
613ab47cfaaSmrg    /* HW uses width */
614ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short) psav->lDelta / (pScrn->bitsPerPixel >> 3);
615ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
616ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
617ab47cfaaSmrg
618ab47cfaaSmrg
619ab47cfaaSmrg    /*
620ab47cfaaSmrg     * CR88, bit 4 - Block write enabled/disabled.
621ab47cfaaSmrg     *
622ab47cfaaSmrg     *      Note: Block write must be disabled when writing to tiled
623ab47cfaaSmrg     *            memory.  Even when writing to non-tiled memory, block
624ab47cfaaSmrg     *            write should only be enabled for certain types of SGRAM.
625ab47cfaaSmrg     */
626ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x88);
627ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | DISABLE_BLOCK_WRITE_2D;
628ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
629ab47cfaaSmrg
630ab47cfaaSmrg    /*
631ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
632ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
633ab47cfaaSmrg     *                  at A000:0.
634ab47cfaaSmrg     */
635ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
636ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
637ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte); /* perhaps this should be 0x0c */
638ab47cfaaSmrg
639ab47cfaaSmrg    /* turn on screen */
640ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
641ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
642ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
643ab47cfaaSmrg
644ab47cfaaSmrg    /* program the GBD and SBD's */
645ab47cfaaSmrg    OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart);
646ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
647ab47cfaaSmrg    OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
648ab47cfaaSmrg    OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
649ab47cfaaSmrg    OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
650ab47cfaaSmrg    OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
651ab47cfaaSmrg}
652ab47cfaaSmrg
653ab47cfaaSmrgvoid SavageSetGBD_M7(ScrnInfoPtr pScrn)
654ab47cfaaSmrg{
655ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
656ab47cfaaSmrg    unsigned long ulTmp;
657ab47cfaaSmrg    unsigned char byte;
658ab47cfaaSmrg    int bci_enable, tile16, tile32;
659ab47cfaaSmrg
660ab47cfaaSmrg    bci_enable = BCI_ENABLE;
661ab47cfaaSmrg    tile16 = TILE_FORMAT_16BPP;
662ab47cfaaSmrg    tile32 = TILE_FORMAT_32BPP;
663ab47cfaaSmrg
664ab47cfaaSmrg
665ab47cfaaSmrg    /* following is the enable case */
666ab47cfaaSmrg
667ab47cfaaSmrg    /* SR01:turn off screen */
668ab47cfaaSmrg    OUTREG8 (SEQ_ADDRESS_REG,0x01);
669ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) | 0x20;
670ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
671ab47cfaaSmrg
672ab47cfaaSmrg    /*
673ab47cfaaSmrg     * CR67_3:
674ab47cfaaSmrg     *  = 1  stream processor MMIO address and stride register
675ab47cfaaSmrg     *       are used to control the primary stream
676ab47cfaaSmrg     *  = 0  standard VGA address and stride registers
677ab47cfaaSmrg     *       are used to control the primary streams
678ab47cfaaSmrg     */
679ab47cfaaSmrg    if (psav->IsPrimary) {
680ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
681ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
682ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
683ab47cfaaSmrg    } else if (psav->IsSecondary) {
684ab47cfaaSmrg    	/* IGA 2 */
685ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
686ab47cfaaSmrg
687ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
688ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
689ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
690ab47cfaaSmrg
691ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
692ab47cfaaSmrg    } else {
693ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
694ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
695ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
696ab47cfaaSmrg    	/* IGA 2 */
697ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
698ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
699ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
700ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
701ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
702ab47cfaaSmrg    }
703ab47cfaaSmrg    /* Set primary stream to bank 0 */
704ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG, MEMORY_CTRL0_REG);/* CRCA */
705ab47cfaaSmrg    byte =  INREG8(CRT_DATA_REG) & ~(MEM_PS1 + MEM_PS2) ;
706ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
707ab47cfaaSmrg#if 0
708ab47cfaaSmrg    /*
709ab47cfaaSmrg     * if we have 8MB of frame buffer here then we must really be a 16MB
710ab47cfaaSmrg     * card and that means that the second device is always in the upper
711ab47cfaaSmrg     * bank of memory (MHS)
712ab47cfaaSmrg     */
713ab47cfaaSmrg    if (psav->videoRambytes >= 0x800000) {
714ab47cfaaSmrg        /* 16MB Video Memory cursor is at the end in Bank 1 */
715ab47cfaaSmrg        byte |= 0x3;
716ab47cfaaSmrg        OUTREG16(CRT_ADDRESS_REG, (byte << 8) | MEMORY_CTRL0_REG);
717ab47cfaaSmrg    }
718ab47cfaaSmrg#endif
719ab47cfaaSmrg
720ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
721ab47cfaaSmrg    if (psav->IsPrimary) {
722ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
723ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
724ab47cfaaSmrg    } else if (psav->IsSecondary) {
725ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
726ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
727ab47cfaaSmrg    } else {
728ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
729ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
730ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
731ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
732ab47cfaaSmrg    }
733ab47cfaaSmrg
734ab47cfaaSmrg    /*
735ab47cfaaSmrg     *  Program Primary Stream Stride Register.
736ab47cfaaSmrg     *
737ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
738ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
739ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
740ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
741ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
742ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
743ab47cfaaSmrg     */
744ab47cfaaSmrg    if (!psav->bTiled) {
745ab47cfaaSmrg 	if (psav->IsPrimary) {
746ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
747ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
748ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
749ab47cfaaSmrg	} else if (psav->IsSecondary) {
750ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
751ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
752ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
753ab47cfaaSmrg	} else {
754ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
755ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
756ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
757ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
758ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
759ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
760ab47cfaaSmrg	}
761ab47cfaaSmrg
762ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 16) {
763ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
764ab47cfaaSmrg	if (psav->IsPrimary) {
765ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
766ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
767ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
768ab47cfaaSmrg        } else if (psav->IsSecondary) {
769ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
770ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
771ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
772ab47cfaaSmrg        } else {
773ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
774ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
775ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
776ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
777ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
778ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
779ab47cfaaSmrg	}
780ab47cfaaSmrg
781ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 32) {
782ab47cfaaSmrg	if (psav->IsPrimary) {
783ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
784ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
785ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
786ab47cfaaSmrg	} else if (psav->IsSecondary) {
787ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
788ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
789ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
790ab47cfaaSmrg	} else {
791ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
792ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
793ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
794ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
795ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
796ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
797ab47cfaaSmrg	}
798ab47cfaaSmrg    }
799ab47cfaaSmrg
800ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
801ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
802ab47cfaaSmrg
803ab47cfaaSmrg    if (!psav->IsSecondary)
804ab47cfaaSmrg    	OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
805ab47cfaaSmrg
806ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
807ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
808ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
809ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
810ab47cfaaSmrg
811ab47cfaaSmrg    /*
812ab47cfaaSmrg     * CR78, bit 3  - Block write enabled(1)/disabled(0).
813ab47cfaaSmrg     *       bit 2  - Block write cycle time(0:2 cycles,1: 1 cycle)
814ab47cfaaSmrg     *      Note: Block write must be disabled when writing to tiled
815ab47cfaaSmrg     *            memory.  Even when writing to non-tiled memory, block
816ab47cfaaSmrg     *            write should only be enabled for certain types of SGRAM.
817ab47cfaaSmrg     */
818ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x78);
819ab47cfaaSmrg    /*byte = INREG8(CRT_DATA_REG) & ~0x0C;*/
820ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xfb;
821ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
822ab47cfaaSmrg
823ab47cfaaSmrg    /*
824ab47cfaaSmrg     * Tiled Surface 0 Registers MM48C40:
825ab47cfaaSmrg     *  bit 0~23: tile surface 0 frame buffer offset
826ab47cfaaSmrg     *  bit 24~29:tile surface 0 width
827ab47cfaaSmrg     *  bit 30~31:tile surface 0 bits/pixel
828ab47cfaaSmrg     *            00: reserved
829ab47cfaaSmrg     *            01, 8 bits
830ab47cfaaSmrg     *            10, 16 Bits.
831ab47cfaaSmrg     *            11, 32 Bits.
832ab47cfaaSmrg     */
833ab47cfaaSmrg    /*
834ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C
835ab47cfaaSmrg     *   bit 24~25: tile format
836ab47cfaaSmrg     *          00: linear
837ab47cfaaSmrg     *          01: reserved
838ab47cfaaSmrg     *          10: 16 bit
839ab47cfaaSmrg     *          11: 32 bit
840ab47cfaaSmrg     *   bit 28: block write disble/enable
841ab47cfaaSmrg     *          0: enable
842ab47cfaaSmrg     *          1: disable
843ab47cfaaSmrg     */
844ab47cfaaSmrg    if (!psav->bTiled) {
845ab47cfaaSmrg        /*
846ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
847ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
848ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
849ab47cfaaSmrg         */
850ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
851ab47cfaaSmrg
852ab47cfaaSmrg    }
853ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
854ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* 16 bit */
855ab47cfaaSmrg
856ab47cfaaSmrg	ulTmp =  ((psav->lDelta / 2) >> 6) << 24;
857ab47cfaaSmrg	if (psav->IsSecondary)
858ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP16 | pScrn->fbOffset);
859ab47cfaaSmrg	else
860ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16 | pScrn->fbOffset);
861ab47cfaaSmrg    }
862ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
863ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* 32 bit */
864ab47cfaaSmrg
865ab47cfaaSmrg	ulTmp =  ((psav->lDelta / 4) >> 5) << 24;
866ab47cfaaSmrg	if (psav->IsSecondary)
867ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP32 | pScrn->fbOffset);
868ab47cfaaSmrg	else
869ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32 | pScrn->fbOffset);
870ab47cfaaSmrg    }
871ab47cfaaSmrg
872ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
873ab47cfaaSmrg    /* HW uses width */
874ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
875ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
876ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
877ab47cfaaSmrg
878ab47cfaaSmrg
879ab47cfaaSmrg    /*
880ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
881ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
882ab47cfaaSmrg     *                  at A000:0.
883ab47cfaaSmrg     */
884ab47cfaaSmrg#if 0
885ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
886ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
887ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
888ab47cfaaSmrg#endif
889ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
890ab47cfaaSmrg    byte = (INREG8(CRT_DATA_REG) | 0x04) & 0xFE;
891ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
892ab47cfaaSmrg
893ab47cfaaSmrg    if (!psav->IsSecondary) {
894ab47cfaaSmrg    	/* program the GBD and SBD's */
895ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
896ab47cfaaSmrg    	/* 8: bci enable */
897ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
898ab47cfaaSmrg                             | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
899ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
900ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
901ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
902ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
903ab47cfaaSmrg    }
904ab47cfaaSmrg
905ab47cfaaSmrg    /* turn on screen */
906ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
907ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0X20;
908ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
909ab47cfaaSmrg}
910ab47cfaaSmrg
911ab47cfaaSmrgvoid SavageSetGBD_PM(ScrnInfoPtr pScrn)
912ab47cfaaSmrg{
913ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
914ab47cfaaSmrg    unsigned long ulTmp;
915ab47cfaaSmrg    unsigned char byte;
916ab47cfaaSmrg    int bci_enable, tile16, tile32;
917ab47cfaaSmrg
918ab47cfaaSmrg
919ab47cfaaSmrg    bci_enable = BCI_ENABLE_TWISTER;
920ab47cfaaSmrg    tile16 = TILE_DESTINATION;
921ab47cfaaSmrg    tile32 = TILE_DESTINATION;
922ab47cfaaSmrg
923ab47cfaaSmrg
924ab47cfaaSmrg    /* following is the enable case */
925ab47cfaaSmrg
926ab47cfaaSmrg    /* SR01:turn off screen */
927ab47cfaaSmrg    OUTREG8 (SEQ_ADDRESS_REG,0x01);
928ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) | 0x20;
929ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
930ab47cfaaSmrg
931ab47cfaaSmrg    /*
932ab47cfaaSmrg     * CR67_3:
933ab47cfaaSmrg     *  = 1  stream processor MMIO address and stride register
934ab47cfaaSmrg     *       are used to control the primary stream
935ab47cfaaSmrg     *  = 0  standard VGA address and stride registers
936ab47cfaaSmrg     *       are used to control the primary streams
937ab47cfaaSmrg     */
938ab47cfaaSmrg    if (psav->IsPrimary) {
939ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
940ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
941ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
942ab47cfaaSmrg    } else if (psav->IsSecondary) {
943ab47cfaaSmrg    	/* IGA 2 */
944ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
945ab47cfaaSmrg
946ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
947ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
948ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
949ab47cfaaSmrg
950ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
951ab47cfaaSmrg    } else {
952ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
953ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
954ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
955ab47cfaaSmrg    	/* IGA 2 */
956ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
957ab47cfaaSmrg
958ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
959ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
960ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
961ab47cfaaSmrg
962ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
963ab47cfaaSmrg    }
964ab47cfaaSmrg
965ab47cfaaSmrg    /*
966ab47cfaaSmrg     * load ps1 active registers as determined by MM81C0/81C4
967ab47cfaaSmrg     * load ps2 active registers as determined by MM81B0/81B4
968ab47cfaaSmrg     */
969ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x65);
970ab47cfaaSmrg    byte =  INREG8(CRT_DATA_REG) | 0x03;
971ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
972ab47cfaaSmrg
973ab47cfaaSmrg    /*
974ab47cfaaSmrg     *  Program Primary Stream Stride Register.
975ab47cfaaSmrg     *
976ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
977ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
978ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
979ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
980ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
981ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
982ab47cfaaSmrg     */
983ab47cfaaSmrg    if (!psav->bTiled) {
984ab47cfaaSmrg	if (psav->IsPrimary) {
985ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
986ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
987ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
988ab47cfaaSmrg	} else if (psav->IsSecondary) {
989ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
990ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
991ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
992ab47cfaaSmrg	} else {
993ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
994ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
995ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
996ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
997ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
998ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
999ab47cfaaSmrg	}
1000ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 16) {
1001ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
1002ab47cfaaSmrg	if (psav->IsPrimary) {
1003ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1004ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1005ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1006ab47cfaaSmrg	} else if (psav->IsSecondary) {
1007ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1008ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1009ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1010ab47cfaaSmrg	} else {
1011ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1012ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1013ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1014ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1015ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1016ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1017ab47cfaaSmrg	}
1018ab47cfaaSmrg
1019ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 32) {
1020ab47cfaaSmrg	if (psav->IsPrimary) {
1021ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1022ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1023ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1024ab47cfaaSmrg	} else if (psav->IsSecondary) {
1025ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1026ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1027ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1028ab47cfaaSmrg	} else {
1029ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1030ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1031ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1032ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1033ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1034ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1035ab47cfaaSmrg	}
1036ab47cfaaSmrg    }
1037ab47cfaaSmrg
1038ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
1039ab47cfaaSmrg    if (psav->IsPrimary) {
1040ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset);
1041ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR1,0x80000000);
1042ab47cfaaSmrg    } else if (psav->IsSecondary) {
1043ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR0,(pScrn->fbOffset & 0xfffffffc) | 0x80000000);
1044ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0xffffffc);
1045ab47cfaaSmrg    } else {
1046ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset);
1047ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR1,0x80000000);
1048ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR0,(pScrn->fbOffset & 0xfffffffc) | 0x80000000);
1049ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0xffffffc);
1050ab47cfaaSmrg    }
1051ab47cfaaSmrg
1052ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
1053ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
1054ab47cfaaSmrg
1055ab47cfaaSmrg    if (!psav->IsSecondary)
1056ab47cfaaSmrg    	/* bit 28:block write disable */
1057ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
1058ab47cfaaSmrg
1059ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
1060ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
1061ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
1062ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
1063ab47cfaaSmrg
1064ab47cfaaSmrg    if (!psav->bTiled) {
1065ab47cfaaSmrg        /*
1066ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
1067ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
1068ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
1069ab47cfaaSmrg         */
1070ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
1071ab47cfaaSmrg
1072ab47cfaaSmrg    }
1073ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
1074ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* tile format destination */
1075ab47cfaaSmrg
1076ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x3f) & 0x0000ffc0) >> 6) << 20;
1077ab47cfaaSmrg	if (psav->IsSecondary)
1078ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP16 | (pScrn->fbOffset>>6));
1079ab47cfaaSmrg	else
1080ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16 | (pScrn->fbOffset>>6));
1081ab47cfaaSmrg    }
1082ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
1083ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* tile format destination */
1084ab47cfaaSmrg
1085ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x1f) & 0x0000ffe0) >> 5) << 20;
1086ab47cfaaSmrg	if (psav->IsSecondary)
1087ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP32 | (pScrn->fbOffset>>6));
1088ab47cfaaSmrg	else
1089ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32 | (pScrn->fbOffset>>6));
1090ab47cfaaSmrg    }
1091ab47cfaaSmrg
1092ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
1093ab47cfaaSmrg    /* HW uses width */
1094ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
1095ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
1096ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
1097ab47cfaaSmrg
1098ab47cfaaSmrg    /*
1099ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
1100ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
1101ab47cfaaSmrg     *                  at A000:0.
1102ab47cfaaSmrg     */
1103ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG);
1104ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
1105ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
1106ab47cfaaSmrg
1107ab47cfaaSmrg    if (!psav->IsSecondary) {
1108ab47cfaaSmrg    	/* program the GBD and SBDs */
1109ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
1110ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
1111ab47cfaaSmrg			     | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
1112ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
1113ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1114ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
1115ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1116ab47cfaaSmrg    }
1117ab47cfaaSmrg
1118ab47cfaaSmrg    /* turn on screen */
1119ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
1120ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
1121ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
1122ab47cfaaSmrg}
1123ab47cfaaSmrg
1124ab47cfaaSmrgvoid SavageSetGBD_2000(ScrnInfoPtr pScrn)
1125ab47cfaaSmrg{
1126ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1127ab47cfaaSmrg    unsigned long ulTmp, ulYRange;
1128ab47cfaaSmrg    unsigned char byte;
1129ab47cfaaSmrg    int bci_enable, tile16, tile32;
1130ab47cfaaSmrg
1131ab47cfaaSmrg    bci_enable = BCI_ENABLE_TWISTER;
1132ab47cfaaSmrg    tile16 = TILE_DESTINATION;
1133ab47cfaaSmrg    tile32 = TILE_DESTINATION;
1134ab47cfaaSmrg
1135ab47cfaaSmrg    if (pScrn->virtualX > 1024)
1136ab47cfaaSmrg      ulYRange = 0x40000000;
1137ab47cfaaSmrg    else
1138ab47cfaaSmrg      ulYRange = 0x20000000;
1139ab47cfaaSmrg
1140ab47cfaaSmrg
1141ab47cfaaSmrg    /* following is the enable case */
1142ab47cfaaSmrg
1143ab47cfaaSmrg    /* SR01:turn off screen */
1144ab47cfaaSmrg    OUTREG8 (SEQ_ADDRESS_REG,0x01);
1145ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) | 0x20;
1146ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
1147ab47cfaaSmrg
1148ab47cfaaSmrg
1149ab47cfaaSmrg    /* MM81C0 and 81B0 are used to control primary stream. */
1150ab47cfaaSmrg    OUTREG32(PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset);
1151ab47cfaaSmrg    OUTREG32(PRI_STREAM2_FBUF_ADDR0, pScrn->fbOffset);
1152ab47cfaaSmrg
1153ab47cfaaSmrg
1154ab47cfaaSmrg    /*
1155ab47cfaaSmrg     *  Program Primary Stream Stride Register.
1156ab47cfaaSmrg     *
1157ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
1158ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
1159ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
1160ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
1161ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
1162ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
1163ab47cfaaSmrg     */
1164ab47cfaaSmrg    if (!psav->bTiled) {
1165ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE,
1166ab47cfaaSmrg		 ((psav->lDelta << 4) & 0x7ff0));
1167ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE,
1168ab47cfaaSmrg                 ((psav->lDelta << 4) & 0x7ff0));
1169ab47cfaaSmrg    } else {
1170ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE,
1171ab47cfaaSmrg		 (0x80000000 |((psav->lDelta << 4) & 0x7ff0)));
1172ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE,
1173ab47cfaaSmrg                 (0x80000000 |((psav->lDelta << 4) & 0x7ff0)));
1174ab47cfaaSmrg    }
1175ab47cfaaSmrg
1176ab47cfaaSmrg    /*
1177ab47cfaaSmrg     * CR67_3:
1178ab47cfaaSmrg     *  = 1  stream processor MMIO address and stride register
1179ab47cfaaSmrg     *       are used to control the primary stream
1180ab47cfaaSmrg     *  = 0  standard VGA address and stride registers
1181ab47cfaaSmrg     *       are used to control the primary streams
1182ab47cfaaSmrg     */
1183ab47cfaaSmrg
1184ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x67);
1185ab47cfaaSmrg    byte =  INREG8(CRT_DATA_REG) | 0x08;
1186ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
1187ab47cfaaSmrg
1188ab47cfaaSmrg
1189ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
1190ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
1191ab47cfaaSmrg
1192ab47cfaaSmrg    /* bit 28:block write disable */
1193ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
1194ab47cfaaSmrg
1195ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
1196ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
1197ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
1198ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
1199ab47cfaaSmrg
1200ab47cfaaSmrg    /* CR73 bit 5 = 0 block write disable */
1201ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x73);
1202ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & ~0x20;
1203ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
1204ab47cfaaSmrg
1205ab47cfaaSmrg    if (!psav->bTiled) {
1206ab47cfaaSmrg        /*
1207ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
1208ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
1209ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
1210ab47cfaaSmrg         */
1211ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
1212ab47cfaaSmrg
1213ab47cfaaSmrg    }
1214ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
1215ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* tile format destination */
1216ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x3f) & 0x0000ffc0) >> 6) << 23;
1217ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16_2000 | ulYRange);
1218ab47cfaaSmrg        ulTmp |= (TILED_SURF_BPP16_2000 | ulYRange);
1219ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1220ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1221ab47cfaaSmrg    }
1222ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
1223ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* tile format destination */
1224ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x1f) & 0x0000ffe0) >> 5) << 23;
1225ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32_2000 | ulYRange);
1226ab47cfaaSmrg        ulTmp |= (TILED_SURF_BPP32_2000 | ulYRange);
1227ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1228ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1229ab47cfaaSmrg    }
1230ab47cfaaSmrg
1231ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
1232ab47cfaaSmrg    /* HW uses width */
1233ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
1234ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
1235ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
1236ab47cfaaSmrg
1237ab47cfaaSmrg    /*
1238ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
1239ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
1240ab47cfaaSmrg     *                  at A000:0.
1241ab47cfaaSmrg     */
1242ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG);
1243ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
1244ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
1245ab47cfaaSmrg
1246ab47cfaaSmrg    /* program the GBD and SBDs */
1247ab47cfaaSmrg    OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
1248ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
1249ab47cfaaSmrg			     | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
1250ab47cfaaSmrg    OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
1251ab47cfaaSmrg    OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1252ab47cfaaSmrg    OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
1253ab47cfaaSmrg    OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1254ab47cfaaSmrg
1255ab47cfaaSmrg    /* turn on screen */
1256ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
1257ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
1258ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
1259ab47cfaaSmrg}
1260ab47cfaaSmrg
1261ab47cfaaSmrgstatic
1262ab47cfaaSmrgvoid SavageRestoreAccelState(ScrnInfoPtr pScrn)
1263ab47cfaaSmrg{
1264ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1265ab47cfaaSmrg
1266ab47cfaaSmrg    psav->WaitIdleEmpty(psav);
1267ab47cfaaSmrg
1268ab47cfaaSmrg    return;
1269ab47cfaaSmrg}
1270ab47cfaaSmrg
1271ab47cfaaSmrg/* Acceleration init function, sets up pointers to our accelerated functions */
1272ab47cfaaSmrg
1273ab47cfaaSmrgBool
1274ab47cfaaSmrgSavageInitAccel(ScreenPtr pScreen)
1275ab47cfaaSmrg{
1276ab47cfaaSmrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1277ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1278ab47cfaaSmrg
1279ab47cfaaSmrg#ifdef XF86DRI
1280ab47cfaaSmrg    if (psav->directRenderingEnabled) {
1281ab47cfaaSmrg        SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
1282ab47cfaaSmrg        BoxRec MemBox;
1283ab47cfaaSmrg        int cpp = pScrn->bitsPerPixel / 8;
1284ab47cfaaSmrg        int widthBytes = psav->lDelta;
1285ab47cfaaSmrg        int bufferSize = ((pScrn->virtualY * widthBytes + SAVAGE_BUFFER_ALIGN)
1286ab47cfaaSmrg                          & ~SAVAGE_BUFFER_ALIGN);
1287ab47cfaaSmrg        int tiledWidth, tiledwidthBytes,tiledBufferSize;
1288ab47cfaaSmrg
1289ab47cfaaSmrg        pSAVAGEDRIServer->frontbufferSize = bufferSize;
1290ab47cfaaSmrg        tiledwidthBytes = psav->lDelta;
1291ab47cfaaSmrg	tiledWidth = tiledwidthBytes / cpp;
1292ab47cfaaSmrg
1293ab47cfaaSmrg        if (cpp == 2) {
1294ab47cfaaSmrg            tiledBufferSize = ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16)
1295ab47cfaaSmrg                *2048;
1296ab47cfaaSmrg        } else {
1297ab47cfaaSmrg            tiledBufferSize = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16)
1298ab47cfaaSmrg                *2048;
1299ab47cfaaSmrg        }
1300ab47cfaaSmrg        /*set Depth buffer to 32bpp*/
1301ab47cfaaSmrg        /*tiledwidthBytes_Z = ((pScrn->virtualX + 31)& ~0x0000001F)*4;
1302ab47cfaaSmrg          tiledBufferSize_Z = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16)
1303ab47cfaaSmrg          *2048;*/
1304ab47cfaaSmrg
1305ab47cfaaSmrg        pSAVAGEDRIServer->backbufferSize = tiledBufferSize;
1306ab47cfaaSmrg        /*pSAVAGEDRIServer->depthbufferSize = tiledBufferSize_Z;*/
1307ab47cfaaSmrg        pSAVAGEDRIServer->depthbufferSize = tiledBufferSize;
1308ab47cfaaSmrg
1309ab47cfaaSmrg        xf86DrvMsg(pScrn->scrnIndex,X_INFO,
1310ab47cfaaSmrg                   "virtualX:%d,virtualY:%d\n",
1311ab47cfaaSmrg                   pScrn->virtualX,pScrn->virtualY);
1312ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1313ab47cfaaSmrg                    "bpp:%d,tiledwidthBytes:%d,tiledBufferSize:%d \n",
1314ab47cfaaSmrg                    pScrn->bitsPerPixel,
1315ab47cfaaSmrg                    tiledwidthBytes,tiledBufferSize);
1316ab47cfaaSmrg
1317ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1318ab47cfaaSmrg                    "bpp:%d,widthBytes:%d,BufferSize:%d \n",
1319ab47cfaaSmrg                    pScrn->bitsPerPixel,
1320ab47cfaaSmrg                    widthBytes,bufferSize);
1321ab47cfaaSmrg
1322ab47cfaaSmrg        pSAVAGEDRIServer->frontOffset = pScrn->fbOffset; /* 0 */
1323ab47cfaaSmrg        pSAVAGEDRIServer->frontPitch = widthBytes;
1324ab47cfaaSmrg
1325ab47cfaaSmrg        /* Try for front, back, depth, and two framebuffers worth of
1326ab47cfaaSmrg         * pixmap cache.  Should be enough for a fullscreen background
1327ab47cfaaSmrg         * image plus some leftovers.
1328ab47cfaaSmrg         */
1329ab47cfaaSmrg        /*     pSAVAGEDRIServer->textureSize = psav->videoRambytes -
1330ab47cfaaSmrg               tiledBufferSize -
1331ab47cfaaSmrg               tiledBufferSize_Z -
1332ab47cfaaSmrg               -0x602000;*/
1333ab47cfaaSmrg        pSAVAGEDRIServer->textureSize = psav->videoRambytes -
1334ab47cfaaSmrg            4096 - /* hw cursor*/
1335ab47cfaaSmrg            psav->cobSize - /*COB*/
1336ab47cfaaSmrg            bufferSize-
1337ab47cfaaSmrg            tiledBufferSize -
1338ab47cfaaSmrg            tiledBufferSize -
1339ab47cfaaSmrg            0x200000;
1340ab47cfaaSmrg
1341ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1342ab47cfaaSmrg                    "videoRambytes:0x%08x \n",
1343ab47cfaaSmrg                    psav->videoRambytes);
1344ab47cfaaSmrg
1345ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1346ab47cfaaSmrg                    "textureSize:0x%08x \n",
1347ab47cfaaSmrg                    pSAVAGEDRIServer->textureSize);
1348ab47cfaaSmrg
1349ab47cfaaSmrg        /* If that gives us less than half the available memory, let's
1350ab47cfaaSmrg         * be greedy and grab some more.  Sorry, I care more about 3D
1351ab47cfaaSmrg         * performance than playing nicely, and you'll get around a full
1352ab47cfaaSmrg         * framebuffer's worth of pixmap cache anyway.
1353ab47cfaaSmrg         */
1354ab47cfaaSmrg#if 0
1355ab47cfaaSmrg        if ( pSAVAGEDRIServer->textureSize < (int)psav->FbMapSize / 2 ) {
1356ab47cfaaSmrg            pSAVAGEDRIServer->textureSize = psav->FbMapSize - 4 * bufferSize;
1357ab47cfaaSmrg        }
1358ab47cfaaSmrg#endif
1359ab47cfaaSmrg        /* Check to see if there is more room available after the maximum
1360ab47cfaaSmrg         * scanline for textures.
1361ab47cfaaSmrg         */
1362ab47cfaaSmrg#if 0
1363ab47cfaaSmrg        if ( (int)psav->FbMapSize - maxlines * widthBytes - bufferSize * 2
1364ab47cfaaSmrg             > pSAVAGEDRIServer->textureSize ) {
1365ab47cfaaSmrg            pSAVAGEDRIServer->textureSize = (psav->FbMapSize -
1366ab47cfaaSmrg                                             maxlines * widthBytes -
1367ab47cfaaSmrg                                             bufferSize * 2);
1368ab47cfaaSmrg        }
1369ab47cfaaSmrg#endif
1370ab47cfaaSmrg        /* Set a minimum usable local texture heap size.  This will fit
1371ab47cfaaSmrg         * two 256x256x32bpp textures.
1372ab47cfaaSmrg         */
1373ab47cfaaSmrg        if ( pSAVAGEDRIServer->textureSize < 512 * 1024 ) {
1374ab47cfaaSmrg            pSAVAGEDRIServer->textureOffset = 0;
1375ab47cfaaSmrg            pSAVAGEDRIServer->textureSize = 0;
1376ab47cfaaSmrg        }
1377ab47cfaaSmrg
1378ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1379ab47cfaaSmrg                    "textureSize:0x%08x \n",
1380ab47cfaaSmrg                    pSAVAGEDRIServer->textureSize);
1381ab47cfaaSmrg
1382ab47cfaaSmrg        /* Reserve space for textures */
1383ab47cfaaSmrg        /*       if (pSAVAGEDRIServer->textureSize)*/
1384ab47cfaaSmrg        pSAVAGEDRIServer->textureOffset = (psav->videoRambytes -
1385ab47cfaaSmrg                                           4096 - /* hw cursor*/
1386ab47cfaaSmrg                                           psav->cobSize - /*COB*/
1387ab47cfaaSmrg                                           pSAVAGEDRIServer->textureSize) & ~SAVAGE_BUFFER_ALIGN;
1388ab47cfaaSmrg
1389ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1390ab47cfaaSmrg                    "textureOffset:0x%08x \n",
1391ab47cfaaSmrg                    pSAVAGEDRIServer->textureOffset);
1392ab47cfaaSmrg
1393ab47cfaaSmrg        /* Reserve space for the shared depth buffer */
1394ab47cfaaSmrg        /*pSAVAGEDRIServer->depthOffset = (pSAVAGEDRIServer->textureOffset -
1395ab47cfaaSmrg          tiledBufferSize_Z + SAVAGE_BUFFER_ALIGN) &  ~SAVAGE_BUFFER_ALIGN;
1396ab47cfaaSmrg        */
1397ab47cfaaSmrg        pSAVAGEDRIServer->depthOffset = (pSAVAGEDRIServer->textureOffset -
1398ab47cfaaSmrg                                         tiledBufferSize) & ~SAVAGE_BUFFER_ALIGN;
1399ab47cfaaSmrg        /*pSAVAGEDRIServer->depthPitch = tiledwidthBytes_Z;*/
1400ab47cfaaSmrg        pSAVAGEDRIServer->depthPitch = tiledwidthBytes;
1401ab47cfaaSmrg
1402ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1403ab47cfaaSmrg                    "depthOffset:0x%08x,depthPitch:%d\n",
1404ab47cfaaSmrg                    pSAVAGEDRIServer->depthOffset,pSAVAGEDRIServer->depthPitch);
1405ab47cfaaSmrg
1406ab47cfaaSmrg        /* Reserve space for the shared back buffer */
1407ab47cfaaSmrg        pSAVAGEDRIServer->backOffset = (pSAVAGEDRIServer->depthOffset -
1408ab47cfaaSmrg                                        tiledBufferSize ) & ~SAVAGE_BUFFER_ALIGN;
1409ab47cfaaSmrg
1410ab47cfaaSmrg        pSAVAGEDRIServer->backPitch = tiledwidthBytes;
1411ab47cfaaSmrg
1412ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1413ab47cfaaSmrg                    "backOffset:0x%08x,backPitch:%d\n",
1414ab47cfaaSmrg                    pSAVAGEDRIServer->backOffset,pSAVAGEDRIServer->backPitch);
1415ab47cfaaSmrg
1416ab47cfaaSmrg	/* Compute bitmap descriptors for front, back and depth buffers */
1417ab47cfaaSmrg	if ((psav->Chipset == S3_TWISTER)
1418ab47cfaaSmrg	    || (psav->Chipset == S3_PROSAVAGE)
1419ab47cfaaSmrg	    || (psav->Chipset == S3_PROSAVAGEDDR)
1420ab47cfaaSmrg	    || (psav->Chipset == S3_SUPERSAVAGE)) {
1421ab47cfaaSmrg	    pSAVAGEDRIServer->frontBitmapDesc =
1422ab47cfaaSmrg		BCI_BD_BW_DISABLE | /* block write disabled */
1423ab47cfaaSmrg		(1<<24) | /* destination tile format */
1424ab47cfaaSmrg		(pScrn->bitsPerPixel<<16) | /* bpp */
1425ab47cfaaSmrg		tiledWidth; /* stride */
1426ab47cfaaSmrg	    pSAVAGEDRIServer->backBitmapDesc =
1427ab47cfaaSmrg		BCI_BD_BW_DISABLE |
1428ab47cfaaSmrg		(1<<24) |
1429ab47cfaaSmrg		(pScrn->bitsPerPixel<<16) |
1430ab47cfaaSmrg		tiledWidth;
1431ab47cfaaSmrg	    pSAVAGEDRIServer->depthBitmapDesc =
1432ab47cfaaSmrg		BCI_BD_BW_DISABLE |
1433ab47cfaaSmrg		(1<<24) |
1434ab47cfaaSmrg		(pScrn->bitsPerPixel<<16) | /* FIXME: allow zpp != cpp */
1435ab47cfaaSmrg		tiledWidth;
1436ab47cfaaSmrg	} else {
1437ab47cfaaSmrg	    pSAVAGEDRIServer->frontBitmapDesc =
1438ab47cfaaSmrg		BCI_BD_BW_DISABLE | /* block write disabled */
1439ab47cfaaSmrg		(cpp==2 ? BCI_BD_TILE_16:BCI_BD_TILE_32) | /*16/32 bpp tile format */
1440ab47cfaaSmrg		(pScrn->bitsPerPixel<<16) | /* bpp */
1441ab47cfaaSmrg		tiledWidth; /* stride */
1442ab47cfaaSmrg	    pSAVAGEDRIServer->backBitmapDesc =
1443ab47cfaaSmrg		BCI_BD_BW_DISABLE |
1444ab47cfaaSmrg		(cpp==2 ? BCI_BD_TILE_16:BCI_BD_TILE_32) |
1445ab47cfaaSmrg		(pScrn->bitsPerPixel<<16) |
1446ab47cfaaSmrg		tiledWidth;
1447ab47cfaaSmrg	    pSAVAGEDRIServer->depthBitmapDesc =
1448ab47cfaaSmrg		BCI_BD_BW_DISABLE |
1449ab47cfaaSmrg		(cpp==2 ? BCI_BD_TILE_16:BCI_BD_TILE_32) |
1450ab47cfaaSmrg		(pScrn->bitsPerPixel<<16) | /* FIXME: allow zpp != cpp */
1451ab47cfaaSmrg		tiledWidth;
1452ab47cfaaSmrg	}
1453ab47cfaaSmrg
1454ab47cfaaSmrg        /*scanlines = pSAVAGEDRIServer->backOffset / widthBytes - 1;*/
1455ab47cfaaSmrg        /*if ( scanlines > maxlines ) scanlines = maxlines;*/
1456ab47cfaaSmrg        /* CR47983, XvMC do not work on system with frame buffer less than 32MB.
1457ab47cfaaSmrg         * VBE reports frame buffer size a little less than 16MB, this makes the condition
1458ab47cfaaSmrg         *   truns out FALSE.
1459ab47cfaaSmrg         * Now just reduce the level to 14.5MB, things should be OK, while the hwmc frame buffer layout
1460ab47cfaaSmrg         *    caculation need more understanding and should be fixed.
1461ab47cfaaSmrg         */
1462ab47cfaaSmrg        /*if total memory is less than 16M, there is no HWMC support */
1463ab47cfaaSmrg        if((psav->videoRambytes < /*16*/(14*1024+512)*1024L) || psav->bDisableXvMC)
1464ab47cfaaSmrg        {
1465ab47cfaaSmrg            psav->hwmcOffset = 0;
1466ab47cfaaSmrg            psav->hwmcSize = 0;
1467ab47cfaaSmrg        }
1468ab47cfaaSmrg        else
1469ab47cfaaSmrg        {
1470ab47cfaaSmrg            psav->hwmcSize = (10*1024+512)*1024;  /* HWMC needs 10MB FB */
1471ab47cfaaSmrg            psav->hwmcOffset = (psav->videoRambytes - 0x2000 - psav->hwmcSize) &
1472ab47cfaaSmrg                ~SAVAGE_BUFFER_ALIGN;
1473ab47cfaaSmrg            if (psav->hwmcOffset < bufferSize) {
1474ab47cfaaSmrg                /* If hwmc buffer will lay in on-screen buffer. */
1475ab47cfaaSmrg                psav->hwmcSize = 0;
1476ab47cfaaSmrg                psav->hwmcOffset = 0;
1477ab47cfaaSmrg            }
1478ab47cfaaSmrg        }
1479ab47cfaaSmrg
1480ab47cfaaSmrg        /* CR48438: Title: "Lots of garbage appear on the background when
1481ab47cfaaSmrg         *  drag the DVD player XINE window at 1024x768 or higher mode."
1482ab47cfaaSmrg         * hwmc used xserver's memory, now xserver will get less memory.
1483ab47cfaaSmrg         * Both 3D and hwmc's memory usage are considered now.
1484ab47cfaaSmrg         */
1485ab47cfaaSmrg#if 0
1486ab47cfaaSmrg        if (pSAVAGEDRIServer->backOffset < psav->hwmcOffset )
1487ab47cfaaSmrg            psav->cyMemory = pSAVAGEDRIServer->backOffset / widthBytes - 1;
1488ab47cfaaSmrg        else
1489ab47cfaaSmrg            psav->cyMemory = psav->hwmcOffset / widthBytes -1;
1490ab47cfaaSmrg#endif
1491ab47cfaaSmrg
1492ab47cfaaSmrg        psav->cyMemory = pSAVAGEDRIServer->backOffset / widthBytes - 1;
1493ab47cfaaSmrg        if (psav->cyMemory > 0x7FFF) {
1494ab47cfaaSmrg            psav->cyMemory = 0x7FFF;
1495ab47cfaaSmrg        }
1496ab47cfaaSmrg
1497ab47cfaaSmrg	psav->EXAendfb = pSAVAGEDRIServer->backOffset & ~SAVAGE_BUFFER_ALIGN;
1498ab47cfaaSmrg
1499ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1500ab47cfaaSmrg                    "Reserved back buffer at offset 0x%x\n",
1501ab47cfaaSmrg                    pSAVAGEDRIServer->backOffset );
1502ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1503ab47cfaaSmrg                    "Reserved depth buffer at offset 0x%x\n",
1504ab47cfaaSmrg                    pSAVAGEDRIServer->depthOffset );
1505ab47cfaaSmrg        xf86DrvMsg( pScrn->scrnIndex, X_INFO,
1506ab47cfaaSmrg                    "Reserved %d kb for textures at offset 0x%x\n",
1507ab47cfaaSmrg                    pSAVAGEDRIServer->textureSize/1024,
1508ab47cfaaSmrg                    pSAVAGEDRIServer->textureOffset );
1509ab47cfaaSmrg    }
1510ab47cfaaSmrg    else
1511ab47cfaaSmrg#endif
1512ab47cfaaSmrg    {
1513ab47cfaaSmrg
1514ab47cfaaSmrg        /*
1515ab47cfaaSmrg         * why this code? because BoxRec members are  short int
1516ab47cfaaSmrg         * if cyMemory is bigger than 0x7fff,then it will overflow
1517ab47cfaaSmrg         */
1518ab47cfaaSmrg        if (psav->cyMemory > 0x7FFF) {
1519ab47cfaaSmrg            psav->cyMemory = 0x7FFF;
1520ab47cfaaSmrg        }
1521ab47cfaaSmrg
1522ab47cfaaSmrg	if (psav->IsPrimary) {
1523ab47cfaaSmrg	    psav->EXAendfb = psav->videoRambytes -
1524ab47cfaaSmrg            		     4096 - /* hw cursor*/
1525ab47cfaaSmrg			     0x200000;
1526ab47cfaaSmrg	} else {
1527ab47cfaaSmrg	    psav->EXAendfb = psav->videoRambytes -
1528ab47cfaaSmrg            		     4096 - /* hw cursor*/
1529ab47cfaaSmrg            		     psav->cobSize - /*COB*/
1530ab47cfaaSmrg			     0x200000;
1531ab47cfaaSmrg	}
1532ab47cfaaSmrg
1533ab47cfaaSmrg    }
1534ab47cfaaSmrg
1535ab47cfaaSmrg    if (psav->useEXA)
1536ab47cfaaSmrg	return SavageEXAInit(pScreen);
1537ab47cfaaSmrg    else
1538ab47cfaaSmrg    	return SavageXAAInit(pScreen);
1539ab47cfaaSmrg}
1540ab47cfaaSmrg
1541ab47cfaaSmrg/* Routines for debugging. */
1542ab47cfaaSmrg
1543ab47cfaaSmrg
1544ab47cfaaSmrgunsigned long
1545ab47cfaaSmrgwritedw( unsigned long addr, unsigned long value )
1546ab47cfaaSmrg{
1547ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1548ab47cfaaSmrg    OUTREG( addr, value );
1549ab47cfaaSmrg    return INREG( addr );
1550ab47cfaaSmrg}
1551ab47cfaaSmrg
1552ab47cfaaSmrgunsigned long
1553ab47cfaaSmrgreaddw( unsigned long addr )
1554ab47cfaaSmrg{
1555ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1556ab47cfaaSmrg    return INREG( addr );
1557ab47cfaaSmrg}
1558ab47cfaaSmrg
1559ab47cfaaSmrgunsigned long
1560ab47cfaaSmrgreadfb( unsigned long addr )
1561ab47cfaaSmrg{
1562ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1563ab47cfaaSmrg    char * videobuffer = (char *) psav->FBBase;
1564ab47cfaaSmrg    return *(volatile unsigned long*)(videobuffer + (addr & ~3) );
1565ab47cfaaSmrg}
1566ab47cfaaSmrg
1567ab47cfaaSmrgunsigned long
1568ab47cfaaSmrgwritefb( unsigned long addr, unsigned long value )
1569ab47cfaaSmrg{
1570ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1571ab47cfaaSmrg    char * videobuffer = (char *) psav->FBBase;
1572ab47cfaaSmrg    *(unsigned long*)(videobuffer + (addr & ~3)) = value;
1573ab47cfaaSmrg    return *(volatile unsigned long*)(videobuffer + (addr & ~3) );
1574ab47cfaaSmrg}
1575ab47cfaaSmrg
1576ab47cfaaSmrgvoid
1577ab47cfaaSmrgwritescan( unsigned long scan, unsigned long color )
1578ab47cfaaSmrg{
1579ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1580ab47cfaaSmrg    int i;
1581ab47cfaaSmrg    char * videobuffer = (char *)psav->FBBase;
1582ab47cfaaSmrg    videobuffer += scan * gpScrn->displayWidth * gpScrn->bitsPerPixel >> 3;
1583ab47cfaaSmrg    for( i = gpScrn->displayWidth; --i; ) {
1584ab47cfaaSmrg	switch( gpScrn->bitsPerPixel ) {
1585ab47cfaaSmrg	    case 8:
1586ab47cfaaSmrg		*videobuffer++ = color;
1587ab47cfaaSmrg		break;
1588ab47cfaaSmrg	    case 16:
1589ab47cfaaSmrg		*(CARD16 *)videobuffer = color;
1590ab47cfaaSmrg		videobuffer += 2;
1591ab47cfaaSmrg		break;
1592ab47cfaaSmrg	    case 32:
1593ab47cfaaSmrg		*(CARD32 *)videobuffer = color;
1594ab47cfaaSmrg		videobuffer += 4;
1595ab47cfaaSmrg		break;
1596ab47cfaaSmrg	}
1597ab47cfaaSmrg    }
1598ab47cfaaSmrg}
1599