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