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