1ab47cfaaSmrg
2ab47cfaaSmrg/*
3ab47cfaaSmrg *
4ab47cfaaSmrg * Copyright 1995-1997 The XFree86 Project, Inc.
5ab47cfaaSmrg *
6ab47cfaaSmrg */
7ab47cfaaSmrg
8ab47cfaaSmrg/*
9ab47cfaaSmrg * The accel file for the Savage driver.
10ab47cfaaSmrg *
11ab47cfaaSmrg * Created 20/03/97 by Sebastien Marineau for 3.3.6
12ab47cfaaSmrg * Modified 17-Nov-2000 by Tim Roberts for 4.0.1
13ab47cfaaSmrg * Modified Feb-2004 by Alex Deucher - integrating DRI support
14ab47cfaaSmrg * Revision:
15ab47cfaaSmrg *
16ab47cfaaSmrg */
17ab47cfaaSmrg
18ab47cfaaSmrg#ifdef HAVE_CONFIG_H
19ab47cfaaSmrg#include "config.h"
20ab47cfaaSmrg#endif
21ab47cfaaSmrg
22ab47cfaaSmrg#include "savage_driver.h"
23ab47cfaaSmrg#include "savage_regs.h"
24ab47cfaaSmrg#include "savage_bci.h"
25ab47cfaaSmrg#include "savage_streams.h"
26ab47cfaaSmrg
27aa9e3350Smrg#ifdef SAVAGEDRI
28ab47cfaaSmrg#define _XF86DRI_SERVER_
29ab47cfaaSmrg#include "savage_dri.h"
30ab47cfaaSmrg#endif
31ab47cfaaSmrg
32ab47cfaaSmrgextern int gSavageEntityIndex;
33ab47cfaaSmrg
34ab47cfaaSmrg/* Forward declaration of functions used in the driver */
35ab47cfaaSmrg
36ab47cfaaSmrgunsigned long writedw( unsigned long addr, unsigned long value );
37ab47cfaaSmrgunsigned long readdw( unsigned long addr );
38ab47cfaaSmrgunsigned long readfb( unsigned long addr );
39ab47cfaaSmrgunsigned long writefb( unsigned long addr, unsigned long value );
40ab47cfaaSmrgvoid writescan( unsigned long scan, unsigned long color );
41ab47cfaaSmrg
42ab47cfaaSmrgstatic int GetTileAperturePitch(unsigned long dwWidth, unsigned long dwBpp);
43ab47cfaaSmrgvoid SavageSetGBD_M7(ScrnInfoPtr pScrn);
44ab47cfaaSmrgvoid SavageSetGBD_3D(ScrnInfoPtr pScrn);
45ab47cfaaSmrgvoid SavageSetGBD_Twister(ScrnInfoPtr pScrn);
46ab47cfaaSmrgvoid SavageSetGBD_PM(ScrnInfoPtr pScrn);
47ab47cfaaSmrgvoid SavageSetGBD_2000(ScrnInfoPtr pScrn);
48ab47cfaaSmrg
49ab47cfaaSmrg/*
50ab47cfaaSmrg * This is used to cache the last known value for routines we want to
51ab47cfaaSmrg * call from the debugger.
52ab47cfaaSmrg */
53ab47cfaaSmrg
54ab47cfaaSmrgScrnInfoPtr gpScrn = 0;
55ab47cfaaSmrg
56ab47cfaaSmrg/*
57ab47cfaaSmrg *  returns the aperture pitch for tiled mode.
58ab47cfaaSmrg *  if MM850C_15 = 0 (use NB linear tile mode) the pitch is screen stride aligned to 128bytes
59ab47cfaaSmrg *  if MM850C_15 = 1 (use MS-1 128bit non-linear tile mode),we should do it as follows
60ab47cfaaSmrg *  we now only support the later, and don't use Y range flag,see tile surface register
61ab47cfaaSmrg*/
62ab47cfaaSmrgstatic int GetTileAperturePitch(unsigned long dwWidth, unsigned long dwBpp)
63ab47cfaaSmrg{
64ab47cfaaSmrg    switch (dwBpp) {
65ab47cfaaSmrg        case 4:
66ab47cfaaSmrg        case 8:
67ab47cfaaSmrg            return(0x2000);
68ab47cfaaSmrg            break;
69ab47cfaaSmrg        case 16:
70ab47cfaaSmrg            return(0x1000);
71ab47cfaaSmrg            break;
72ab47cfaaSmrg        case 32:
73ab47cfaaSmrg            return(0x2000);
74ab47cfaaSmrg            break;
75ab47cfaaSmrg        default:
76ab47cfaaSmrg            return(0x2000);
77ab47cfaaSmrg    }
78ab47cfaaSmrg}
79ab47cfaaSmrg
80ab47cfaaSmrgstatic int GetTileAperturePitch2000(unsigned long dwWidth, unsigned long dwBpp, int lDelta)
81ab47cfaaSmrg{
82ab47cfaaSmrg    switch (dwBpp) {
83ab47cfaaSmrg        case 4:
84ab47cfaaSmrg        case 8:
85ab47cfaaSmrg            return(0x2000);
86ab47cfaaSmrg            break;
87ab47cfaaSmrg        case 16:
88ab47cfaaSmrg	    if (lDelta > 0x800)
89ab47cfaaSmrg                return(0x1000);
90ab47cfaaSmrg	    else
91ab47cfaaSmrg	        return(0x800);
92ab47cfaaSmrg            break;
93ab47cfaaSmrg        case 32:
94ab47cfaaSmrg	    if (lDelta > 0x1000)
95ab47cfaaSmrg                return(0x2000);
96ab47cfaaSmrg	    else
97ab47cfaaSmrg	        return(0x1000);
98ab47cfaaSmrg            break;
99ab47cfaaSmrg        default:
100ab47cfaaSmrg            return(0x2000);
101ab47cfaaSmrg    }
102ab47cfaaSmrg}
103ab47cfaaSmrg
104ab47cfaaSmrgvoid
105ab47cfaaSmrgSavageInitialize2DEngine(ScrnInfoPtr pScrn)
106ab47cfaaSmrg{
107ab47cfaaSmrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
108ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
109ab47cfaaSmrg    unsigned int vgaCRIndex = hwp->IOBase + 4;
110ab47cfaaSmrg    unsigned int vgaCRReg = hwp->IOBase + 5;
111ab47cfaaSmrg
112ab47cfaaSmrg    gpScrn = pScrn;
113ab47cfaaSmrg
114ab47cfaaSmrg    VGAOUT16(vgaCRIndex, 0x0140);
115ab47cfaaSmrg    VGAOUT8(vgaCRIndex, 0x31);
116ab47cfaaSmrg    VGAOUT8(vgaCRReg, 0x0c);
117ab47cfaaSmrg
118ab47cfaaSmrg    /* Setup plane masks */
119ab47cfaaSmrg    OUTREG(0x8128, ~0); /* enable all write planes */
120ab47cfaaSmrg    OUTREG(0x812C, ~0); /* enable all read planes */
121ab47cfaaSmrg    OUTREG16(0x8134, 0x27);
122ab47cfaaSmrg    OUTREG16(0x8136, 0x07);
123ab47cfaaSmrg
124ab47cfaaSmrg    switch( psav->Chipset ) {
125ab47cfaaSmrg
126ab47cfaaSmrg    case S3_SAVAGE3D:
127ab47cfaaSmrg    case S3_SAVAGE_MX:
128ab47cfaaSmrg	/* Disable BCI */
129ab47cfaaSmrg	OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
130ab47cfaaSmrg	/* Setup BCI command overflow buffer */
131ab47cfaaSmrg	OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29)); /* tim */
132ab47cfaaSmrg    	/*OUTREG(S3_OVERFLOW_BUFFER, psav->cobOffset >> 11 | 0xE0000000);*/ /* S3 */
133ab47cfaaSmrg	/* Program shadow status update. */
134ab47cfaaSmrg	{
135ab47cfaaSmrg	    unsigned long thresholds = ((psav->bciThresholdLo & 0xffff) << 16) |
136ab47cfaaSmrg		(psav->bciThresholdHi & 0xffff);
137ab47cfaaSmrg	    OUTREG(0x48C10, thresholds);
138ab47cfaaSmrg	    /* used to be 0x78207220 */
139ab47cfaaSmrg	}
140ab47cfaaSmrg	if( psav->ShadowStatus )
141ab47cfaaSmrg	{
142ab47cfaaSmrg	    OUTREG(0x48C0C, psav->ShadowPhysical | 1 );
143ab47cfaaSmrg	    /* Enable BCI and command overflow buffer */
144ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x0E);
145ab47cfaaSmrg	}
146ab47cfaaSmrg	else
147ab47cfaaSmrg	{
148ab47cfaaSmrg	    OUTREG(0x48C0C, 0);
149ab47cfaaSmrg	    /* Enable BCI and command overflow buffer */
150ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x0C);
151ab47cfaaSmrg	}
152ab47cfaaSmrg	break;
153ab47cfaaSmrg
154ab47cfaaSmrg    case S3_SAVAGE4:
155ab47cfaaSmrg    case S3_TWISTER:
156ab47cfaaSmrg    case S3_PROSAVAGE:
157ab47cfaaSmrg    case S3_PROSAVAGEDDR:
158ab47cfaaSmrg    case S3_SUPERSAVAGE:
159ab47cfaaSmrg	/* Disable BCI */
160ab47cfaaSmrg	OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
161ab47cfaaSmrg	if (!psav->disableCOB) {
162ab47cfaaSmrg	    /* Setup BCI command overflow buffer */
163ab47cfaaSmrg	    OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29));
164ab47cfaaSmrg	}
165ab47cfaaSmrg	/* Program shadow status update */ /* AGD: what should this be? */
166ab47cfaaSmrg	{
167ab47cfaaSmrg	    unsigned long thresholds = ((psav->bciThresholdLo & 0x1fffe0) << 11) |
168ab47cfaaSmrg		((psav->bciThresholdHi & 0x1fffe0) >> 5);
169ab47cfaaSmrg	    OUTREG(0x48C10, thresholds);
170ab47cfaaSmrg	}
171ab47cfaaSmrg	/*OUTREG(0x48C10, 0x00700040);*/ /* tim */
172ab47cfaaSmrg        /*OUTREG(0x48C10, 0x0e440f04L);*/ /* S3 */
173ab47cfaaSmrg	if( psav->ShadowStatus )
174ab47cfaaSmrg	{
175ab47cfaaSmrg	    OUTREG(0x48C0C, psav->ShadowPhysical | 1 );
176ab47cfaaSmrg	    if (psav->disableCOB) {
177ab47cfaaSmrg	    	/* Enable BCI without the COB */
178ab47cfaaSmrg		OUTREG(0x48C18, INREG(0x48C18) | 0x0a);
179ab47cfaaSmrg	    } else {
180ab47cfaaSmrg		OUTREG32(0x48C18, INREG32(0x48C18) | 0x0E);
181ab47cfaaSmrg	    }
182ab47cfaaSmrg	}
183ab47cfaaSmrg	else
184ab47cfaaSmrg	{
185ab47cfaaSmrg	    OUTREG(0x48C0C, 0);
186ab47cfaaSmrg	    if (psav->disableCOB) {
187ab47cfaaSmrg	    	/* Enable BCI without the COB */
188ab47cfaaSmrg	    	OUTREG(0x48C18, INREG(0x48C18) | 0x08);
189ab47cfaaSmrg	    } else {
190ab47cfaaSmrg		OUTREG32(0x48C18, INREG32(0x48C18) | 0x0C);
191ab47cfaaSmrg	    }
192ab47cfaaSmrg	}
193ab47cfaaSmrg	break;
194ab47cfaaSmrg
195ab47cfaaSmrg    case S3_SAVAGE2000:
196ab47cfaaSmrg	/* Disable BCI */
197ab47cfaaSmrg	OUTREG(0x48C18, 0);
198ab47cfaaSmrg	/* Setup BCI command overflow buffer */
199ab47cfaaSmrg	OUTREG(0x48C18, (psav->cobOffset >> 7) | (psav->cobIndex));
200ab47cfaaSmrg	if( psav->ShadowStatus )
201ab47cfaaSmrg	{
2022b2b4fcbSmrg	    /* Set shadow update thresholds. */
203ab47cfaaSmrg	    /*OUTREG(0x48C10, 0x6090 );
204ab47cfaaSmrg	      OUTREG(0x48C14, 0x70A8 );*/
205ab47cfaaSmrg	    OUTREG(0x48C10, psav->bciThresholdLo >> 2);
206ab47cfaaSmrg	    OUTREG(0x48C14, psav->bciThresholdHi >> 2);
207ab47cfaaSmrg	    /* Enable shadow status update */
208ab47cfaaSmrg	    OUTREG(0x48A30, psav->ShadowPhysical );
209ab47cfaaSmrg	    /* Enable BCI, command overflow buffer and shadow status. */
210ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x00380000 );
211ab47cfaaSmrg	}
212ab47cfaaSmrg	else
213ab47cfaaSmrg	{
214ab47cfaaSmrg	    /* Disable shadow status update */
215ab47cfaaSmrg	    OUTREG(0x48A30, 0);
216ab47cfaaSmrg	    /* Enable BCI and command overflow buffer */
217ab47cfaaSmrg	    OUTREG(0x48C18, INREG(0x48C18) | 0x00280000 );
218ab47cfaaSmrg	}
219ab47cfaaSmrg	break;
220ab47cfaaSmrg    }
221ab47cfaaSmrg
222ab47cfaaSmrg    /* Use and set global bitmap descriptor. */
223ab47cfaaSmrg
224ab47cfaaSmrg    /* For reasons I do not fully understand yet, on the Savage4, the */
225ab47cfaaSmrg    /* write to the GBD register, MM816C, does not "take" at this time. */
226ab47cfaaSmrg    /* Only the low-order byte is acknowledged, resulting in an incorrect */
227ab47cfaaSmrg    /* stride.  Writing the register later, after the mode switch, works */
228ab47cfaaSmrg    /* correctly.  This needs to get resolved. */
229ab47cfaaSmrg
230ab47cfaaSmrg    SavageSetGBD(pScrn);
231ab47cfaaSmrg}
232ab47cfaaSmrg
233ab47cfaaSmrgvoid
234ab47cfaaSmrgSavageSetGBD(ScrnInfoPtr pScrn)
235ab47cfaaSmrg{
236ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
237ab47cfaaSmrg
238ab47cfaaSmrg    UnProtectCRTC();
239ab47cfaaSmrg    UnLockExtRegs();
240ab47cfaaSmrg    VerticalRetraceWait();
241ab47cfaaSmrg
242ab47cfaaSmrg    psav->lDelta = pScrn->virtualX * (pScrn->bitsPerPixel >> 3);
243ab47cfaaSmrg
244ab47cfaaSmrg    /*
245ab47cfaaSmrg     * we can use Option "DisableTile" "TRUE" to disable tile mode
246ab47cfaaSmrg     * if don't disable tile,we only support tile mode under 16/32bpp
247ab47cfaaSmrg     */
248ab47cfaaSmrg    if ((!psav->bDisableTile) && ((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32))) {
249ab47cfaaSmrg        /* tileing in 16/32 BPP */
250ab47cfaaSmrg        psav->bTiled = TRUE;
251ab47cfaaSmrg        psav->lDelta = ((psav->lDelta + 127) >> 7) << 7;
252ab47cfaaSmrg
253ab47cfaaSmrg        if (S3_SAVAGE3D_SERIES(psav->Chipset))
254ab47cfaaSmrg            psav->ulAperturePitch = 0x2000;
255ab47cfaaSmrg	else if (psav->Chipset == S3_SAVAGE2000)
256ab47cfaaSmrg	    psav->ulAperturePitch = GetTileAperturePitch2000(pScrn->virtualX,
257ab47cfaaSmrg							     pScrn->bitsPerPixel,
258ab47cfaaSmrg							     psav->lDelta);
259ab47cfaaSmrg        else
260ab47cfaaSmrg            psav->ulAperturePitch = GetTileAperturePitch(pScrn->virtualX,pScrn->bitsPerPixel);
261ab47cfaaSmrg
262ab47cfaaSmrg        /* Use the aperture for linear screen */
263ab47cfaaSmrg        psav->FBStart = psav->ApertureMap;
264ab47cfaaSmrg    } else {
265ab47cfaaSmrg        psav->bTiled = FALSE;
266ab47cfaaSmrg        /* 32: Alignment for nontiled mode */
267ab47cfaaSmrg        psav->lDelta = ((psav->lDelta + 31) >> 5) << 5;
268ab47cfaaSmrg        psav->ulAperturePitch = psav->lDelta;
269ab47cfaaSmrg    }
270ab47cfaaSmrg
271ab47cfaaSmrg    psav->Bpp = pScrn->bitsPerPixel >> 3;
272ab47cfaaSmrg    psav->cxMemory = psav->lDelta / (psav->Bpp);
273ab47cfaaSmrg    psav->cyMemory = psav->endfb / psav->lDelta - 1;
274ab47cfaaSmrg    /* ??????????? */
275ab47cfaaSmrg    if (psav->cyMemory > 2048)
276ab47cfaaSmrg        psav->cyMemory = 2048;
277ab47cfaaSmrg
278ab47cfaaSmrg    /*
279ab47cfaaSmrg     * If tiling, adjust down psav->cyMemory to the last multiple
280ab47cfaaSmrg     * of a tileheight, so that we don't try to use partial tiles.
281ab47cfaaSmrg     */
282ab47cfaaSmrg    if (psav->bTiled)  {
283ab47cfaaSmrg        psav->cyMemory -= (psav->cyMemory % 16);
284ab47cfaaSmrg    }
285ab47cfaaSmrg
286ab47cfaaSmrg    /*
287ab47cfaaSmrg     *  Initialization per GX-3.
288ab47cfaaSmrg     *
289ab47cfaaSmrg     *  1. MM48C18 - Disable BCI.
290ab47cfaaSmrg     *  2. MM48C0C - Enable updating shadow status
291ab47cfaaSmrg     *              and initialize shadow memory address.
292ab47cfaaSmrg     *  2b. MM48C18 - bit 1 = 1, Enable Command Buffer status updates
293ab47cfaaSmrg     *              (S3_OVERFLOW_BUFFER_PTR)
294ab47cfaaSmrg     *  3. MM48C10 - Initialize command buffer threshold
295ab47cfaaSmrg     *              (S3_BUFFER_THRESHOLD)
296ab47cfaaSmrg     *  4. MM48C14 - Setup command buffer offset and size
297ab47cfaaSmrg     *              (S3_OVERFLOW_BUFFER)
298ab47cfaaSmrg     *  5. MM816C  - Enable BCI.
299ab47cfaaSmrg     *  6. MM48C40 - Setup tiled surface 0 register.
300ab47cfaaSmrg     *  7. CR31 - bit 0 = 0, Disable address offset bits(CR6A_6-0).
301ab47cfaaSmrg     *  8. CR50 - bit 7,6,0 = 111, Use Global Bitmap Descriptor.
302ab47cfaaSmrg     *  9. CR88 - bit 4 = 0, Block write on (linear mode) IFF we know we
303ab47cfaaSmrg     *                       have the right kind of SGRAM memory,
304ab47cfaaSmrg     *                       bit 4 = 1, Block write off (always off if tiling)
305ab47cfaaSmrg     *  10.CR69 - Bit 7 = 1, MM81C0 and 81C4 are used to control
306ab47cfaaSmrg     *                       primary stream.
307ab47cfaaSmrg     *  11.MM8128, MM812c - Setup read/write mask registers
308ab47cfaaSmrg     *  12.MM816C, MM8168 - Set up Global Bitmap Descriptor 1 and 2.
309ab47cfaaSmrg     */
310ab47cfaaSmrg    switch (psav->Chipset) {
311ab47cfaaSmrg        case S3_SAVAGE3D:
312ab47cfaaSmrg	    SavageSetGBD_3D(pScrn);
313ab47cfaaSmrg	    break;
314ab47cfaaSmrg        case S3_SAVAGE_MX:
315ab47cfaaSmrg            SavageSetGBD_M7(pScrn);
316ab47cfaaSmrg            break;
317ab47cfaaSmrg        case S3_SAVAGE4:
318ab47cfaaSmrg        case S3_TWISTER:
319ab47cfaaSmrg        case S3_PROSAVAGE:
320ab47cfaaSmrg        case S3_PROSAVAGEDDR:
321ab47cfaaSmrg            SavageSetGBD_Twister(pScrn);
322ab47cfaaSmrg            break;
323ab47cfaaSmrg        case S3_SUPERSAVAGE:
324ab47cfaaSmrg            SavageSetGBD_PM(pScrn);
325ab47cfaaSmrg            break;
326ab47cfaaSmrg        case S3_SAVAGE2000:
327ab47cfaaSmrg	    SavageSetGBD_2000(pScrn);
328ab47cfaaSmrg	    break;
329ab47cfaaSmrg    }
330ab47cfaaSmrg}
331ab47cfaaSmrg
332ab47cfaaSmrgvoid SavageSetGBD_Twister(ScrnInfoPtr pScrn)
333ab47cfaaSmrg{
334ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
335ab47cfaaSmrg    unsigned long       ulTmp;
336ab47cfaaSmrg    unsigned char byte;
337ab47cfaaSmrg    int bci_enable, tile16, tile32;
338ab47cfaaSmrg
339ab47cfaaSmrg    if (psav->Chipset == S3_SAVAGE4) {
340ab47cfaaSmrg	bci_enable = BCI_ENABLE;
341ab47cfaaSmrg	tile16 = TILE_FORMAT_16BPP;
342ab47cfaaSmrg	tile32 = TILE_FORMAT_32BPP;
343ab47cfaaSmrg    } else {
344ab47cfaaSmrg	bci_enable = BCI_ENABLE_TWISTER;
345ab47cfaaSmrg	tile16 = TILE_DESTINATION;
346ab47cfaaSmrg	tile32 = TILE_DESTINATION;
347ab47cfaaSmrg    }
348ab47cfaaSmrg
349ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
350ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR0_REG,0x00000000);
351ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR1_REG,0x00000000);
352ab47cfaaSmrg
353ab47cfaaSmrg    /*
354ab47cfaaSmrg     *  Program Primary Stream Stride Register.
355ab47cfaaSmrg     *
356ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
357ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
358ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
359ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
360ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
361ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
362ab47cfaaSmrg     */
363ab47cfaaSmrg    if (!psav->bTiled) {
364ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
365ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
366ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
367ab47cfaaSmrg    }
368ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
369ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
370ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
371ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
372ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
373ab47cfaaSmrg    }
374ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
375ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
376ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
377ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
378ab47cfaaSmrg    }
379ab47cfaaSmrg
380ab47cfaaSmrg    /*
381ab47cfaaSmrg     *  CR69, bit 7 = 1
382ab47cfaaSmrg     *  to use MM streams processor registers to control primary stream.
383ab47cfaaSmrg     */
384ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x69);
385ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0x80;
386ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
387ab47cfaaSmrg
388ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
389ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
390ab47cfaaSmrg
391ab47cfaaSmrg    OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
392ab47cfaaSmrg
393ab47cfaaSmrg
394ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
395ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
396ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
397ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
398ab47cfaaSmrg
399ab47cfaaSmrg    /*
400ab47cfaaSmrg     * if MS1NB style linear tiling mode.
401ab47cfaaSmrg     * bit MM850C[15] = 0 select NB linear tile mode.
402ab47cfaaSmrg     * bit MM850C[15] = 1 select MS-1 128-bit non-linear tile mode.
403ab47cfaaSmrg     */
404ab47cfaaSmrg    ulTmp = INREG32(ADVANCED_FUNC_CTRL) | 0x8000; /* use MS-s style tile mode*/
405ab47cfaaSmrg    OUTREG32(ADVANCED_FUNC_CTRL,ulTmp);
406ab47cfaaSmrg
407ab47cfaaSmrg    /*
408ab47cfaaSmrg     * Set up Tiled Surface Registers
409ab47cfaaSmrg     *  Bit 25:20 - Surface width in tiles.
410ab47cfaaSmrg     *  Bit 29 - Y Range Flag.
411ab47cfaaSmrg     *  Bit 31:30 = 00, 4 bpp.
412ab47cfaaSmrg     *            = 01, 8 bpp.
413ab47cfaaSmrg     *            = 10, 16 bpp.
414ab47cfaaSmrg     *            = 11, 32 bpp.
415ab47cfaaSmrg     */
416ab47cfaaSmrg    /*
417ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C - twister/prosavage
418ab47cfaaSmrg     *   bit 24~25: tile format
419ab47cfaaSmrg     *          00: linear
420ab47cfaaSmrg     *          01: destination tiling format
421ab47cfaaSmrg     *          10: texture tiling format
422ab47cfaaSmrg     *          11: reserved
4232b2b4fcbSmrg     *   bit 28: block write disable/enable
424ab47cfaaSmrg     *          0: disable
425ab47cfaaSmrg     *          1: enable
426ab47cfaaSmrg     */
427ab47cfaaSmrg    /*
428ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C - savage4
429ab47cfaaSmrg     *   bit 24~25: tile format
430ab47cfaaSmrg     *          00: linear
431ab47cfaaSmrg     *          01: reserved
432ab47cfaaSmrg     *          10: 16 bpp tiles
433ab47cfaaSmrg     *          11: 32 bpp tiles
434ab47cfaaSmrg     *   bit 28: block write disable/enable
435ab47cfaaSmrg     *          0: enable
436ab47cfaaSmrg     *          1: disable
437ab47cfaaSmrg     */
438ab47cfaaSmrg    if (!psav->bTiled) {
439ab47cfaaSmrg        /*
440ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
441ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
442ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
443ab47cfaaSmrg         */
444ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
445ab47cfaaSmrg    }
446ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
447ab47cfaaSmrg	psav->GlobalBD.bd1.HighPart.ResBWTile = tile16; /* 16 bpp/destination tiling format */
448ab47cfaaSmrg
449ab47cfaaSmrg        ulTmp = (((pScrn->virtualX + 0x3F) & 0x0000FFC0) >> 6) << 20;
450ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
451ab47cfaaSmrg    }
452ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
453ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32; /* 32 bpp/destination tiling format */
454ab47cfaaSmrg
455ab47cfaaSmrg        ulTmp = ( ((pScrn->virtualX + 0x1F) & 0x0000FFE0) >> 5) << 20;
456ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
457ab47cfaaSmrg    }
458ab47cfaaSmrg
459ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write - was 0 */
460ab47cfaaSmrg    /* HW uses width */
461ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short) psav->lDelta / (pScrn->bitsPerPixel >> 3);
462ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
463ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
464ab47cfaaSmrg
465ab47cfaaSmrg
466ab47cfaaSmrg    /*
467ab47cfaaSmrg     * CR88, bit 4 - Block write enabled/disabled.
468ab47cfaaSmrg     *
469ab47cfaaSmrg     *      Note: Block write must be disabled when writing to tiled
470ab47cfaaSmrg     *            memory.  Even when writing to non-tiled memory, block
471ab47cfaaSmrg     *            write should only be enabled for certain types of SGRAM.
472ab47cfaaSmrg     */
473ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x88);
474ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | DISABLE_BLOCK_WRITE_2D;
475ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
476ab47cfaaSmrg
477ab47cfaaSmrg    /*
478ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
479ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
480ab47cfaaSmrg     *                  at A000:0.
481ab47cfaaSmrg     */
482ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
483ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
484ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte); /* perhaps this should be 0x0c */
485ab47cfaaSmrg
486ab47cfaaSmrg    /* turn on screen */
487ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
488ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
489ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
490ab47cfaaSmrg
491ab47cfaaSmrg    /* program the GBD and SBD's */
492ab47cfaaSmrg    OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart);
493ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
494ab47cfaaSmrg    OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
495ab47cfaaSmrg    OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
496ab47cfaaSmrg    OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
497ab47cfaaSmrg    OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
498ab47cfaaSmrg}
499ab47cfaaSmrg
500ab47cfaaSmrgvoid SavageSetGBD_3D(ScrnInfoPtr pScrn)
501ab47cfaaSmrg{
502ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
503ab47cfaaSmrg    unsigned long       ulTmp;
504ab47cfaaSmrg    unsigned char byte;
505ab47cfaaSmrg    int bci_enable, tile16, tile32;
506ab47cfaaSmrg
507ab47cfaaSmrg    bci_enable = BCI_ENABLE;
508ab47cfaaSmrg    tile16 = TILE_FORMAT_16BPP;
509ab47cfaaSmrg    tile32 = TILE_FORMAT_32BPP;
510ab47cfaaSmrg
511ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
512ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR0_REG,0x00000000);
513ab47cfaaSmrg    OUTREG32(PSTREAM_FBADDR1_REG,0x00000000);
514ab47cfaaSmrg
515ab47cfaaSmrg    /*
516ab47cfaaSmrg     *  Program Primary Stream Stride Register.
517ab47cfaaSmrg     *
518ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
519ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
520ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
521ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
522ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
523ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
524ab47cfaaSmrg     */
525ab47cfaaSmrg    if (!psav->bTiled) {
526ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
527ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
528ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
529ab47cfaaSmrg    }
530ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
531ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
532ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
533ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
534ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
535ab47cfaaSmrg    }
536ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
537ab47cfaaSmrg        OUTREG32(PSTREAM_STRIDE_REG,
538ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFFE000)
539ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
540ab47cfaaSmrg    }
541ab47cfaaSmrg
542ab47cfaaSmrg    /*
543ab47cfaaSmrg     *  CR69, bit 7 = 1
544ab47cfaaSmrg     *  to use MM streams processor registers to control primary stream.
545ab47cfaaSmrg     */
546ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x69);
547ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0x80;
548ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
549ab47cfaaSmrg
550ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
551ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
552ab47cfaaSmrg
553ab47cfaaSmrg    OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
554ab47cfaaSmrg
555ab47cfaaSmrg
556ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
557ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
558ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
559ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
560ab47cfaaSmrg
561ab47cfaaSmrg    /*
562ab47cfaaSmrg     * if MS1NB style linear tiling mode.
563ab47cfaaSmrg     * bit MM850C[15] = 0 select NB linear tile mode.
564ab47cfaaSmrg     * bit MM850C[15] = 1 select MS-1 128-bit non-linear tile mode.
565ab47cfaaSmrg     */
566ab47cfaaSmrg    ulTmp = INREG32(ADVANCED_FUNC_CTRL) | 0x8000; /* use MS-s style tile mode*/
567ab47cfaaSmrg    OUTREG32(ADVANCED_FUNC_CTRL,ulTmp);
568ab47cfaaSmrg
569ab47cfaaSmrg    /*
570ab47cfaaSmrg     * Tiled Surface 0 Registers MM48C40:
571ab47cfaaSmrg     *  bit 0~23: tile surface 0 frame buffer offset
572ab47cfaaSmrg     *  bit 24~29:tile surface 0 width
573ab47cfaaSmrg     *  bit 30~31:tile surface 0 bits/pixel
574ab47cfaaSmrg     *            00: reserved
575ab47cfaaSmrg     *            01, 8 bits
576ab47cfaaSmrg     *            10, 16 Bits.
577ab47cfaaSmrg     *            11, 32 Bits.
578ab47cfaaSmrg     */
579ab47cfaaSmrg    /*
580ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C
581ab47cfaaSmrg     *   bit 24~25: tile format
582ab47cfaaSmrg     *          00: linear
583ab47cfaaSmrg     *          01: reserved
584ab47cfaaSmrg     *          10: 16 bpp tiles
585ab47cfaaSmrg     *          11: 32 bpp tiles
586ab47cfaaSmrg     *   bit 28: block write disable/enable
587ab47cfaaSmrg     *          0: enable
588ab47cfaaSmrg     *          1: disable
589ab47cfaaSmrg     */
590ab47cfaaSmrg    if (!psav->bTiled) {
591ab47cfaaSmrg        /*
592ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
593ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
594ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
595ab47cfaaSmrg         */
596ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
597ab47cfaaSmrg    }
598ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
599ab47cfaaSmrg	psav->GlobalBD.bd1.HighPart.ResBWTile = tile16; /* 16 bpp/destination tiling format */
600ab47cfaaSmrg
601ab47cfaaSmrg        ulTmp = (((pScrn->virtualX + 0x3F) & 0x0000FFC0) >> 6) << 24;
602ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
603ab47cfaaSmrg    }
604ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
605ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32; /* 32 bpp/destination tiling format */
606ab47cfaaSmrg
607ab47cfaaSmrg        ulTmp = ( ((pScrn->virtualX + 0x1F) & 0x0000FFE0) >> 5) << 24;
608ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
609ab47cfaaSmrg    }
610ab47cfaaSmrg
611ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write - was 0 */
612ab47cfaaSmrg    /* HW uses width */
613ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short) psav->lDelta / (pScrn->bitsPerPixel >> 3);
614ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
615ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
616ab47cfaaSmrg
617ab47cfaaSmrg
618ab47cfaaSmrg    /*
619ab47cfaaSmrg     * CR88, bit 4 - Block write enabled/disabled.
620ab47cfaaSmrg     *
621ab47cfaaSmrg     *      Note: Block write must be disabled when writing to tiled
622ab47cfaaSmrg     *            memory.  Even when writing to non-tiled memory, block
623ab47cfaaSmrg     *            write should only be enabled for certain types of SGRAM.
624ab47cfaaSmrg     */
625ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x88);
626ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | DISABLE_BLOCK_WRITE_2D;
627ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
628ab47cfaaSmrg
629ab47cfaaSmrg    /*
630ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
631ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
632ab47cfaaSmrg     *                  at A000:0.
633ab47cfaaSmrg     */
634ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
635ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
636ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte); /* perhaps this should be 0x0c */
637ab47cfaaSmrg
638ab47cfaaSmrg    /* turn on screen */
639ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
640ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
641ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
642ab47cfaaSmrg
643ab47cfaaSmrg    /* program the GBD and SBD's */
644ab47cfaaSmrg    OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart);
645ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
646ab47cfaaSmrg    OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
647ab47cfaaSmrg    OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
648ab47cfaaSmrg    OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
649ab47cfaaSmrg    OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
650ab47cfaaSmrg}
651ab47cfaaSmrg
652ab47cfaaSmrgvoid SavageSetGBD_M7(ScrnInfoPtr pScrn)
653ab47cfaaSmrg{
654ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
655ab47cfaaSmrg    unsigned long ulTmp;
656ab47cfaaSmrg    unsigned char byte;
657ab47cfaaSmrg    int bci_enable, tile16, tile32;
658ab47cfaaSmrg
659ab47cfaaSmrg    bci_enable = BCI_ENABLE;
660ab47cfaaSmrg    tile16 = TILE_FORMAT_16BPP;
661ab47cfaaSmrg    tile32 = TILE_FORMAT_32BPP;
662ab47cfaaSmrg
663ab47cfaaSmrg
664ab47cfaaSmrg    /* following is the enable case */
665ab47cfaaSmrg
666ab47cfaaSmrg    /* SR01:turn off screen */
667ab47cfaaSmrg    OUTREG8 (SEQ_ADDRESS_REG,0x01);
668ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) | 0x20;
669ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
670ab47cfaaSmrg
671ab47cfaaSmrg    /*
672ab47cfaaSmrg     * CR67_3:
673ab47cfaaSmrg     *  = 1  stream processor MMIO address and stride register
674ab47cfaaSmrg     *       are used to control the primary stream
675ab47cfaaSmrg     *  = 0  standard VGA address and stride registers
676ab47cfaaSmrg     *       are used to control the primary streams
677ab47cfaaSmrg     */
678ab47cfaaSmrg    if (psav->IsPrimary) {
679ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
680ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
681ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
682ab47cfaaSmrg    } else if (psav->IsSecondary) {
683ab47cfaaSmrg    	/* IGA 2 */
684ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
685ab47cfaaSmrg
686ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
687ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
688ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
689ab47cfaaSmrg
690ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
691ab47cfaaSmrg    } else {
692ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
693ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
694ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
695ab47cfaaSmrg    	/* IGA 2 */
696ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
697ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
698ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
699ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
700ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
701ab47cfaaSmrg    }
702ab47cfaaSmrg    /* Set primary stream to bank 0 */
703ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG, MEMORY_CTRL0_REG);/* CRCA */
704ab47cfaaSmrg    byte =  INREG8(CRT_DATA_REG) & ~(MEM_PS1 + MEM_PS2) ;
705ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
706ab47cfaaSmrg#if 0
707ab47cfaaSmrg    /*
708ab47cfaaSmrg     * if we have 8MB of frame buffer here then we must really be a 16MB
709ab47cfaaSmrg     * card and that means that the second device is always in the upper
710ab47cfaaSmrg     * bank of memory (MHS)
711ab47cfaaSmrg     */
712ab47cfaaSmrg    if (psav->videoRambytes >= 0x800000) {
713ab47cfaaSmrg        /* 16MB Video Memory cursor is at the end in Bank 1 */
714ab47cfaaSmrg        byte |= 0x3;
715ab47cfaaSmrg        OUTREG16(CRT_ADDRESS_REG, (byte << 8) | MEMORY_CTRL0_REG);
716ab47cfaaSmrg    }
717ab47cfaaSmrg#endif
718ab47cfaaSmrg
719ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
720ab47cfaaSmrg    if (psav->IsPrimary) {
721ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
722ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
723ab47cfaaSmrg    } else if (psav->IsSecondary) {
724ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
725ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
726ab47cfaaSmrg    } else {
727ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
728ab47cfaaSmrg    	OUTREG32(PRI_STREAM_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
729ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR0,pScrn->fbOffset & 0x7fffff);
730ab47cfaaSmrg    	OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0x7fffff);
731ab47cfaaSmrg    }
732ab47cfaaSmrg
733ab47cfaaSmrg    /*
734ab47cfaaSmrg     *  Program Primary Stream Stride Register.
735ab47cfaaSmrg     *
736ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
737ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
738ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
739ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
740ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
741ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
742ab47cfaaSmrg     */
743ab47cfaaSmrg    if (!psav->bTiled) {
744ab47cfaaSmrg 	if (psav->IsPrimary) {
745ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
746ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
747ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
748ab47cfaaSmrg	} else if (psav->IsSecondary) {
749ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
750ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
751ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
752ab47cfaaSmrg	} else {
753ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
754ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
755ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
756ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
757ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
758ab47cfaaSmrg                 (psav->lDelta & 0x00003fff));
759ab47cfaaSmrg	}
760ab47cfaaSmrg
761ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 16) {
762ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
763ab47cfaaSmrg	if (psav->IsPrimary) {
764ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
765ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
766ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
767ab47cfaaSmrg        } else if (psav->IsSecondary) {
768ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
769ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
770ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
771ab47cfaaSmrg        } else {
772ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
773ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
774ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
775ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
776ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
777ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00003fff));
778ab47cfaaSmrg	}
779ab47cfaaSmrg
780ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 32) {
781ab47cfaaSmrg	if (psav->IsPrimary) {
782ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
783ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
784ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
785ab47cfaaSmrg	} else if (psav->IsSecondary) {
786ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
787ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
788ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
789ab47cfaaSmrg	} else {
790ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
791ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
792ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
793ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
794ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
795ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00003fff));
796ab47cfaaSmrg	}
797ab47cfaaSmrg    }
798ab47cfaaSmrg
799ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
800ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
801ab47cfaaSmrg
802ab47cfaaSmrg    if (!psav->IsSecondary)
803ab47cfaaSmrg    	OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
804ab47cfaaSmrg
805ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
806ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
807ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
808ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
809ab47cfaaSmrg
810ab47cfaaSmrg    /*
811ab47cfaaSmrg     * CR78, bit 3  - Block write enabled(1)/disabled(0).
812ab47cfaaSmrg     *       bit 2  - Block write cycle time(0:2 cycles,1: 1 cycle)
813ab47cfaaSmrg     *      Note: Block write must be disabled when writing to tiled
814ab47cfaaSmrg     *            memory.  Even when writing to non-tiled memory, block
815ab47cfaaSmrg     *            write should only be enabled for certain types of SGRAM.
816ab47cfaaSmrg     */
817ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x78);
818ab47cfaaSmrg    /*byte = INREG8(CRT_DATA_REG) & ~0x0C;*/
819ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xfb;
820ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
821ab47cfaaSmrg
822ab47cfaaSmrg    /*
823ab47cfaaSmrg     * Tiled Surface 0 Registers MM48C40:
824ab47cfaaSmrg     *  bit 0~23: tile surface 0 frame buffer offset
825ab47cfaaSmrg     *  bit 24~29:tile surface 0 width
826ab47cfaaSmrg     *  bit 30~31:tile surface 0 bits/pixel
827ab47cfaaSmrg     *            00: reserved
828ab47cfaaSmrg     *            01, 8 bits
829ab47cfaaSmrg     *            10, 16 Bits.
830ab47cfaaSmrg     *            11, 32 Bits.
831ab47cfaaSmrg     */
832ab47cfaaSmrg    /*
833ab47cfaaSmrg     * Global Bitmap Descriptor Register MM816C
834ab47cfaaSmrg     *   bit 24~25: tile format
835ab47cfaaSmrg     *          00: linear
836ab47cfaaSmrg     *          01: reserved
837ab47cfaaSmrg     *          10: 16 bit
838ab47cfaaSmrg     *          11: 32 bit
8392b2b4fcbSmrg     *   bit 28: block write disable/enable
840ab47cfaaSmrg     *          0: enable
841ab47cfaaSmrg     *          1: disable
842ab47cfaaSmrg     */
843ab47cfaaSmrg    if (!psav->bTiled) {
844ab47cfaaSmrg        /*
845ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
846ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
847ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
848ab47cfaaSmrg         */
849ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
850ab47cfaaSmrg
851ab47cfaaSmrg    }
852ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
853ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* 16 bit */
854ab47cfaaSmrg
855ab47cfaaSmrg	ulTmp =  ((psav->lDelta / 2) >> 6) << 24;
856ab47cfaaSmrg	if (psav->IsSecondary)
857ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP16 | pScrn->fbOffset);
858ab47cfaaSmrg	else
859ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16 | pScrn->fbOffset);
860ab47cfaaSmrg    }
861ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
862ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* 32 bit */
863ab47cfaaSmrg
864ab47cfaaSmrg	ulTmp =  ((psav->lDelta / 4) >> 5) << 24;
865ab47cfaaSmrg	if (psav->IsSecondary)
866ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP32 | pScrn->fbOffset);
867ab47cfaaSmrg	else
868ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32 | pScrn->fbOffset);
869ab47cfaaSmrg    }
870ab47cfaaSmrg
871ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
872ab47cfaaSmrg    /* HW uses width */
873ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
874ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
875ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
876ab47cfaaSmrg
877ab47cfaaSmrg
878ab47cfaaSmrg    /*
879ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
880ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
881ab47cfaaSmrg     *                  at A000:0.
882ab47cfaaSmrg     */
883ab47cfaaSmrg#if 0
884ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
885ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
886ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
887ab47cfaaSmrg#endif
888ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
889ab47cfaaSmrg    byte = (INREG8(CRT_DATA_REG) | 0x04) & 0xFE;
890ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
891ab47cfaaSmrg
892ab47cfaaSmrg    if (!psav->IsSecondary) {
893ab47cfaaSmrg    	/* program the GBD and SBD's */
894ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
895ab47cfaaSmrg    	/* 8: bci enable */
896ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
897ab47cfaaSmrg                             | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
898ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
899ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
900ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
901ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
902ab47cfaaSmrg    }
903ab47cfaaSmrg
904ab47cfaaSmrg    /* turn on screen */
905ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
906ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0X20;
907ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
908ab47cfaaSmrg}
909ab47cfaaSmrg
910ab47cfaaSmrgvoid SavageSetGBD_PM(ScrnInfoPtr pScrn)
911ab47cfaaSmrg{
912ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
913ab47cfaaSmrg    unsigned long ulTmp;
914ab47cfaaSmrg    unsigned char byte;
915ab47cfaaSmrg    int bci_enable, tile16, tile32;
916ab47cfaaSmrg
917ab47cfaaSmrg
918ab47cfaaSmrg    bci_enable = BCI_ENABLE_TWISTER;
919ab47cfaaSmrg    tile16 = TILE_DESTINATION;
920ab47cfaaSmrg    tile32 = TILE_DESTINATION;
921ab47cfaaSmrg
922ab47cfaaSmrg
923ab47cfaaSmrg    /* following is the enable case */
924ab47cfaaSmrg
925ab47cfaaSmrg    /* SR01:turn off screen */
926ab47cfaaSmrg    OUTREG8 (SEQ_ADDRESS_REG,0x01);
927ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) | 0x20;
928ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
929ab47cfaaSmrg
930ab47cfaaSmrg    /*
931ab47cfaaSmrg     * CR67_3:
932ab47cfaaSmrg     *  = 1  stream processor MMIO address and stride register
933ab47cfaaSmrg     *       are used to control the primary stream
934ab47cfaaSmrg     *  = 0  standard VGA address and stride registers
935ab47cfaaSmrg     *       are used to control the primary streams
936ab47cfaaSmrg     */
937ab47cfaaSmrg    if (psav->IsPrimary) {
938ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
939ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
940ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
941ab47cfaaSmrg    } else if (psav->IsSecondary) {
942ab47cfaaSmrg    	/* IGA 2 */
943ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
944ab47cfaaSmrg
945ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
946ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
947ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
948ab47cfaaSmrg
949ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
950ab47cfaaSmrg    } else {
951ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
952ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
953ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
954ab47cfaaSmrg    	/* IGA 2 */
955ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
956ab47cfaaSmrg
957ab47cfaaSmrg    	OUTREG8(CRT_ADDRESS_REG,0x67);
958ab47cfaaSmrg    	byte =  INREG8(CRT_DATA_REG) | 0x08;
959ab47cfaaSmrg    	OUTREG8(CRT_DATA_REG,byte);
960ab47cfaaSmrg
961ab47cfaaSmrg    	OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
962ab47cfaaSmrg    }
963ab47cfaaSmrg
964ab47cfaaSmrg    /*
965ab47cfaaSmrg     * load ps1 active registers as determined by MM81C0/81C4
966ab47cfaaSmrg     * load ps2 active registers as determined by MM81B0/81B4
967ab47cfaaSmrg     */
968ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x65);
969ab47cfaaSmrg    byte =  INREG8(CRT_DATA_REG) | 0x03;
970ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
971ab47cfaaSmrg
972ab47cfaaSmrg    /*
973ab47cfaaSmrg     *  Program Primary Stream Stride Register.
974ab47cfaaSmrg     *
975ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
976ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
977ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
978ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
979ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
980ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
981ab47cfaaSmrg     */
982ab47cfaaSmrg    if (!psav->bTiled) {
983ab47cfaaSmrg	if (psav->IsPrimary) {
984ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
985ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
986ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
987ab47cfaaSmrg	} else if (psav->IsSecondary) {
988ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
989ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
990ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
991ab47cfaaSmrg	} else {
992ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
993ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
994ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
995ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
996ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
997ab47cfaaSmrg                 (psav->lDelta & 0x00001fff));
998ab47cfaaSmrg	}
999ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 16) {
1000ab47cfaaSmrg        /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
1001ab47cfaaSmrg	if (psav->IsPrimary) {
1002ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1003ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1004ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1005ab47cfaaSmrg	} else if (psav->IsSecondary) {
1006ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1007ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1008ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1009ab47cfaaSmrg	} else {
1010ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1011ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1012ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1013ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1014ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1015ab47cfaaSmrg                 | 0x80000000 | (psav->lDelta & 0x00001fff));
1016ab47cfaaSmrg	}
1017ab47cfaaSmrg
1018ab47cfaaSmrg    } else if (pScrn->bitsPerPixel == 32) {
1019ab47cfaaSmrg	if (psav->IsPrimary) {
1020ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1021ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1022ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1023ab47cfaaSmrg	} else if (psav->IsSecondary) {
1024ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1025ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1026ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1027ab47cfaaSmrg	} else {
1028ab47cfaaSmrg            OUTREG32(PRI_STREAM_STRIDE,
1029ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1030ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1031ab47cfaaSmrg            OUTREG32(PRI_STREAM2_STRIDE,
1032ab47cfaaSmrg                 (((psav->lDelta * 2) << 16) & 0x3FFF0000)
1033ab47cfaaSmrg                 | 0xC0000000 | (psav->lDelta & 0x00001fff));
1034ab47cfaaSmrg	}
1035ab47cfaaSmrg    }
1036ab47cfaaSmrg
1037ab47cfaaSmrg    /* MM81C0 and 81C4 are used to control primary stream. */
1038ab47cfaaSmrg    if (psav->IsPrimary) {
1039ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset);
1040ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR1,0x80000000);
1041ab47cfaaSmrg    } else if (psav->IsSecondary) {
1042ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR0,(pScrn->fbOffset & 0xfffffffc) | 0x80000000);
1043ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0xffffffc);
1044ab47cfaaSmrg    } else {
1045ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset);
1046ab47cfaaSmrg        OUTREG32(PRI_STREAM_FBUF_ADDR1,0x80000000);
1047ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR0,(pScrn->fbOffset & 0xfffffffc) | 0x80000000);
1048ab47cfaaSmrg        OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset & 0xffffffc);
1049ab47cfaaSmrg    }
1050ab47cfaaSmrg
1051ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
1052ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
1053ab47cfaaSmrg
1054ab47cfaaSmrg    if (!psav->IsSecondary)
1055ab47cfaaSmrg    	/* bit 28:block write disable */
1056ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
1057ab47cfaaSmrg
1058ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
1059ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
1060ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
1061ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
1062ab47cfaaSmrg
1063ab47cfaaSmrg    if (!psav->bTiled) {
1064ab47cfaaSmrg        /*
1065ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
1066ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
1067ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
1068ab47cfaaSmrg         */
1069ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
1070ab47cfaaSmrg
1071ab47cfaaSmrg    }
1072ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
1073ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* tile format destination */
1074ab47cfaaSmrg
1075ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x3f) & 0x0000ffc0) >> 6) << 20;
1076ab47cfaaSmrg	if (psav->IsSecondary)
1077ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP16 | (pScrn->fbOffset>>6));
1078ab47cfaaSmrg	else
1079ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16 | (pScrn->fbOffset>>6));
1080ab47cfaaSmrg    }
1081ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
1082ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* tile format destination */
1083ab47cfaaSmrg
1084ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x1f) & 0x0000ffe0) >> 5) << 20;
1085ab47cfaaSmrg	if (psav->IsSecondary)
1086ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP32 | (pScrn->fbOffset>>6));
1087ab47cfaaSmrg	else
1088ab47cfaaSmrg            OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32 | (pScrn->fbOffset>>6));
1089ab47cfaaSmrg    }
1090ab47cfaaSmrg
1091ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
1092ab47cfaaSmrg    /* HW uses width */
1093ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
1094ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
1095ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
1096ab47cfaaSmrg
1097ab47cfaaSmrg    /*
1098ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
1099ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
1100ab47cfaaSmrg     *                  at A000:0.
1101ab47cfaaSmrg     */
1102ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG);
1103ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
1104ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
1105ab47cfaaSmrg
1106ab47cfaaSmrg    if (!psav->IsSecondary) {
1107ab47cfaaSmrg    	/* program the GBD and SBDs */
1108ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
1109ab47cfaaSmrg    	OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
1110ab47cfaaSmrg			     | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
1111ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
1112ab47cfaaSmrg    	OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1113ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
1114ab47cfaaSmrg    	OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1115ab47cfaaSmrg    }
1116ab47cfaaSmrg
1117ab47cfaaSmrg    /* turn on screen */
1118ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
1119ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
1120ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
1121ab47cfaaSmrg}
1122ab47cfaaSmrg
1123ab47cfaaSmrgvoid SavageSetGBD_2000(ScrnInfoPtr pScrn)
1124ab47cfaaSmrg{
1125ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1126ab47cfaaSmrg    unsigned long ulTmp, ulYRange;
1127ab47cfaaSmrg    unsigned char byte;
1128ab47cfaaSmrg    int bci_enable, tile16, tile32;
1129ab47cfaaSmrg
1130ab47cfaaSmrg    bci_enable = BCI_ENABLE_TWISTER;
1131ab47cfaaSmrg    tile16 = TILE_DESTINATION;
1132ab47cfaaSmrg    tile32 = TILE_DESTINATION;
1133ab47cfaaSmrg
1134ab47cfaaSmrg    if (pScrn->virtualX > 1024)
1135ab47cfaaSmrg      ulYRange = 0x40000000;
1136ab47cfaaSmrg    else
1137ab47cfaaSmrg      ulYRange = 0x20000000;
1138ab47cfaaSmrg
1139ab47cfaaSmrg
1140ab47cfaaSmrg    /* following is the enable case */
1141ab47cfaaSmrg
1142ab47cfaaSmrg    /* SR01:turn off screen */
1143ab47cfaaSmrg    OUTREG8 (SEQ_ADDRESS_REG,0x01);
1144ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) | 0x20;
1145ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
1146ab47cfaaSmrg
1147ab47cfaaSmrg
1148ab47cfaaSmrg    /* MM81C0 and 81B0 are used to control primary stream. */
1149ab47cfaaSmrg    OUTREG32(PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset);
1150ab47cfaaSmrg    OUTREG32(PRI_STREAM2_FBUF_ADDR0, pScrn->fbOffset);
1151ab47cfaaSmrg
1152ab47cfaaSmrg
1153ab47cfaaSmrg    /*
1154ab47cfaaSmrg     *  Program Primary Stream Stride Register.
1155ab47cfaaSmrg     *
1156ab47cfaaSmrg     *  Tell engine if tiling on or off, set primary stream stride, and
1157ab47cfaaSmrg     *  if tiling, set tiling bits/pixel and primary stream tile offset.
1158ab47cfaaSmrg     *  Note that tile offset (bits 16 - 29) must be scanline width in
1159ab47cfaaSmrg     *  bytes/128bytespertile * 256 Qwords/tile.  This is equivalent to
1160ab47cfaaSmrg     *  lDelta * 2.  Remember that if tiling, lDelta is screenwidth in
1161ab47cfaaSmrg     *  bytes padded up to an even number of tilewidths.
1162ab47cfaaSmrg     */
1163ab47cfaaSmrg    if (!psav->bTiled) {
1164ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE,
1165ab47cfaaSmrg		 ((psav->lDelta << 4) & 0x7ff0));
1166ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE,
1167ab47cfaaSmrg                 ((psav->lDelta << 4) & 0x7ff0));
1168ab47cfaaSmrg    } else {
1169ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE,
1170ab47cfaaSmrg		 (0x80000000 |((psav->lDelta << 4) & 0x7ff0)));
1171ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE,
1172ab47cfaaSmrg                 (0x80000000 |((psav->lDelta << 4) & 0x7ff0)));
1173ab47cfaaSmrg    }
1174ab47cfaaSmrg
1175ab47cfaaSmrg    /*
1176ab47cfaaSmrg     * CR67_3:
1177ab47cfaaSmrg     *  = 1  stream processor MMIO address and stride register
1178ab47cfaaSmrg     *       are used to control the primary stream
1179ab47cfaaSmrg     *  = 0  standard VGA address and stride registers
1180ab47cfaaSmrg     *       are used to control the primary streams
1181ab47cfaaSmrg     */
1182ab47cfaaSmrg
1183ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x67);
1184ab47cfaaSmrg    byte =  INREG8(CRT_DATA_REG) | 0x08;
1185ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
1186ab47cfaaSmrg
1187ab47cfaaSmrg
1188ab47cfaaSmrg    OUTREG32(0x8128, 0xFFFFFFFFL);
1189ab47cfaaSmrg    OUTREG32(0x812C, 0xFFFFFFFFL);
1190ab47cfaaSmrg
1191ab47cfaaSmrg    /* bit 28:block write disable */
1192ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
1193ab47cfaaSmrg
1194ab47cfaaSmrg    /* CR50, bit 7,6,0 = 111, Use GBD.*/
1195ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x50);
1196ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) | 0xC1;
1197ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
1198ab47cfaaSmrg
1199ab47cfaaSmrg    /* CR73 bit 5 = 0 block write disable */
1200ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,0x73);
1201ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & ~0x20;
1202ab47cfaaSmrg    OUTREG8(CRT_DATA_REG, byte);
1203ab47cfaaSmrg
1204ab47cfaaSmrg    if (!psav->bTiled) {
1205ab47cfaaSmrg        /*
1206ab47cfaaSmrg         *  Do not enable block_write even for non-tiling modes, because
1207ab47cfaaSmrg         *  the driver cannot determine if the memory type is the certain
1208ab47cfaaSmrg         *  type of SGRAM for which block_write can be used.
1209ab47cfaaSmrg         */
1210ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
1211ab47cfaaSmrg
1212ab47cfaaSmrg    }
1213ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 16) {
1214ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* tile format destination */
1215ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x3f) & 0x0000ffc0) >> 6) << 23;
1216ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16_2000 | ulYRange);
1217ab47cfaaSmrg        ulTmp |= (TILED_SURF_BPP16_2000 | ulYRange);
1218ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1219ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1220ab47cfaaSmrg    }
1221ab47cfaaSmrg    else if (pScrn->bitsPerPixel == 32) {
1222ab47cfaaSmrg        psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* tile format destination */
1223ab47cfaaSmrg        ulTmp =  (((pScrn->virtualX + 0x1f) & 0x0000ffe0) >> 5) << 23;
1224ab47cfaaSmrg        OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32_2000 | ulYRange);
1225ab47cfaaSmrg        ulTmp |= (TILED_SURF_BPP32_2000 | ulYRange);
1226ab47cfaaSmrg        OUTREG32(PRI_STREAM_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1227ab47cfaaSmrg        OUTREG32(PRI_STREAM2_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
1228ab47cfaaSmrg    }
1229ab47cfaaSmrg
1230ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
1231ab47cfaaSmrg    /* HW uses width */
1232ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Stride = (unsigned short)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
1233ab47cfaaSmrg    psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
1234ab47cfaaSmrg    psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
1235ab47cfaaSmrg
1236ab47cfaaSmrg    /*
1237ab47cfaaSmrg     * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
1238ab47cfaaSmrg     *       bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
1239ab47cfaaSmrg     *                  at A000:0.
1240ab47cfaaSmrg     */
1241ab47cfaaSmrg    OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG);
1242ab47cfaaSmrg    byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
1243ab47cfaaSmrg    OUTREG8(CRT_DATA_REG,byte);
1244ab47cfaaSmrg
1245ab47cfaaSmrg    /* program the GBD and SBDs */
1246ab47cfaaSmrg    OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
1247ab47cfaaSmrg    OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
1248ab47cfaaSmrg			     | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
1249ab47cfaaSmrg    OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
1250ab47cfaaSmrg    OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1251ab47cfaaSmrg    OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
1252ab47cfaaSmrg    OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
1253ab47cfaaSmrg
1254ab47cfaaSmrg    /* turn on screen */
1255ab47cfaaSmrg    OUTREG8(SEQ_ADDRESS_REG,0x01);
1256ab47cfaaSmrg    byte = INREG8(SEQ_DATA_REG) & ~0x20;
1257ab47cfaaSmrg    OUTREG8(SEQ_DATA_REG,byte);
1258ab47cfaaSmrg}
1259ab47cfaaSmrg
1260aa9e3350Smrg#if 0
1261ab47cfaaSmrgstatic
1262ab47cfaaSmrgvoid SavageRestoreAccelState(ScrnInfoPtr pScrn)
1263ab47cfaaSmrg{
1264ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1265ab47cfaaSmrg
1266ab47cfaaSmrg    psav->WaitIdleEmpty(psav);
1267ab47cfaaSmrg
1268ab47cfaaSmrg    return;
1269ab47cfaaSmrg}
1270aa9e3350Smrg#endif
1271ab47cfaaSmrg
1272ab47cfaaSmrg/* Acceleration init function, sets up pointers to our accelerated functions */
1273ab47cfaaSmrg
1274ab47cfaaSmrgBool
1275ab47cfaaSmrgSavageInitAccel(ScreenPtr pScreen)
1276ab47cfaaSmrg{
1277aa9e3350Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1278ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1279ab47cfaaSmrg
1280aa9e3350Smrg#ifdef SAVAGEDRI
1281ab47cfaaSmrg    if (psav->directRenderingEnabled) {
1282ab47cfaaSmrg        SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
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
14582b2b4fcbSmrg         *   turns out FALSE.
1459ab47cfaaSmrg         * Now just reduce the level to 14.5MB, things should be OK, while the hwmc frame buffer layout
14602b2b4fcbSmrg         *    calculation 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
15411473d951Smrgint SavageGetCopyROP(int rop) {
15421473d951Smrg
15431473d951Smrg    int ALUCopyROP[16] =
15441473d951Smrg    {
15451473d951Smrg       0x00, /*ROP_0 GXclear */
15461473d951Smrg       0x88, /*ROP_DSa GXand */
15471473d951Smrg       0x44, /*ROP_SDna GXandReverse */
15481473d951Smrg       0xCC, /*ROP_S GXcopy */
15491473d951Smrg       0x22, /*ROP_DSna GXandInverted */
15501473d951Smrg       0xAA, /*ROP_D GXnoop */
15511473d951Smrg       0x66, /*ROP_DSx GXxor */
15521473d951Smrg       0xEE, /*ROP_DSo GXor */
15531473d951Smrg       0x11, /*ROP_DSon GXnor */
15541473d951Smrg       0x99, /*ROP_DSxn GXequiv */
15551473d951Smrg       0x55, /*ROP_Dn GXinvert*/
15561473d951Smrg       0xDD, /*ROP_SDno GXorReverse */
15571473d951Smrg       0x33, /*ROP_Sn GXcopyInverted */
15581473d951Smrg       0xBB, /*ROP_DSno GXorInverted */
15591473d951Smrg       0x77, /*ROP_DSan GXnand */
15601473d951Smrg       0xFF, /*ROP_1 GXset */
15611473d951Smrg    };
15621473d951Smrg
15631473d951Smrg    return (ALUCopyROP[rop]);
15641473d951Smrg
15651473d951Smrg}
15661473d951Smrg
1567ab47cfaaSmrg/* Routines for debugging. */
1568ab47cfaaSmrg
1569ab47cfaaSmrg
1570ab47cfaaSmrgunsigned long
1571ab47cfaaSmrgwritedw( unsigned long addr, unsigned long value )
1572ab47cfaaSmrg{
1573ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1574ab47cfaaSmrg    OUTREG( addr, value );
1575ab47cfaaSmrg    return INREG( addr );
1576ab47cfaaSmrg}
1577ab47cfaaSmrg
1578ab47cfaaSmrgunsigned long
1579ab47cfaaSmrgreaddw( unsigned long addr )
1580ab47cfaaSmrg{
1581ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1582ab47cfaaSmrg    return INREG( addr );
1583ab47cfaaSmrg}
1584ab47cfaaSmrg
1585ab47cfaaSmrgunsigned long
1586ab47cfaaSmrgreadfb( unsigned long addr )
1587ab47cfaaSmrg{
1588ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1589ab47cfaaSmrg    char * videobuffer = (char *) psav->FBBase;
1590ab47cfaaSmrg    return *(volatile unsigned long*)(videobuffer + (addr & ~3) );
1591ab47cfaaSmrg}
1592ab47cfaaSmrg
1593ab47cfaaSmrgunsigned long
1594ab47cfaaSmrgwritefb( unsigned long addr, unsigned long value )
1595ab47cfaaSmrg{
1596ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1597ab47cfaaSmrg    char * videobuffer = (char *) psav->FBBase;
1598ab47cfaaSmrg    *(unsigned long*)(videobuffer + (addr & ~3)) = value;
1599ab47cfaaSmrg    return *(volatile unsigned long*)(videobuffer + (addr & ~3) );
1600ab47cfaaSmrg}
1601ab47cfaaSmrg
1602ab47cfaaSmrgvoid
1603ab47cfaaSmrgwritescan( unsigned long scan, unsigned long color )
1604ab47cfaaSmrg{
1605ab47cfaaSmrg    SavagePtr psav = SAVPTR(gpScrn);
1606ab47cfaaSmrg    int i;
1607ab47cfaaSmrg    char * videobuffer = (char *)psav->FBBase;
1608ab47cfaaSmrg    videobuffer += scan * gpScrn->displayWidth * gpScrn->bitsPerPixel >> 3;
1609ab47cfaaSmrg    for( i = gpScrn->displayWidth; --i; ) {
1610ab47cfaaSmrg	switch( gpScrn->bitsPerPixel ) {
1611ab47cfaaSmrg	    case 8:
1612ab47cfaaSmrg		*videobuffer++ = color;
1613ab47cfaaSmrg		break;
1614ab47cfaaSmrg	    case 16:
1615ab47cfaaSmrg		*(CARD16 *)videobuffer = color;
1616ab47cfaaSmrg		videobuffer += 2;
1617ab47cfaaSmrg		break;
1618ab47cfaaSmrg	    case 32:
1619ab47cfaaSmrg		*(CARD32 *)videobuffer = color;
1620ab47cfaaSmrg		videobuffer += 4;
1621ab47cfaaSmrg		break;
1622ab47cfaaSmrg	}
1623ab47cfaaSmrg    }
1624ab47cfaaSmrg}
1625