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