atipreinit.c revision 32b578d3
1/* 2 * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of Marc Aurele La France not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. Marc Aurele La France makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as-is" without express or implied warranty. 13 * 14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include <string.h> 28#include <stdio.h> 29 30#include "ati.h" 31#include "atiadjust.h" 32#include "atiaudio.h" 33#include "atibus.h" 34#include "atichip.h" 35#include "aticursor.h" 36#include "atidac.h" 37#include "atidsp.h" 38#include "atii2c.h" 39#include "atiload.h" 40#include "atilock.h" 41#include "atimach64.h" 42#include "atimach64accel.h" 43#include "atimach64io.h" 44#include "atimach64probe.h" 45#include "atimode.h" 46#include "atioption.h" 47#include "atipreinit.h" 48#include "atiprint.h" 49#include "atiprobe.h" 50#include "atividmem.h" 51#include "atiwonderio.h" 52#include "atixv.h" 53 54#include "vbe.h" 55#include "xf86RAC.h" 56 57/* 58 * FreeScreen handles the clean-up. 59 */ 60static Bool 61Mach64GetRec(ScrnInfoPtr pScrn) 62{ 63 if (!pScrn->driverPrivate) { 64 pScrn->driverPrivate = xnfcalloc(sizeof(ATIRec), 1); 65 memset(pScrn->driverPrivate, 0, sizeof(ATIRec)); 66 } 67 68 return TRUE; 69} 70 71/* 72 * ATIReportMemory -- 73 * 74 * This function reports on the amount and type of video memory found. 75 */ 76static void 77ATIReportMemory 78( 79 ScrnInfoPtr pScreenInfo, 80 ATIPtr pATI, 81 const char *MemoryTypeName 82) 83{ 84 char Buffer[128], *Message; 85 86 Message = Buffer + 87 snprintf(Buffer, SizeOf(Buffer), "%d kB of %s detected", 88 pATI->VideoRAM, MemoryTypeName); 89 90 if (pATI->VideoRAM > pScreenInfo->videoRam) 91 { 92 Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message, 93 " (using %d kB)", pScreenInfo->videoRam); 94 } 95 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "%s.\n", Buffer); 96} 97 98static const int videoRamSizes[] = 99 {512, 1024, 2*1024, 4*1024, 6*1024, 8*1024, 12*1024, 16*1024}; 100static const rgb defaultWeight = {0, 0, 0}; 101static const Gamma defaultGamma = {0.0, 0.0, 0.0}; 102 103/* 104 * ATIPrintNoiseIfRequested -- 105 * 106 * This function formats debugging information on the server's stderr when 107 * requested by the user through the server's verbosity setting. 108 */ 109static void 110ATIPrintNoiseIfRequested 111( 112 ATIPtr pATI, 113 CARD8 *BIOS, 114 unsigned int BIOSSize 115) 116{ 117 if (xf86GetVerbosity() <= 3) 118 return; 119 120 if (BIOSSize > 0) 121 ATIPrintBIOS(BIOS, BIOSSize); 122 xf86ErrorFVerb(4, "\n On server entry:\n"); 123 ATIPrintRegisters(pATI); 124} 125 126#define BIOS_SIZE 0x00010000U /* 64kB */ 127#define BIOSByte(_n) ((CARD8)(BIOS[_n])) 128#define BIOSWord(_n) ((CARD16)(BIOS[_n] | \ 129 (BIOS[(_n) + 1] << 8))) 130 131/* 132 * For Mach64 adapters, pick up, from the BIOS, the type of programmable 133 * clock generator (if any), and various information about it. 134 */ 135static void 136ati_bios_clock 137( 138 ScrnInfoPtr pScreenInfo, 139 ATIPtr pATI, 140 CARD8 *BIOS, 141 unsigned int ClockTable, 142 GDevPtr pGDev 143) 144{ 145 CARD16 ClockDac; 146 147 if (ClockTable > 0) 148 { 149 pATI->ProgrammableClock = BIOSByte(ClockTable); 150 pATI->ClockNumberToProgramme = BIOSByte(ClockTable + 0x06U); 151 pATI->refclk = BIOSWord(ClockTable + 0x08U); 152 pATI->refclk *= 10000; 153 } 154 else 155 { 156 /* 157 * Compensate for BIOS absence. Note that the reference 158 * frequency has already been set by option processing. 159 */ 160 if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL) 161 { 162 pATI->ProgrammableClock = ATI_CLOCK_INTERNAL; 163 } 164 else switch (pATI->DAC) 165 { 166 case ATI_DAC_STG1703: 167 pATI->ProgrammableClock = ATI_CLOCK_STG1703; 168 break; 169 170 case ATI_DAC_CH8398: 171 pATI->ProgrammableClock = ATI_CLOCK_CH8398; 172 break; 173 174 case ATI_DAC_ATT20C408: 175 pATI->ProgrammableClock = ATI_CLOCK_ATT20C408; 176 break; 177 178 case ATI_DAC_IBMRGB514: 179 pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514; 180 break; 181 182 default: /* Provisional */ 183 pATI->ProgrammableClock = ATI_CLOCK_ICS2595; 184 break; 185 } 186 187 /* This should be safe for all generators except IBM's RGB514 */ 188 pATI->ClockNumberToProgramme = 3; 189 } 190 191 pATI->ClockDescriptor = ATIClockDescriptors[ATI_CLOCK_FIXED]; 192 193 if ((pATI->ProgrammableClock > ATI_CLOCK_FIXED) && 194 (pATI->ProgrammableClock < ATI_CLOCK_MAX)) 195 { 196 /* 197 * Graphics PRO TURBO 1600's are unusual in that an ICS2595 is used 198 * to generate clocks for VGA modes, and an IBM RGB514 is used for 199 * accelerator modes. 200 */ 201 if ((pATI->ProgrammableClock == ATI_CLOCK_ICS2595) && 202 (pATI->DAC == ATI_DAC_IBMRGB514)) 203 pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514; 204 205 pATI->ClockDescriptor = ATIClockDescriptors[pATI->ProgrammableClock]; 206 } 207 208 ClockDac = pATI->DAC; 209 switch (pATI->ProgrammableClock) 210 { 211 case ATI_CLOCK_ICS2595: 212 /* 213 * Pick up reference divider (43 or 46) appropriate to the chip 214 * revision level. 215 */ 216 if (ClockTable > 0) 217 pATI->ClockDescriptor.MinM = 218 pATI->ClockDescriptor.MaxM = BIOSWord(ClockTable + 0x0AU); 219 else if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-0")) 220 pATI->ClockDescriptor.MinM = 221 pATI->ClockDescriptor.MaxM = 43; 222 else if (!xf86NameCmp(pGDev->clockchip, "ATI 18818-1")) 223 pATI->ClockDescriptor.MinM = 224 pATI->ClockDescriptor.MaxM = 46; 225 else 226 pATI->ProgrammableClock = ATI_CLOCK_UNKNOWN; 227 break; 228 229 case ATI_CLOCK_STG1703: 230 /* This one's also a RAMDAC */ 231 ClockDac = ATI_DAC_STG1703; 232 break; 233 234 case ATI_CLOCK_CH8398: 235 /* This one's also a RAMDAC */ 236 ClockDac = ATI_DAC_CH8398; 237 break; 238 239 case ATI_CLOCK_INTERNAL: 240 /* 241 * The reference divider has already been programmed by BIOS 242 * initialisation. Because, there is only one reference 243 * divider for all generated frequencies (including MCLK), it 244 * cannot be changed without reprogramming all clocks every 245 * time one of them needs a different reference divider. 246 * 247 * Besides, it's not a good idea to change the reference 248 * divider. BIOS initialisation sets it to a value that 249 * effectively prevents generating frequencies beyond the 250 * graphics controller's tolerance. 251 */ 252 pATI->ClockDescriptor.MinM = 253 pATI->ClockDescriptor.MaxM = ATIMach64GetPLLReg(PLL_REF_DIV); 254 255 /* The DAC is also integrated */ 256 if ((pATI->DAC & ~0x0FU) != ATI_DAC_INTERNAL) 257 ClockDac = ATI_DAC_INTERNAL; 258 259 break; 260 261 case ATI_CLOCK_ATT20C408: 262 /* This one's also a RAMDAC */ 263 ClockDac = ATI_DAC_ATT20C408; 264 break; 265 266 case ATI_CLOCK_IBMRGB514: 267 /* This one's also a RAMDAC */ 268 ClockDac = ATI_DAC_IBMRGB514; 269 pATI->ClockNumberToProgramme = 7; 270 break; 271 272 default: 273 break; 274 } 275 276 /* 277 * We now have up to two indications of what RAMDAC the adapter uses. 278 * They should be the same. The following test and corresponding 279 * action are under construction. 280 */ 281 if (pATI->DAC != ClockDac) 282 { 283 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 284 "Mach64 RAMDAC probe discrepancy detected:\n" 285 " DAC=0x%02X; ClockDac=0x%02X.\n", 286 pATI->DAC, ClockDac); 287 288 if (pATI->DAC == ATI_DAC_IBMRGB514) 289 { 290 pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514; 291 pATI->ClockDescriptor = ATIClockDescriptors[ATI_CLOCK_IBMRGB514]; 292 pATI->ClockNumberToProgramme = 7; 293 } 294 else 295 { 296 pATI->DAC = ClockDac; /* For now */ 297 } 298 } 299 300 switch (pATI->refclk / 100000) 301 { 302 case 143: 303 pATI->ReferenceNumerator = 157500; 304 pATI->ReferenceDenominator = 11; 305 break; 306 307 case 286: 308 pATI->ReferenceNumerator = 315000; 309 pATI->ReferenceDenominator = 11; 310 break; 311 312 default: 313 pATI->ReferenceNumerator = pATI->refclk / 1000; 314 pATI->ReferenceDenominator = 1; 315 break; 316 } 317} 318 319/* 320 * Pick up multimedia information, which will be at different 321 * displacements depending on table revision. 322 */ 323static void 324ati_bios_mmedia 325( 326 ScrnInfoPtr pScreenInfo, 327 ATIPtr pATI, 328 CARD8 *BIOS, 329 unsigned int VideoTable, 330 unsigned int HardwareTable 331) 332{ 333 pATI->Audio = ATI_AUDIO_NONE; 334 335 if (VideoTable > 0) 336 { 337 switch (BIOSByte(VideoTable - 0x02U)) 338 { 339 case 0x00U: 340 pATI->Tuner = BIOSByte(VideoTable) & 0x1FU; 341 342 /* 343 * XXX The VideoTable[1] byte is known to have been 344 * omitted in LTPro and Mobility BIOS'es. Any others? 345 */ 346 switch (pATI->Chip) 347 { 348 case ATI_CHIP_264LTPRO: 349 case ATI_CHIP_MOBILITY: 350 pATI->Decoder = BIOSByte(VideoTable + 0x01U) & 0x07U; 351 pATI->Audio = BIOSByte(VideoTable + 0x02U) & 0x0FU; 352 break; 353 354 default: 355 pATI->Decoder = BIOSByte(VideoTable + 0x02U) & 0x07U; 356 pATI->Audio = BIOSByte(VideoTable + 0x03U) & 0x0FU; 357 break; 358 } 359 360 break; 361 362 case 0x01U: 363 pATI->Tuner = BIOSByte(VideoTable) & 0x1FU; 364 pATI->Audio = BIOSByte(VideoTable + 0x01U) & 0x0FU; 365 pATI->Decoder = BIOSByte(VideoTable + 0x05U) & 0x0FU; 366 break; 367 368 default: 369 break; 370 } 371 } 372 373 if (HardwareTable > 0) 374 { 375 pATI->I2CType = BIOSByte(HardwareTable + 0x06U) & 0x0FU; 376 } 377} 378 379/* 380 * Determine panel dimensions and model. 381 */ 382static void 383ati_bios_panel_info 384( 385 ScrnInfoPtr pScreenInfo, 386 ATIPtr pATI, 387 CARD8 *BIOS, 388 unsigned int BIOSSize, 389 unsigned int LCDTable 390) 391{ 392 unsigned int LCDPanelInfo = 0; 393 char Buffer[128]; 394 int i, j; 395 396 if (LCDTable > 0) 397 { 398 LCDPanelInfo = BIOSWord(LCDTable + 0x0AU); 399 if (((LCDPanelInfo + 0x1DU) > BIOSSize) || 400 ((BIOSByte(LCDPanelInfo) != pATI->LCDPanelID) && 401 (pATI->LCDPanelID || (BIOSByte(LCDPanelInfo) > 0x1FU) || 402 (pATI->Chip <= ATI_CHIP_264LTPRO)))) 403 LCDPanelInfo = 0; 404 } 405 406 if (!LCDPanelInfo) 407 { 408 /* 409 * Scan BIOS for panel info table. 410 */ 411 for (i = 0; i <= (int)(BIOSSize - 0x1DU); i++) 412 { 413 /* Look for panel ID ... */ 414 if ((BIOSByte(i) != pATI->LCDPanelID) && 415 (pATI->LCDPanelID || (BIOSByte(i) > 0x1FU) || 416 (pATI->Chip <= ATI_CHIP_264LTPRO))) 417 continue; 418 419 /* ... followed by 24-byte panel model name ... */ 420 for (j = 0; j < 24; j++) 421 { 422 if ((CARD8)(BIOSByte(i + j + 1) - 0x20U) > 0x5FU) 423 { 424 i += j; 425 goto NextBIOSByte; 426 } 427 } 428 429 /* ... verify panel width ... */ 430 if (pATI->LCDHorizontal && 431 (pATI->LCDHorizontal != BIOSWord(i + 0x19U))) 432 continue; 433 434 /* ... and verify panel height */ 435 if (pATI->LCDVertical && 436 (pATI->LCDVertical != BIOSWord(i + 0x1BU))) 437 continue; 438 439 if (LCDPanelInfo) 440 { 441 /* 442 * More than one possibility, but don't care if all 443 * tables describe panels of the same size. 444 */ 445 if ((BIOSByte(LCDPanelInfo + 0x19U) == 446 BIOSByte(i + 0x19U)) && 447 (BIOSByte(LCDPanelInfo + 0x1AU) == 448 BIOSByte(i + 0x1AU)) && 449 (BIOSByte(LCDPanelInfo + 0x1BU) == 450 BIOSByte(i + 0x1BU)) && 451 (BIOSByte(LCDPanelInfo + 0x1CU) == 452 BIOSByte(i + 0x1CU))) 453 continue; 454 455 LCDPanelInfo = 0; 456 break; 457 } 458 459 LCDPanelInfo = i; 460 461 NextBIOSByte: ; 462 } 463 } 464 465 if (LCDPanelInfo > 0) 466 { 467 pATI->LCDPanelID = BIOSByte(LCDPanelInfo); 468 pATI->LCDHorizontal = BIOSWord(LCDPanelInfo + 0x19U); 469 pATI->LCDVertical = BIOSWord(LCDPanelInfo + 0x1BU); 470 } 471 472 if (LCDPanelInfo) 473 { 474 for (i = 0; i < 24; i++) 475 Buffer[i] = BIOSByte(LCDPanelInfo + 1 + i); 476 for (; --i >= 0; ) 477 if (Buffer[i] && Buffer[i] != ' ') 478 { 479 Buffer[i + 1] = '\0'; 480 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 481 "Panel model %s.\n", Buffer); 482 break; 483 } 484 } 485} 486 487/* 488 * ATIPreInit -- 489 * 490 * This function is only called once per screen at the start of the first 491 * server generation. 492 */ 493Bool 494ATIPreInit 495( 496 ScrnInfoPtr pScreenInfo, 497 int flags 498) 499{ 500 CARD8 BIOS[BIOS_SIZE]; 501 unsigned int BIOSSize = 0; 502 unsigned int ROMTable = 0, ClockTable = 0, FrequencyTable = 0; 503 unsigned int LCDTable = 0, VideoTable = 0; 504 unsigned int HardwareTable = 0; 505 506 char Buffer[128], *Message; 507 ATIPtr pATI; 508 GDevPtr pGDev; 509 EntityInfoPtr pEntity; 510 resPtr pResources; 511 pciVideoPtr pVideo; 512 DisplayModePtr pMode; 513 CARD32 IOValue; 514 int i, j; 515 int Numerator, Denominator; 516 int MinX, MinY; 517 ClockRange ATIClockRange = {NULL, 0, 80000, -1, TRUE, TRUE, 1, 1, 0}; 518 int DefaultmaxClock = 0; 519 int minPitch, maxPitch = 0xFFU, pitchInc, maxHeight = 0; 520 int ApertureSize = 0x00010000U; 521 int ModeType = M_T_BUILTIN; 522 LookupModeFlags Strategy = LOOKUP_CLOSEST_CLOCK; 523 int DefaultDepth; 524 Bool PreInitSuccess = FALSE; 525 526# define pATIHW (&pATI->OldHW) 527 528#ifndef AVOID_CPIO 529 530 xf86Int10InfoPtr pInt10Info = NULL; 531 vbeInfoPtr pVBE = NULL; 532 pointer pInt10Module, pDDCModule = NULL, pVBEModule = NULL; 533 534#endif /* AVOID_CPIO */ 535 536 if (pScreenInfo->numEntities != 1) 537 { 538 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 539 "Logic error: Number of attached entities not 1.\n"); 540 return FALSE; 541 } 542 543 if (!Mach64GetRec(pScreenInfo)) 544 return FALSE; 545 546 pATI = ATIPTR(pScreenInfo); 547 548 /* Register resources */ 549 pEntity = xf86GetEntityInfo(pScreenInfo->entityList[0]); 550 pGDev = pEntity->device; 551 pResources = pEntity->resources; 552 553 pATI->iEntity = pEntity->index; 554 pATI->Chip = pEntity->chipset; 555 pVideo = xf86GetPciInfoForEntity(pATI->iEntity); 556 557 xfree(pEntity); 558 559 if (!pResources) 560 pResources = xf86RegisterResources(pATI->iEntity, NULL, ResShared); 561 if (pResources) 562 { 563 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 564 "Unable to register the following bus resources:\n"); 565 xf86PrintResList(0, pResources); 566 xf86FreeResList(pResources); 567 return FALSE; 568 } 569 570 ConfiguredMonitor = NULL; 571 (void)memset(BIOS, 0, SizeOf(BIOS)); 572 573 if (!(flags & PROBE_DETECT)) 574 { 575 /* Set monitor */ 576 pScreenInfo->monitor = pScreenInfo->confScreen->monitor; 577 578 /* Set depth, bpp, etc. */ 579 if ((pATI->Chip < ATI_CHIP_264CT)) 580 { 581 i = NoDepth24Support; /* No support for >8bpp either */ 582 DefaultDepth = 8; 583 } 584 else 585 { 586 i = Support24bppFb | Support32bppFb; 587 DefaultDepth = 0; 588 } 589 590 if (!xf86SetDepthBpp(pScreenInfo, DefaultDepth, 0, 0, i)) 591 return FALSE; 592 593 for (j = 0; ; j++) 594 { 595 static const CARD8 AllowedDepthBpp[][2] = 596 { 597 { 8, 8}, 598 {15, 16}, 599 {16, 16}, 600 {24, 24}, 601 {24, 32} 602 }; 603 604 if (j < NumberOf(AllowedDepthBpp)) 605 { 606 if (pScreenInfo->depth > AllowedDepthBpp[j][0]) 607 continue; 608 609 if (pScreenInfo->depth == AllowedDepthBpp[j][0]) 610 { 611 if (pScreenInfo->bitsPerPixel > AllowedDepthBpp[j][1]) 612 continue; 613 614 if (pScreenInfo->bitsPerPixel == AllowedDepthBpp[j][1]) 615 break; 616 } 617 } 618 619 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 620 "Driver does not support depth %d at fbbpp %d.\n", 621 pScreenInfo->depth, pScreenInfo->bitsPerPixel); 622 return FALSE; 623 } 624 625 xf86PrintDepthBpp(pScreenInfo); 626 627 if ((i == NoDepth24Support) && (pScreenInfo->depth > 8)) 628 { 629 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 630 "Depth %d is not supported through this adapter.\n", 631 pScreenInfo->depth); 632 return FALSE; 633 } 634 635 /* Pick up XF86Config options */ 636 ATIProcessOptions(pScreenInfo, pATI); 637 } 638 639 if (!ATIMach64ProbeIO(pVideo, pATI)) 640 return FALSE; 641 642 ATIClaimBusSlot(pGDev->active, pATI); 643 644#ifndef AVOID_CPIO 645 646#ifdef TV_OUT 647 648 pATI->pVBE = NULL; 649 pATI->pInt10 = NULL; 650 651#endif /* TV_OUT */ 652 653 /* 654 * If there is an ix86-style BIOS, ensure its initialisation entry point 655 * has been executed, and retrieve DDC and VBE information from it. 656 */ 657 if (!(pInt10Module = xf86LoadSubModule(pScreenInfo, "int10"))) 658 { 659 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 660 "Unable to load int10 module.\n"); 661 } 662 else if (!(pInt10Info = xf86InitInt10(pATI->iEntity))) 663 { 664 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 665 "Unable to initialise int10 interface.\n"); 666 } 667 else 668 { 669 if (!(pDDCModule = xf86LoadSubModule(pScreenInfo, "ddc"))) 670 { 671 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 672 "Unable to load ddc module.\n"); 673 } 674 else 675 if (!(pVBEModule = xf86LoadSubModule(pScreenInfo, "vbe"))) 676 { 677 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 678 "Unable to load vbe module.\n"); 679 } 680 else 681 { 682 if ((pVBE = VBEInit(pInt10Info, pATI->iEntity))) 683 { 684 ConfiguredMonitor = vbeDoEDID(pVBE, pDDCModule); 685 } 686 } 687 688 if (!(flags & PROBE_DETECT)) 689 { 690 /* Validate, then make a private copy of, the initialised BIOS */ 691 CARD8 *pBIOS = xf86int10Addr(pInt10Info, pInt10Info->BIOSseg << 4); 692 693 if ((pBIOS[0] != 0x55U) || (pBIOS[1] != 0xAAU) || !pBIOS[2]) 694 { 695 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 696 "Unable to correctly retrieve adapter BIOS.\n"); 697 } 698 else 699 { 700 BIOSSize = pBIOS[2] << 9; 701 if (BIOSSize > BIOS_SIZE) 702 BIOSSize = BIOS_SIZE; 703 (void)memcpy(BIOS, pBIOS, BIOSSize); 704 } 705 } 706 } 707 708#ifndef TV_OUT 709 /* De-activate VBE */ 710 vbeFree(pVBE); 711 xf86UnloadSubModule(pVBEModule); 712 713 /* De-activate int10 */ 714 xf86FreeInt10(pInt10Info); 715 xf86UnloadSubModule(pInt10Module); 716#else 717 pATI->pInt10 = pInt10Info; 718 pATI->pVBE = pVBE; 719 pVBE = NULL; 720 pInt10Info = NULL; 721#endif /* TV_OUT */ 722 723 if (ConfiguredMonitor && !(flags & PROBE_DETECT)) 724 { 725 xf86PrintEDID(ConfiguredMonitor); 726 xf86SetDDCproperties(pScreenInfo, ConfiguredMonitor); 727 } 728 729 /* DDC module is no longer needed at this point */ 730 xf86UnloadSubModule(pDDCModule); 731 732#endif /* AVOID_CPIO */ 733 734 if (flags & PROBE_DETECT) 735 { 736 return TRUE; 737 } 738 739#ifndef AVOID_CPIO 740 741 /* I/O bases might no longer be valid after BIOS initialisation */ 742 { 743 if (pATI->CPIODecoding == BLOCK_IO) 744 pATI->CPIOBase = PCI_REGION_BASE(pVideo, 1, REGION_IO); 745 746 pATI->MMIOInLinear = FALSE; 747 748 /* Set MMIO address from PCI configuration space, if available */ 749 if ((pATI->Block0Base = PCI_REGION_BASE(pVideo, 2, REGION_MEM))) 750 { 751 pATI->Block0Base += 0x0400U; 752 } 753 } 754 755#endif /* AVOID_CPIO */ 756 757#ifdef AVOID_CPIO 758 759 pScreenInfo->racMemFlags = 760 RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; 761 762#else /* AVOID_CPIO */ 763 764 pScreenInfo->racIoFlags = 765 RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; 766 pScreenInfo->racMemFlags = RAC_FB | RAC_CURSOR; 767 768#endif /* AVOID_CPIO */ 769 770 /* Finish private area initialisation */ 771 pATI->nFIFOEntries = 16; /* For now */ 772 773 /* Finish probing the adapter */ 774 { 775 /* 776 * For MMIO register access, the MMIO address is computed when probing 777 * and there are no BIOS calls. This mapping should always succeed. 778 * 779 * For CPIO register access, the MMIO address is computed above in the 780 * presence of an auxiliary aperture. Otherwise, it is set to zero and 781 * gets computed when we read the linear aperture configuration. This 782 * mapping is either irrelevant or a no-op. 783 */ 784 if (!ATIMapApertures(pScreenInfo->scrnIndex, pATI)) 785 return FALSE; 786 787#ifdef AVOID_CPIO 788 789 if (!pATI->pBlock[0]) 790 { 791 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 792 "Unable to mmap() adapter registers.\n"); 793 return FALSE; 794 } 795 796#endif /* AVOID_CPIO */ 797 798 /* 799 * Verify register access by comparing against the CONFIG_CHIP_ID 800 * value saved by adapter detection. 801 */ 802 if (pATI->config_chip_id != inr(CONFIG_CHIP_ID)) 803 { 804 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 805 "Adapter registers not mapped correctly.\n"); 806 ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); 807 return FALSE; 808 } 809 810 pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL); 811 if (!(pATIHW->crtc_gen_cntl & CRTC_EN) && 812 (pATI->Chip >= ATI_CHIP_264CT)) 813 { 814 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 815 "Adapter has not been initialised.\n"); 816 goto bail_locked; 817 } 818 819#ifdef AVOID_CPIO 820 821 if (!(pATIHW->crtc_gen_cntl & CRTC_EXT_DISP_EN)) 822 { 823 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 824 "Adapters found to be in VGA mode on server entry are not" 825 " supported by the MMIO-only version of this driver.\n"); 826 goto bail_locked; 827 } 828 829#endif /* AVOID_CPIO */ 830 831 pATIHW->mem_cntl = inr(MEM_CNTL); 832 if (pATI->Chip < ATI_CHIP_264VTB) 833 { 834 IOValue = GetBits(pATIHW->mem_cntl, CTL_MEM_SIZE); 835 pATI->VideoRAM = videoRamSizes[IOValue]; 836 } 837 else 838 { 839 pATI->nFIFOEntries = /* Don't care */ 840 (unsigned int)(-1) >> 1; 841 842 IOValue = GetBits(pATIHW->mem_cntl, CTL_MEM_SIZEB); 843 if (IOValue < 8) 844 pATI->VideoRAM = (IOValue + 1) * 512; 845 else if (IOValue < 12) 846 pATI->VideoRAM = (IOValue - 3) * 1024; 847 else 848 pATI->VideoRAM = (IOValue - 7) * 2048; 849 } 850 851 IOValue = inr(CONFIG_STATUS64_0); 852 if (pATI->Chip >= ATI_CHIP_264CT) 853 { 854 pATI->MemoryType = GetBits(IOValue, CFG_MEM_TYPE_T); 855 } 856 else 857 { 858 pATI->MemoryType = GetBits(IOValue, CFG_MEM_TYPE); 859 } 860 861 pATI->LCDPanelID = -1; 862 863 if (pATI->Chip >= ATI_CHIP_264CT) 864 { 865 /* Get LCD panel id */ 866 if (pATI->Chip == ATI_CHIP_264LT) 867 { 868 pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID); 869 870 pATIHW->horz_stretching = inr(HORZ_STRETCHING); 871 pATIHW->vert_stretching = inr(VERT_STRETCHING); 872 pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL); 873 } 874 else if ((pATI->Chip == ATI_CHIP_264LTPRO) || 875 (pATI->Chip == ATI_CHIP_264XL) || 876 (pATI->Chip == ATI_CHIP_MOBILITY)) 877 { 878 pATI->LCDPanelID = GetBits(IOValue, CFG_PANEL_ID); 879 880 pATIHW->lcd_index = inr(LCD_INDEX); 881 pATIHW->horz_stretching = 882 ATIMach64GetLCDReg(LCD_HORZ_STRETCHING); 883 pATI->LCDHorizontal = 884 GetBits(pATIHW->horz_stretching, HORZ_PANEL_SIZE); 885 if (pATI->LCDHorizontal) 886 { 887 if (pATI->LCDHorizontal == MaxBits(HORZ_PANEL_SIZE)) 888 pATI->LCDHorizontal = 0; 889 else 890 pATI->LCDHorizontal = 891 (pATI->LCDHorizontal + 1) << 3; 892 } 893 pATIHW->ext_vert_stretch = 894 ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH); 895 pATI->LCDVertical = 896 GetBits(pATIHW->ext_vert_stretch, VERT_PANEL_SIZE); 897 if (pATI->LCDVertical) 898 { 899 if (pATI->LCDVertical == MaxBits(VERT_PANEL_SIZE)) 900 pATI->LCDVertical = 0; 901 else 902 pATI->LCDVertical++; 903 } 904 pATIHW->vert_stretching = 905 ATIMach64GetLCDReg(LCD_VERT_STRETCHING); 906 pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL); 907 outr(LCD_INDEX, pATIHW->lcd_index); 908 } 909 910 /* 911 * Don't bother with panel support if it hasn't been previously 912 * enabled. 913 */ 914 if ((pATI->LCDPanelID >= 0) && 915 !(pATIHW->horz_stretching & HORZ_STRETCH_EN) && 916 !(pATIHW->vert_stretching & VERT_STRETCH_EN) && 917 !(pATIHW->lcd_gen_ctrl & LCD_ON)) 918 { 919 /* 920 * At this point, if an XL or Mobility BIOS hasn't set 921 * panel dimensions, then there is no panel. Otherwise, 922 * keep any panel disabled to allow for modes greater than 923 * the panel's dimensions. 924 */ 925 if ((pATI->Chip >= ATI_CHIP_264XL) && 926 (!pATI->LCDHorizontal || !pATI->LCDVertical)) 927 pATI->LCDPanelID = -1; 928 else 929 pATI->OptionPanelDisplay = FALSE; 930 } 931 } 932 933 /* Get DAC type */ 934 pATI->DAC = GetBits(inr(DAC_CNTL), DAC_TYPE); 935 936 if (pATI->Chip < ATI_CHIP_264CT) 937 { 938 /* Factor in what the BIOS says the DAC is */ 939 pATI->DAC = ATI_DAC(pATI->DAC, 940 GetBits(inr(SCRATCH_REG1), BIOS_INIT_DAC_SUBTYPE)); 941 } 942 943 /* 944 * RAMDAC types 0 & 1 for Mach64's are different than those for 945 * Mach32's. 946 */ 947 if (pATI->DAC < ATI_DAC_ATI68875) 948 pATI->DAC += ATI_DAC_INTERNAL; 949 } 950 951 { 952 ROMTable = BIOSWord(0x48U); 953 if ((ROMTable < 0x0002U) || 954 (BIOSWord(ROMTable - 0x02U) < 0x0012U) || 955 ((ROMTable + BIOSWord(ROMTable - 0x02U)) > BIOSSize)) 956 ROMTable = 0; 957 958 if (ROMTable > 0) 959 { 960 ClockTable = BIOSWord(ROMTable + 0x10U); 961 if ((ClockTable + 0x20U) > BIOSSize) 962 ClockTable = 0; 963 964 if (BIOSWord(ROMTable - 0x02U) >= 0x0048U) 965 { 966 VideoTable = BIOSWord(ROMTable + 0x46U); 967 if ((VideoTable < 0x08U) || 968 (BIOSByte(VideoTable - 0x01U) < 0x08U) || 969 (BIOSByte(VideoTable - 0x02U) > 0x01U) || 970 ((VideoTable + BIOSByte(VideoTable - 0x01U)) > BIOSSize)) 971 VideoTable = 0; 972 } 973 974 if (BIOSWord(ROMTable - 0x02U) >= 0x004AU) 975 { 976 HardwareTable = BIOSWord(ROMTable + 0x48U); 977 if (((HardwareTable + 0x08U) > BIOSSize) || 978 (memcmp(BIOS + HardwareTable, "$ATI", 4) != 0)) 979 HardwareTable = 0; 980 } 981 } 982 983 ati_bios_clock(pScreenInfo, pATI, BIOS, ClockTable, pGDev); 984 985 ati_bios_mmedia(pScreenInfo, pATI, BIOS, VideoTable, HardwareTable); 986 987 if (pATI->LCDPanelID >= 0) 988 { 989 LCDTable = BIOSWord(0x78U); 990 if ((LCDTable + BIOSByte(LCDTable + 5)) > BIOSSize) 991 LCDTable = 0; 992 993 ati_bios_panel_info(pScreenInfo, pATI, BIOS, BIOSSize, LCDTable); 994 } 995 996 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3, 997 "BIOS Data: BIOSSize=0x%04X, ROMTable=0x%04X.\n", 998 BIOSSize, ROMTable); 999 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3, 1000 "BIOS Data: ClockTable=0x%04X, FrequencyTable=0x%04X.\n", 1001 ClockTable, FrequencyTable); 1002 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3, 1003 "BIOS Data: LCDTable=0x%04X.\n", 1004 LCDTable); 1005 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3, 1006 "BIOS Data: VideoTable=0x%04X, HardwareTable=0x%04X.\n", 1007 VideoTable, HardwareTable); 1008 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_INFO, 3, 1009 "BIOS Data: I2CType=0x%02X, Tuner=0x%02X, Decoder=0x%02X," 1010 " Audio=0x%02X.\n", 1011 pATI->I2CType, pATI->Tuner, pATI->Decoder, pATI->Audio); 1012 } 1013 1014 ATIUnlock(pATI); /* Unlock registers */ 1015 1016 /* Report what was found */ 1017 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1018 "%s graphics controller detected.\n", 1019 xf86TokenToString(Mach64Chipsets, pATI->Chip)); 1020 1021 { 1022 Message = Buffer + snprintf(Buffer, SizeOf(Buffer), "Chip type %04X", 1023 pATI->ChipType); 1024 if (!(pATI->ChipType & ~(CHIP_CODE_0 | CHIP_CODE_1))) 1025 Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message, 1026 " (%c%c)", 1027 GetBits(pATI->ChipType, CHIP_CODE_1) + 0x41U, 1028 GetBits(pATI->ChipType, CHIP_CODE_0) + 0x41U); 1029 else if ((pATI->ChipType & 0x4040U) == 0x4040U) 1030 Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message, 1031 " \"%c%c\"", 1032 GetByte(pATI->ChipType, 1), GetByte(pATI->ChipType, 0)); 1033 if ((pATI->Chip >= ATI_CHIP_264CT) && (pATI->Chip != ATI_CHIP_Mach64)) 1034 Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message, 1035 ", version %d, foundry %s", 1036 pATI->ChipVersion, ATIFoundryNames[pATI->ChipFoundry]); 1037 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1038 "%s, class %d, revision 0x%02X.\n", 1039 Buffer, pATI->ChipClass, pATI->ChipRevision); 1040 } 1041 1042 { 1043 Message = Buffer + snprintf(Buffer, SizeOf(Buffer), 1044 "%s bus interface detected", ATIBusNames[pATI->BusType]); 1045 1046#ifndef AVOID_CPIO 1047 1048 { 1049 Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message, 1050 "; %s I/O base is 0x%04lX", 1051 (pATI->CPIODecoding == SPARSE_IO) ? "sparse" : "block", 1052 pATI->CPIOBase); 1053 } 1054 1055#endif /* AVOID_CPIO */ 1056 1057 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "%s.\n", Buffer); 1058 } 1059 1060#ifndef AVOID_CPIO 1061 1062 if (pATI->CPIO_VGAWonder) 1063 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1064 "VGA Wonder registers at I/O port 0x%04lX.\n", 1065 pATI->CPIO_VGAWonder); 1066 1067#endif /* AVOID_CPIO */ 1068 1069 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1070 "ATI Mach64 adapter detected.\n"); 1071 1072 if (pATI->Chip >= ATI_CHIP_264GT) 1073 xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE, 1074 "For information on using the multimedia capabilities\n\tof this" 1075 " adapter, please see http://gatos.sf.net.\n"); 1076 1077 if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL) 1078 { 1079 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1080 "Internal RAMDAC (subtype %d) detected.\n", pATI->DAC & 0x0FU); 1081 } 1082 else 1083 { 1084 const SymTabRec *DAC; 1085 1086 for (DAC = ATIDACDescriptors; ; DAC++) 1087 { 1088 if (pATI->DAC == DAC->token) 1089 { 1090 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1091 "%s RAMDAC detected.\n", DAC->name); 1092 break; 1093 } 1094 1095 if (pATI->DAC < DAC->token) 1096 { 1097 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0, 1098 "Unknown RAMDAC type 0x%02X detected.\n", pATI->DAC); 1099 break; 1100 } 1101 } 1102 } 1103 1104 if (!xf86LinearVidMem()) 1105 { 1106 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 1107 "A linear aperture is not available.\n"); 1108 goto bail; 1109 } 1110 1111 /* 1112 * Set colour weights. 1113 */ 1114 1115 if (pATI->Chip < ATI_CHIP_264CT) 1116 pScreenInfo->rgbBits = 6; 1117 else 1118 pScreenInfo->rgbBits = 8; 1119 pATI->rgbBits = pScreenInfo->rgbBits; 1120 if (!xf86SetWeight(pScreenInfo, defaultWeight, defaultWeight)) 1121 goto bail; 1122 1123 if ((pScreenInfo->depth > 8) && 1124 ((pScreenInfo->weight.red != pScreenInfo->weight.blue) || 1125 (pScreenInfo->weight.red != (CARD32)(pScreenInfo->depth / 3)) || 1126 ((CARD32)pScreenInfo->depth != (pScreenInfo->weight.red + 1127 pScreenInfo->weight.green + 1128 pScreenInfo->weight.blue)))) 1129 { 1130 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 1131 "Driver does not support weight %d%d%d for depth %d.\n", 1132 (int)pScreenInfo->weight.red, (int)pScreenInfo->weight.green, 1133 (int)pScreenInfo->weight.blue, pScreenInfo->depth); 1134 goto bail; 1135 } 1136 1137 /* 1138 * Set default visual. 1139 */ 1140 1141 if (!xf86SetDefaultVisual(pScreenInfo, -1)) 1142 goto bail; 1143 1144 if ((pScreenInfo->depth > 8) && 1145 (((pScreenInfo->defaultVisual | DynamicClass) != DirectColor) || 1146 ((pScreenInfo->defaultVisual == DirectColor) && 1147 (pATI->DAC == ATI_DAC_INTERNAL)))) 1148 { 1149 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 1150 "Driver does not support default visual %s for depth %d.\n", 1151 xf86GetVisualName(pScreenInfo->defaultVisual), 1152 pScreenInfo->depth); 1153 goto bail; 1154 } 1155 1156 /* 1157 * Set colour gamma. 1158 */ 1159 1160 if (!xf86SetGamma(pScreenInfo, defaultGamma)) 1161 goto bail; 1162 1163 pATI->depth = pScreenInfo->depth; 1164 pATI->bitsPerPixel = pScreenInfo->bitsPerPixel; 1165 pATI->weight = pScreenInfo->weight; 1166 pATI->XModifier = pATI->bitsPerPixel / UnitOf(pATI->bitsPerPixel); 1167 1168 /* 1169 * Determine which CRT controller to use for video modes. 1170 */ 1171 1172 { 1173 pATI->NewHW.crtc = ATI_CRTC_MACH64; 1174 1175 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 1176 "Using Mach64 accelerator CRTC.\n"); 1177 1178#ifndef AVOID_CPIO 1179 1180 if (pATI->VGAAdapter) 1181 { 1182 /* 1183 * No need for VGA I/O resources during operating state (but they 1184 * are still decoded). 1185 */ 1186 pResources = 1187 xf86SetOperatingState(resVgaIo, pATI->iEntity, ResUnusedOpr); 1188 if (pResources) 1189 { 1190 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 1191 "Logic error setting operating state for VGA I/O.\n"); 1192 xf86FreeResList(pResources); 1193 } 1194 1195 if (pATI->CPIO_VGAWonder) 1196 { 1197 pResources = xf86SetOperatingState(pATI->VGAWonderResources, 1198 pATI->iEntity, ResUnusedOpr); 1199 if (pResources) 1200 { 1201 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 1202 "Logic error setting operating state for" 1203 " VGAWonder I/O.\n"); 1204 xf86FreeResList(pResources); 1205 } 1206 } 1207 } 1208 1209#endif /* AVOID_CPIO */ 1210 1211 } 1212 1213 /* 1214 * Decide between the CRT and the panel. 1215 */ 1216 if (pATI->LCDPanelID >= 0) 1217 { 1218 if (!pATI->OptionPanelDisplay) 1219 { 1220 xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG, 1221 "Using CRT interface and disabling digital flat panel.\n"); 1222 } 1223 else 1224 { 1225 unsigned HDisplay, VDisplay; 1226 CARD8 ClockMask, PostMask; 1227 1228 /* 1229 * Determine porch data. This groks the mode on entry to extract 1230 * the width and position of its sync and blanking pulses, and 1231 * considers any overscan as part of the displayed area, given that 1232 * the overscan is also stretched. 1233 * 1234 * This also attempts to determine panel dimensions but cannot do 1235 * so for one that is "auto-stretched". 1236 */ 1237 1238 if (pATI->Chip == ATI_CHIP_264LT) 1239 { 1240 pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL); 1241 1242 /* Set up to read non-shadow registers */ 1243 if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN) 1244 outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN); 1245 } 1246 else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 1247 (pATI->Chip == ATI_CHIP_264XL) || 1248 (pATI->Chip == ATI_CHIP_MOBILITY)) */ 1249 { 1250 pATIHW->lcd_index = inr(LCD_INDEX); 1251 pATIHW->config_panel = ATIMach64GetLCDReg(LCD_CONFIG_PANEL); 1252 pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL); 1253 1254 /* Set up to read non-shadow registers */ 1255 if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN) 1256 ATIMach64PutLCDReg(LCD_GEN_CNTL, 1257 pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN); 1258 } 1259 1260#ifndef AVOID_CPIO 1261 1262 if (!(pATIHW->crtc_gen_cntl & CRTC_EXT_DISP_EN)) 1263 { 1264 unsigned HBlankStart, HSyncStart, HSyncEnd, HBlankEnd, HTotal; 1265 unsigned VBlankStart, VSyncStart, VSyncEnd, VBlankEnd, VTotal; 1266 1267 pATIHW->clock = (inb(R_GENMO) & 0x0CU) >> 2; 1268 1269 pATIHW->crt[2] = GetReg(CRTX(pATI->CPIO_VGABase), 0x02U); 1270 pATIHW->crt[3] = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U); 1271 pATIHW->crt[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U); 1272 pATIHW->crt[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U); 1273 pATIHW->crt[9] = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U); 1274 pATIHW->crt[21] = GetReg(CRTX(pATI->CPIO_VGABase), 0x15U); 1275 pATIHW->crt[22] = GetReg(CRTX(pATI->CPIO_VGABase), 0x16U); 1276 1277 pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP); 1278 pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); 1279 pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP); 1280 pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); 1281 1282 /* Switch to shadow registers */ 1283 if (pATI->Chip == ATI_CHIP_264LT) 1284 outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN); 1285 else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 1286 (pATI->Chip == ATI_CHIP_264XL) || 1287 (pATI->Chip == ATI_CHIP_MOBILITY)) */ 1288 ATIMach64PutLCDReg(LCD_GEN_CNTL, 1289 pATIHW->lcd_gen_ctrl | SHADOW_RW_EN); 1290 1291 pATIHW->shadow_vga[2] = 1292 GetReg(CRTX(pATI->CPIO_VGABase), 0x02U); 1293 pATIHW->shadow_vga[3] = 1294 GetReg(CRTX(pATI->CPIO_VGABase), 0x03U); 1295 pATIHW->shadow_vga[5] = 1296 GetReg(CRTX(pATI->CPIO_VGABase), 0x05U); 1297 pATIHW->shadow_vga[7] = 1298 GetReg(CRTX(pATI->CPIO_VGABase), 0x07U); 1299 pATIHW->shadow_vga[9] = 1300 GetReg(CRTX(pATI->CPIO_VGABase), 0x09U); 1301 pATIHW->shadow_vga[21] = 1302 GetReg(CRTX(pATI->CPIO_VGABase), 0x15U); 1303 pATIHW->shadow_vga[22] = 1304 GetReg(CRTX(pATI->CPIO_VGABase), 0x16U); 1305 1306 pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP); 1307 pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); 1308 pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP); 1309 pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); 1310 1311 /* 1312 * HSyncStart and HSyncEnd should equal their shadow 1313 * counterparts. Otherwise, due to a chip bug, the panel might 1314 * not sync, regardless of which register set is used to drive 1315 * the panel. There are certain combinations of register 1316 * values where the panel does in fact sync, but it remains 1317 * impossible to accurately determine the horizontal sync pulse 1318 * timing actually seen by the panel. 1319 * 1320 * Note that this hardware bug does not affect the CRT output. 1321 */ 1322 if (((pATIHW->crtc_h_sync_strt_wid ^ 1323 pATIHW->shadow_h_sync_strt_wid) & 1324 (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI | 1325 CRTC_H_SYNC_WID))) 1326 { 1327 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_NOTICE, 0, 1328 "Invalid horizontal sync pulse timing detected in mode" 1329 " on server entry.\n"); 1330 1331 /* Don't trust input timing */ 1332 pATI->OptionLCDSync = TRUE; 1333 ModeType = 0; 1334 } 1335 1336 /* Merge in shadow registers as appropriate */ 1337 if (pATIHW->lcd_gen_ctrl & SHADOW_EN) 1338 { 1339 pATIHW->crt[2] = pATIHW->shadow_vga[2]; 1340 pATIHW->crt[3] = pATIHW->shadow_vga[3]; 1341 pATIHW->crt[5] = pATIHW->shadow_vga[5]; 1342 1343 /* XXX Does this apply to VGA? If so, what about the LT? */ 1344 if ((pATI->Chip < ATI_CHIP_264LTPRO) || 1345 !(pATIHW->config_panel & DONT_SHADOW_HEND)) 1346 { 1347 pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP; 1348 pATIHW->crtc_h_total_disp |= 1349 pATIHW->shadow_h_total_disp & CRTC_H_DISP; 1350 } 1351 1352 pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL; 1353 pATIHW->crtc_h_total_disp |= 1354 pATIHW->shadow_h_total_disp & CRTC_H_TOTAL; 1355 pATIHW->crtc_h_sync_strt_wid = 1356 pATIHW->shadow_h_sync_strt_wid; 1357 1358 /* XXX Does this apply to VGA? */ 1359 if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND) 1360 { 1361 pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP; 1362 pATIHW->crtc_v_total_disp |= 1363 pATIHW->shadow_v_total_disp & CRTC_V_DISP; 1364 } 1365 1366 if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) 1367 { 1368 pATIHW->crt[7] = pATIHW->shadow_vga[7]; 1369 pATIHW->crt[9] = pATIHW->shadow_vga[9]; 1370 pATIHW->crt[21] = pATIHW->shadow_vga[21]; 1371 pATIHW->crt[22] = pATIHW->shadow_vga[22]; 1372 1373 pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL; 1374 pATIHW->crtc_v_total_disp |= 1375 pATIHW->shadow_v_total_disp & CRTC_V_TOTAL; 1376 } 1377 } 1378 1379 if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) 1380 pATIHW->crtc_v_sync_strt_wid = 1381 pATIHW->shadow_v_sync_strt_wid; 1382 1383 /* 1384 * Decipher input timing. This is complicated by the fact that 1385 * the full width of all timing parameters, except for the 1386 * blanking pulses, is only available through the accelerator 1387 * registers, not the VGA ones. Blanking pulse boundaries must 1388 * then be interpolated. 1389 * 1390 * Note that, in VGA mode, the accelerator's sync width fields 1391 * are actually end positions, not widths. 1392 */ 1393 HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP); 1394 HSyncStart = 1395 (GetBits(pATIHW->crtc_h_sync_strt_wid, 1396 CRTC_H_SYNC_STRT_HI) * 1397 (MaxBits(CRTC_H_SYNC_STRT) + 1)) | 1398 GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT); 1399 HSyncEnd = (HSyncStart & ~MaxBits(CRTC_H_SYNC_WID)) | 1400 GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID); 1401 if (HSyncStart >= HSyncEnd) 1402 HSyncEnd += MaxBits(CRTC_H_SYNC_WID) + 1; 1403 HTotal = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL); 1404 1405 HBlankStart = (HDisplay & ~0xFFU) | pATIHW->crt[2]; 1406 if (HDisplay > HBlankStart) 1407 HBlankStart += 0x0100U; 1408 HBlankEnd = (HSyncEnd & ~0x3FU) | 1409 ((pATIHW->crt[5] >> 2) & 0x20U) | 1410 (pATIHW->crt[3] & 0x1FU); 1411 if (HSyncEnd > (HBlankEnd + 1)) 1412 HBlankEnd += 0x40U; 1413 1414 VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP); 1415 VSyncStart = 1416 GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT); 1417 VSyncEnd = (VSyncStart & ~MaxBits(CRTC_V_SYNC_END_VGA)) | 1418 GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_END_VGA); 1419 if (VSyncStart > VSyncEnd) 1420 VSyncEnd += MaxBits(CRTC_V_SYNC_END_VGA) + 1; 1421 VTotal = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL); 1422 1423 VBlankStart = (VDisplay & ~0x03FFU) | 1424 ((pATIHW->crt[9] << 4) & 0x0200U) | 1425 ((pATIHW->crt[7] << 5) & 0x0100U) | pATIHW->crt[21]; 1426 if (VDisplay > VBlankStart) 1427 VBlankStart += 0x0400U; 1428 VBlankEnd = (VSyncEnd & ~0x00FFU) | pATIHW->crt[22]; 1429 if (VSyncEnd > (VBlankEnd + 1)) 1430 VBlankEnd += 0x0100U; 1431 1432 pATI->LCDHBlankWidth = HBlankEnd - HBlankStart; 1433 pATI->LCDHSyncStart = HSyncStart - HBlankStart; 1434 pATI->LCDHSyncWidth = HSyncEnd - HSyncStart; 1435 1436 pATI->LCDVBlankWidth = VBlankEnd - VBlankStart; 1437 pATI->LCDVSyncStart = VSyncStart - VBlankStart; 1438 pATI->LCDVSyncWidth = VSyncEnd - VSyncStart; 1439 1440 HDisplay = HTotal + 5 - pATI->LCDHBlankWidth; 1441 VDisplay = VTotal + 2 - pATI->LCDVBlankWidth; 1442 } 1443 else 1444 1445#endif /* AVOID_CPIO */ 1446 1447 { 1448 pATIHW->clock = inr(CLOCK_CNTL) & 0x03U; 1449 1450 pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP); 1451 pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); 1452 pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP); 1453 pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); 1454 pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT); 1455 pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM); 1456 1457 /* Switch to shadow registers */ 1458 if (pATI->Chip == ATI_CHIP_264LT) 1459 outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN); 1460 else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 1461 (pATI->Chip == ATI_CHIP_264XL) || 1462 (pATI->Chip == ATI_CHIP_MOBILITY)) */ 1463 ATIMach64PutLCDReg(LCD_GEN_CNTL, 1464 pATIHW->lcd_gen_ctrl | SHADOW_RW_EN); 1465 1466 /* Oddly enough, there are no shadow overscan registers */ 1467 pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP); 1468 pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); 1469 pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP); 1470 pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); 1471 1472 /* 1473 * HSyncStart and HSyncEnd should equal their shadow 1474 * counterparts. Otherwise, due to a chip bug, the panel might 1475 * not sync, regardless of which register set is used to drive 1476 * the panel. There are certain combinations of register 1477 * values where the panel does in fact sync, but it remains 1478 * impossible to accurately determine the horizontal sync pulse 1479 * timing actually seen by the panel. 1480 * 1481 * Note that this hardware bug does not affect the CRT output. 1482 */ 1483 if (((pATIHW->crtc_h_sync_strt_wid ^ 1484 pATIHW->shadow_h_sync_strt_wid) & 1485 (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI | 1486 CRTC_H_SYNC_WID))) 1487 { 1488 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_NOTICE, 0, 1489 "Invalid horizontal sync pulse timing detected in mode" 1490 " on server entry.\n"); 1491 1492 /* Don't trust input timing */ 1493 pATI->OptionLCDSync = TRUE; 1494 ModeType = 0; 1495 } 1496 1497 /* Merge in shadow registers as appropriate */ 1498 if (pATIHW->lcd_gen_ctrl & SHADOW_EN) 1499 { 1500 /* XXX What about the LT? */ 1501 if ((pATI->Chip < ATI_CHIP_264LTPRO) || 1502 !(pATIHW->config_panel & DONT_SHADOW_HEND)) 1503 { 1504 pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP; 1505 pATIHW->crtc_h_total_disp |= 1506 pATIHW->shadow_h_total_disp & CRTC_H_DISP; 1507 } 1508 1509 pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL; 1510 pATIHW->crtc_h_total_disp |= 1511 pATIHW->shadow_h_total_disp & CRTC_H_TOTAL; 1512 pATIHW->crtc_h_sync_strt_wid = 1513 pATIHW->shadow_h_sync_strt_wid; 1514 1515 if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND) 1516 { 1517 pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP; 1518 pATIHW->crtc_v_total_disp |= 1519 pATIHW->shadow_v_total_disp & CRTC_V_DISP; 1520 } 1521 1522 if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) 1523 { 1524 pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL; 1525 pATIHW->crtc_v_total_disp |= 1526 pATIHW->shadow_v_total_disp & CRTC_V_TOTAL; 1527 } 1528 } 1529 1530 if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) 1531 pATIHW->crtc_v_sync_strt_wid = 1532 pATIHW->shadow_v_sync_strt_wid; 1533 1534 /* Decipher input timing */ 1535 HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP) + 1536 GetBits(pATIHW->ovr_wid_left_right, OVR_WID_LEFT) + 1537 GetBits(pATIHW->ovr_wid_left_right, OVR_WID_RIGHT); 1538 VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP) + 1539 GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_TOP) + 1540 GetBits(pATIHW->ovr_wid_top_bottom, OVR_WID_BOTTOM); 1541 1542 pATI->LCDHSyncStart = 1543 (GetBits(pATIHW->crtc_h_sync_strt_wid, 1544 CRTC_H_SYNC_STRT_HI) * 1545 (MaxBits(CRTC_H_SYNC_STRT) + 1)) + 1546 GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT) - 1547 HDisplay; 1548 pATI->LCDHSyncWidth = 1549 GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID); 1550 pATI->LCDHBlankWidth = 1551 GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL) - 1552 HDisplay; 1553 pATI->LCDVSyncStart = 1554 GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT) - 1555 VDisplay; 1556 pATI->LCDVSyncWidth = 1557 GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_WID); 1558 pATI->LCDVBlankWidth = 1559 GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL) - 1560 VDisplay; 1561 1562 HDisplay++; 1563 VDisplay++; 1564 } 1565 1566 /* Restore LCD registers */ 1567 if (pATI->Chip == ATI_CHIP_264LT) 1568 { 1569 outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl); 1570 } 1571 else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || 1572 (pATI->Chip == ATI_CHIP_264XL) || 1573 (pATI->Chip == ATI_CHIP_MOBILITY)) */ 1574 { 1575 ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl); 1576 outr(LCD_INDEX, pATIHW->lcd_index); 1577 } 1578 1579 HDisplay <<= 3; 1580 pATI->LCDHSyncStart <<= 3; 1581 pATI->LCDHSyncWidth <<= 3; 1582 pATI->LCDHBlankWidth <<= 3; 1583 1584 /* Calculate panel dimensions implied by the input timing */ 1585 if ((pATIHW->horz_stretching & 1586 (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) == 1587 HORZ_STRETCH_EN) 1588 { 1589 if (pATIHW->horz_stretching & HORZ_STRETCH_MODE) 1590 { 1591 if (pATIHW->horz_stretching & HORZ_STRETCH_BLEND) 1592 { 1593 HDisplay = 1594 (HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) / 1595 GetBits(pATIHW->horz_stretching, 1596 HORZ_STRETCH_BLEND); 1597 } 1598 } 1599 else if (((pATIHW->horz_stretching & HORZ_STRETCH_LOOP) > 1600 HORZ_STRETCH_LOOP15) || 1601 (pATIHW->horz_stretching & 1602 SetBits(1, HORZ_STRETCH_RATIO))) 1603 { 1604 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 1605 "Ignoring invalid horizontal stretch ratio in mode on" 1606 " server entry.\n"); 1607 } 1608 else 1609 { 1610 IOValue = 1611 GetBits(pATIHW->horz_stretching, HORZ_STRETCH_RATIO); 1612 1613 switch (GetBits(pATIHW->horz_stretching, 1614 HORZ_STRETCH_LOOP)) 1615 { 1616 case GetBits(HORZ_STRETCH_LOOP09, HORZ_STRETCH_LOOP): 1617 i = 9; 1618 IOValue &= (1 << 9) - 1; 1619 break; 1620 1621 case GetBits(HORZ_STRETCH_LOOP11, HORZ_STRETCH_LOOP): 1622 i = 11; 1623 IOValue &= (1 << 11) - 1; 1624 break; 1625 1626 case GetBits(HORZ_STRETCH_LOOP12, HORZ_STRETCH_LOOP): 1627 i = 12; 1628 IOValue &= (1 << 12) - 1; 1629 break; 1630 1631 case GetBits(HORZ_STRETCH_LOOP14, HORZ_STRETCH_LOOP): 1632 i = 14; 1633 IOValue &= (1 << 14) - 1; 1634 break; 1635 1636 case GetBits(HORZ_STRETCH_LOOP15, HORZ_STRETCH_LOOP): 1637 default: /* Muffle compiler */ 1638 i = 15; 1639 IOValue &= (1 << 15) - 1; 1640 break; 1641 } 1642 1643 if (IOValue) 1644 { 1645 /* Count the number of bits in IOValue */ 1646 j = (IOValue >> 1) & 0x36DBU; 1647 j = IOValue - j - ((j >> 1) & 0x36DBU); 1648 j = ((j + (j >> 3)) & 0x71C7U) % 0x3FU; 1649 1650 HDisplay = (HDisplay * i) / j; 1651 } 1652 } 1653 } 1654 1655 if ((pATIHW->vert_stretching & VERT_STRETCH_EN) && 1656 !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO)) 1657 { 1658 if ((pATIHW->vert_stretching & VERT_STRETCH_USE0) || 1659 (VDisplay <= 350)) 1660 IOValue = 1661 GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO0); 1662 else if (VDisplay <= 400) 1663 IOValue = 1664 GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO1); 1665 else if ((VDisplay <= 480) || 1666 !(pATIHW->ext_vert_stretch & VERT_STRETCH_RATIO3)) 1667 IOValue = 1668 GetBits(pATIHW->vert_stretching, VERT_STRETCH_RATIO2); 1669 else 1670 IOValue = 1671 GetBits(pATIHW->ext_vert_stretch, VERT_STRETCH_RATIO3); 1672 1673 if (IOValue) 1674 VDisplay = 1675 (VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) / 1676 IOValue; 1677 } 1678 1679 /* Match calculated dimensions to probed dimensions */ 1680 if (!pATI->LCDHorizontal) 1681 { 1682 if ((pATIHW->horz_stretching & 1683 (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) != 1684 (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) 1685 pATI->LCDHorizontal = HDisplay; 1686 } 1687 else if (pATI->LCDHorizontal != (int)HDisplay) 1688 { 1689 if ((pATIHW->horz_stretching & 1690 (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) != 1691 (HORZ_STRETCH_EN | AUTO_HORZ_RATIO)) 1692 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 4, 1693 "Inconsistent panel horizontal dimension:" 1694 " %d and %d.\n", pATI->LCDHorizontal, HDisplay); 1695 HDisplay = pATI->LCDHorizontal; 1696 } 1697 1698 if (!pATI->LCDVertical) 1699 { 1700 if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) || 1701 !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO)) 1702 pATI->LCDVertical = VDisplay; 1703 } 1704 else if (pATI->LCDVertical != (int)VDisplay) 1705 { 1706 if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) || 1707 !(pATIHW->ext_vert_stretch & AUTO_VERT_RATIO)) 1708 xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 4, 1709 "Inconsistent panel vertical dimension: %d and %d.\n", 1710 pATI->LCDVertical, VDisplay); 1711 VDisplay = pATI->LCDVertical; 1712 } 1713 1714 if (!pATI->LCDHorizontal || !pATI->LCDVertical) 1715 { 1716 if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO)) 1717 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 1718 "Unable to determine dimensions of panel (ID %d).\n", 1719 pATI->LCDPanelID); 1720 else 1721 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 1722 "Unable to determine dimensions of panel.\n"); 1723 1724 goto bail; 1725 } 1726 1727 /* If the mode on entry wasn't stretched, adjust timings */ 1728 if (!(pATIHW->horz_stretching & HORZ_STRETCH_EN) && 1729 (pATI->LCDHorizontal > (int)HDisplay)) 1730 { 1731 HDisplay = pATI->LCDHorizontal - HDisplay; 1732 if (pATI->LCDHSyncStart >= HDisplay) 1733 pATI->LCDHSyncStart -= HDisplay; 1734 else 1735 pATI->LCDHSyncStart = 0; 1736 pATI->LCDHBlankWidth -= HDisplay; 1737 HDisplay = pATI->LCDHSyncStart + pATI->LCDHSyncWidth; 1738 if (pATI->LCDHBlankWidth < HDisplay) 1739 pATI->LCDHBlankWidth = HDisplay; 1740 } 1741 1742 if (!(pATIHW->vert_stretching & VERT_STRETCH_EN) && 1743 (pATI->LCDVertical > (int)VDisplay)) 1744 { 1745 VDisplay = pATI->LCDVertical - VDisplay; 1746 if (pATI->LCDVSyncStart >= VDisplay) 1747 pATI->LCDVSyncStart -= VDisplay; 1748 else 1749 pATI->LCDVSyncStart = 0; 1750 pATI->LCDVBlankWidth -= VDisplay; 1751 VDisplay = pATI->LCDVSyncStart + pATI->LCDVSyncWidth; 1752 if (pATI->LCDVBlankWidth < VDisplay) 1753 pATI->LCDVBlankWidth = VDisplay; 1754 } 1755 1756 if (pATI->LCDPanelID || (pATI->Chip <= ATI_CHIP_264LTPRO)) 1757 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1758 "%dx%d panel (ID %d) detected.\n", 1759 pATI->LCDHorizontal, pATI->LCDVertical, pATI->LCDPanelID); 1760 else 1761 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1762 "%dx%d panel detected.\n", 1763 pATI->LCDHorizontal, pATI->LCDVertical); 1764 1765 /* 1766 * Determine panel clock. This must be done after option 1767 * processing so that the adapter's reference frequency is always 1768 * available. 1769 * 1770 * Get post divider. A GCC bug has caused the following expression 1771 * to be broken down into its individual components. 1772 */ 1773 ClockMask = PLL_VCLK0_XDIV << pATIHW->clock; 1774 PostMask = PLL_VCLK0_POST_DIV << (pATIHW->clock * 2); 1775 i = GetBits(ATIMach64GetPLLReg(PLL_XCLK_CNTL), ClockMask); 1776 i *= MaxBits(PLL_VCLK0_POST_DIV) + 1; 1777 i |= GetBits(ATIMach64GetPLLReg(PLL_VCLK_POST_DIV), PostMask); 1778 1779 /* Calculate clock of mode on entry */ 1780 Numerator = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV + pATIHW->clock) * 1781 pATI->ReferenceNumerator; 1782 Denominator = pATI->ClockDescriptor.MinM * 1783 pATI->ReferenceDenominator * 1784 pATI->ClockDescriptor.PostDividers[i]; 1785 pATI->LCDClock = ATIDivide(Numerator, Denominator, 1, 0); 1786 1787 xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 1788 "Panel clock is %.3f MHz.\n", 1789 (double)(pATI->LCDClock) / 1000.0); 1790 1791 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 1792 "Using digital flat panel interface%s.\n", 1793 pATI->OptionCRTDisplay ? 1794 " to display on both CRT and panel" : ""); 1795 } 1796 } 1797 1798 /* 1799 * Finish detecting video RAM size. 1800 */ 1801 pScreenInfo->videoRam = pATI->VideoRAM; 1802 1803 { 1804 { 1805 /* Get adapter's linear aperture configuration */ 1806 pATIHW->config_cntl = inr(CONFIG_CNTL); 1807 pATI->LinearBase = 1808 GetBits(pATIHW->config_cntl, CFG_MEM_AP_LOC) << 22; 1809 if ((pATIHW->config_cntl & CFG_MEM_AP_SIZE) != CFG_MEM_AP_SIZE) 1810 { 1811 pATI->LinearSize = 1812 GetBits(pATIHW->config_cntl, CFG_MEM_AP_SIZE) << 22; 1813 1814 /* 1815 * Linear aperture could have been disabled (but still 1816 * assigned) by BIOS initialisation. 1817 */ 1818 if (pATI->LinearBase && !pATI->LinearSize) 1819 { 1820 if ((pATI->Chip <= ATI_CHIP_88800GXD) && 1821 (pATI->VideoRAM < 4096)) 1822 pATI->LinearSize = 4 * 1024 * 1024; 1823 else 1824 pATI->LinearSize = 8 * 1024 * 1024; 1825 } 1826 } 1827 1828 if (pATI->LinearBase && pATI->LinearSize) 1829 { 1830 int AcceleratorVideoRAM = 0, ServerVideoRAM; 1831 1832#ifndef AVOID_CPIO 1833 1834 /* 1835 * Unless specified in PCI configuration space, set MMIO 1836 * address to tail end of linear aperture. 1837 */ 1838 if (!pATI->Block0Base) 1839 { 1840 pATI->Block0Base = 1841 pATI->LinearBase + pATI->LinearSize - 0x00000400U; 1842 pATI->MMIOInLinear = TRUE; 1843 } 1844 1845#endif /* AVOID_CPIO */ 1846 1847 AcceleratorVideoRAM = pATI->LinearSize >> 10; 1848 1849 /* 1850 * Account for MMIO area at the tail end of the linear 1851 * aperture, if it is needed or if it cannot be disabled. 1852 */ 1853 if (pATI->MMIOInLinear || (pATI->Chip < ATI_CHIP_264VTB)) 1854 AcceleratorVideoRAM -= 2; 1855 1856 ServerVideoRAM = pATI->VideoRAM; 1857 1858 if (pATI->Cursor > ATI_CURSOR_SOFTWARE) 1859 { 1860 /* 1861 * Allocate a 1 kB cursor image area at the top of the 1862 * little-endian aperture, just before any MMIO area that 1863 * might also be there. 1864 */ 1865 if (ServerVideoRAM > AcceleratorVideoRAM) 1866 ServerVideoRAM = AcceleratorVideoRAM; 1867 1868 ServerVideoRAM--; 1869 pATI->CursorOffset = ServerVideoRAM << 10; 1870 pATI->CursorBase = pATI->LinearBase + pATI->CursorOffset; 1871 1872 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 1873 "Storing hardware cursor image at 0x%08lX.\n", 1874 pATI->CursorBase); 1875 } 1876 1877 { 1878 CARD32 PageSize = getpagesize() >> 10; 1879 1880#if X_BYTE_ORDER == X_LITTLE_ENDIAN 1881 1882 /* 1883 * MMIO areas must be mmap()'ed separately to avoid write 1884 * combining them. Thus, they might not end up still 1885 * adjacent with the little-endian linear aperture after 1886 * mmap()'ing. So, round down the linear aperture size to 1887 * avoid an overlap. Any hardware cursor image area might 1888 * not end up being write combined, but this seems 1889 * preferable to further reducing the video memory size 1890 * advertised to the server. 1891 * 1892 * XXX Ideally this should be dealt with in the os-support 1893 * layer, i.e., it should be possible to reset a 1894 * subarea's write combining after it has been 1895 * mmap()'ed, but doing so currently causes the removal 1896 * of write combining for the entire aperture. 1897 */ 1898 if (pATI->MMIOInLinear) 1899 AcceleratorVideoRAM -= AcceleratorVideoRAM % PageSize; 1900 1901#else /* if X_BYTE_ORDER != X_LITTLE_ENDIAN */ 1902 1903 /* 1904 * Big-endian apertures are 8 MB higher and don't contain 1905 * an MMIO area. 1906 */ 1907 pATI->LinearBase += 0x00800000U; 1908 AcceleratorVideoRAM = pATI->LinearSize >> 10; 1909 1910#endif /* X_BYTE_ORDER */ 1911 1912 if (ServerVideoRAM > AcceleratorVideoRAM) 1913 ServerVideoRAM = AcceleratorVideoRAM; 1914 else if (AcceleratorVideoRAM > pATI->VideoRAM) 1915 AcceleratorVideoRAM = pATI->VideoRAM; 1916 1917 PageSize--; 1918 AcceleratorVideoRAM = 1919 (AcceleratorVideoRAM + PageSize) & ~PageSize; 1920 1921 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 1922 "Using %d MB linear aperture at 0x%08lX.\n", 1923 pATI->LinearSize >> 20, pATI->LinearBase); 1924 1925 /* Only mmap what is needed */ 1926 ApertureSize = pATI->LinearSize = 1927 AcceleratorVideoRAM << 10; 1928 } 1929 1930 if (ServerVideoRAM < pATI->VideoRAM) 1931 { 1932 pScreenInfo->videoRam = ServerVideoRAM; 1933 xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE, 1934 "Virtual resolutions will be limited to %d kB\n due to" 1935 " linear aperture size and/or placement of hardware" 1936 " cursor image area.\n", 1937 ServerVideoRAM); 1938 } 1939 } 1940 } 1941 1942 if (!pATI->LinearBase || !pATI->LinearSize) 1943 { 1944 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 1945 "Linear aperture not available.\n"); 1946 goto bail; 1947 } 1948 1949 if (pATI->Block0Base) 1950 { 1951 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 1952 "Using Block 0 MMIO aperture at 0x%08lX.\n", pATI->Block0Base); 1953 1954 /* Set Block1 MMIO address if supported */ 1955 if (pATI->Chip >= ATI_CHIP_264VT) 1956 { 1957 pATI->Block1Base = pATI->Block0Base - 0x00000400U; 1958 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 1959 "Using Block 1 MMIO aperture at 0x%08lX.\n", 1960 pATI->Block1Base); 1961 } 1962 } 1963 } 1964 1965#ifndef AVOID_CPIO 1966 1967 if (pATI->VGAAdapter) 1968 { 1969 /* 1970 * Free VGA memory aperture during operating state (but it is still 1971 * decoded). 1972 */ 1973 pResources = xf86SetOperatingState(resVgaMem, pATI->iEntity, 1974 ResUnusedOpr); 1975 if (pResources) 1976 { 1977 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 1978 "Logic error setting operating state for VGA memory" 1979 " aperture.\n"); 1980 xf86FreeResList(pResources); 1981 } 1982 } 1983 1984#endif /* AVOID_CPIO */ 1985 1986 /* 1987 * Remap apertures. Must lock and re-unlock around this in case the 1988 * remapping fails. 1989 */ 1990 ATILock(pATI); 1991 ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); 1992 if (!ATIMapApertures(pScreenInfo->scrnIndex, pATI)) 1993 return FALSE; 1994 1995 ATIUnlock(pATI); 1996 1997 if (pATI->OptionAccel) 1998 { 1999 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 2000 "MMIO write caching %sabled.\n", 2001 pATI->OptionMMIOCache ? "en" : "dis"); 2002 } 2003 2004 { 2005 if (pATI->Chip >= ATI_CHIP_264CT) 2006 ATIReportMemory(pScreenInfo, pATI, 2007 ATIMemoryTypeNames_264xT[pATI->MemoryType]); 2008 else if (pATI->Chip == ATI_CHIP_88800CX) 2009 ATIReportMemory(pScreenInfo, pATI, 2010 ATIMemoryTypeNames_88800CX[pATI->MemoryType]); 2011 else 2012 ATIReportMemory(pScreenInfo, pATI, 2013 ATIMemoryTypeNames_Mach[pATI->MemoryType]); 2014 } 2015 2016 /* 2017 * Finish banking setup. This needs to be fixed to not assume the mode on 2018 * entry is a VGA mode. XXX 2019 */ 2020 2021#ifndef AVOID_CPIO 2022 2023 if (!pATI->VGAAdapter) 2024 { 2025 pATI->NewHW.SetBank = ATIx8800SetBank; 2026 pATI->NewHW.nPlane = 0; 2027 2028 pATIHW->crtc = pATI->NewHW.crtc; 2029 2030 pATIHW->SetBank = (ATIBankProcPtr)NoopDDA; 2031 } 2032 else 2033 { 2034 Bool ext_disp_en = (pATI->LockData.crtc_gen_cntl & CRTC_EXT_DISP_EN); 2035 Bool vga_ap_en = (pATI->LockData.config_cntl & CFG_MEM_VGA_AP_EN); 2036 Bool vga_color_256 = (GetReg(SEQX, 0x04U) & 0x08U); 2037 2038 pATI->NewHW.SetBank = ATIMach64SetBankPacked; 2039 pATI->NewHW.nPlane = 1; 2040 2041 pATIHW->crtc = ATI_CRTC_VGA; 2042 2043 if (ext_disp_en) 2044 pATIHW->crtc = ATI_CRTC_MACH64; 2045 2046 if ((pATIHW->crtc != ATI_CRTC_VGA) || vga_color_256) 2047 pATIHW->nPlane = 1; 2048 else 2049 pATIHW->nPlane = 4; 2050 2051 /* VideoRAM is a multiple of 512kB and BankSize is 64kB */ 2052 pATIHW->nBank = pATI->VideoRAM / (pATIHW->nPlane * 0x40U); 2053 2054 if ((pATIHW->crtc == ATI_CRTC_VGA) && !vga_ap_en) 2055 { 2056 pATIHW->SetBank = (ATIBankProcPtr)NoopDDA; 2057 pATIHW->nBank = 1; 2058 } 2059 else if (pATIHW->nPlane == 1) 2060 { 2061 pATIHW->SetBank = ATIMach64SetBankPacked; 2062 } 2063 else 2064 { 2065 pATIHW->SetBank = ATIMach64SetBankPlanar; 2066 } 2067 } 2068 2069#else /* AVOID_CPIO */ 2070 2071 { 2072 pATIHW->crtc = pATI->NewHW.crtc; 2073 } 2074 2075#endif /* AVOID_CPIO */ 2076 2077 if (pATI->OptionShadowFB) 2078 { 2079 /* Until ShadowFB becomes a true screen wrapper, if it ever does... */ 2080 2081 if (pATI->OptionAccel) 2082 { 2083 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 2084 "Cannot shadow an accelerated frame buffer.\n"); 2085 pATI->OptionShadowFB = FALSE; 2086 } 2087 else 2088 { 2089 xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 2090 "Using shadow frame buffer.\n"); 2091 } 2092 } 2093 2094 /* 264VT-B's and later have DSP registers */ 2095 if ((pATI->Chip >= ATI_CHIP_264VTB) && 2096 !ATIDSPPreInit(pScreenInfo->scrnIndex, pATI)) 2097 goto bail; 2098 2099 /* 2100 * Determine minClock and maxClock. For adapters with supported 2101 * programmable clock generators, start with an absolute maximum. 2102 */ 2103 if (pATI->ClockDescriptor.MaxN > 0) 2104 { 2105 Numerator = pATI->ClockDescriptor.MaxN * pATI->ReferenceNumerator; 2106 Denominator = pATI->ClockDescriptor.MinM * pATI->ReferenceDenominator * 2107 pATI->ClockDescriptor.PostDividers[0]; 2108 2109 /* 2110 * An integrated PLL behaves as though the reference frequency were 2111 * doubled. It also does not appear to care about the colour depth. 2112 */ 2113 if (pATI->ProgrammableClock == ATI_CLOCK_INTERNAL) 2114 Numerator <<= 1; 2115 2116 ATIClockRange.maxClock = (Numerator / (Denominator * 1000)) * 1000; 2117 2118 Numerator = pATI->ClockDescriptor.MinN * pATI->ReferenceNumerator; 2119 Denominator = pATI->ClockDescriptor.MaxM * pATI->ReferenceDenominator * 2120 pATI->ClockDescriptor.PostDividers[pATI->ClockDescriptor.NumD - 1]; 2121 2122 if (pATI->ProgrammableClock == ATI_CLOCK_INTERNAL) 2123 Numerator <<= 1; 2124 2125 ATIClockRange.minClock = (Numerator / (Denominator * 1000)) * 1000; 2126 2127 if (pATI->XCLKFeedbackDivider) 2128 { 2129 /* Possibly reduce maxClock due to memory bandwidth */ 2130 Numerator = pATI->XCLKFeedbackDivider * 2 * 2131 pATI->ReferenceNumerator; 2132 Denominator = pATI->ClockDescriptor.MinM * 2133 pATI->XCLKReferenceDivider * pATI->ReferenceDenominator; 2134 2135 { 2136 Denominator *= pATI->bitsPerPixel / 4; 2137 } 2138 2139 i = (6 - 2) - pATI->XCLKPostDivider; 2140 2141 i = (ATIDivide(Numerator, Denominator, i, -1) / 1000) * 1000; 2142 if (i < ATIClockRange.maxClock) 2143 ATIClockRange.maxClock = i; 2144 } 2145 } 2146 2147 /* 2148 * Assume an internal DAC can handle whatever frequency the internal PLL 2149 * can produce (with the reference divider set by BIOS initialisation), but 2150 * default maxClock to a lower chip-specific default. 2151 */ 2152 if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL) 2153 { 2154 int DacSpeed; 2155 switch (pATI->bitsPerPixel) 2156 { 2157 case 15: 2158 case 16: 2159 DacSpeed = pGDev->dacSpeeds[DAC_BPP16]; 2160 break; 2161 2162 case 24: 2163 DacSpeed = pGDev->dacSpeeds[DAC_BPP24]; 2164 break; 2165 2166 case 32: 2167 DacSpeed = pGDev->dacSpeeds[DAC_BPP32]; 2168 break; 2169 2170 default: 2171 DacSpeed = 0; 2172 break; 2173 } 2174 if (!DacSpeed) 2175 DacSpeed = pGDev->dacSpeeds[DAC_BPP8]; 2176 if (DacSpeed < ATIClockRange.maxClock) 2177 { 2178 DefaultmaxClock = 135000; 2179 2180 if (pATI->depth > 8) 2181 DefaultmaxClock = 80000; 2182 2183 if ((pATI->Chip >= ATI_CHIP_264VTB) && 2184 (pATI->Chip != ATI_CHIP_Mach64)) 2185 { 2186 if ((pATI->Chip >= ATI_CHIP_264VT4) && 2187 (pATI->Chip != ATI_CHIP_264LTPRO)) 2188 DefaultmaxClock = 230000; 2189 else if (pATI->Chip >= ATI_CHIP_264VT3) 2190 DefaultmaxClock = 200000; 2191 else 2192 DefaultmaxClock = 170000; 2193 } 2194 if (DacSpeed > DefaultmaxClock) 2195 ATIClockRange.maxClock = DacSpeed; 2196 else if (DefaultmaxClock < ATIClockRange.maxClock) 2197 ATIClockRange.maxClock = DefaultmaxClock; 2198 } 2199 } 2200 else 2201 { 2202 switch(pATI->DAC) 2203 { 2204 case ATI_DAC_STG1700: 2205 case ATI_DAC_STG1702: 2206 case ATI_DAC_STG1703: 2207 DefaultmaxClock = 110000; 2208 break; 2209 2210 case ATI_DAC_IBMRGB514: 2211 pATI->maxClock = 220000; 2212 { 2213 DefaultmaxClock = 220000; 2214 } 2215 break; 2216 2217 default: 2218 2219#ifndef AVOID_CPIO 2220 2221 if (pATI->CPIO_VGAWonder && (pATI->VideoRAM < 1024)) 2222 { 2223 DefaultmaxClock = 2224 (GetBits(BIOSByte(0x44U), 0x04U) * 5000) + 40000; 2225 } 2226 else 2227 2228#endif /* AVOID_CPIO */ 2229 2230 { 2231 DefaultmaxClock = 80000; 2232 } 2233 2234 break; 2235 } 2236 2237 if (DefaultmaxClock < ATIClockRange.maxClock) 2238 ATIClockRange.maxClock = DefaultmaxClock; 2239 } 2240 2241 /* 2242 * Determine available pixel clock frequencies. 2243 */ 2244 2245 if ((pATI->ProgrammableClock <= ATI_CLOCK_FIXED) || 2246 (pATI->ProgrammableClock >= ATI_CLOCK_MAX)) 2247 { 2248 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 2249 "Unsupported or non-programmable clock generator.\n"); 2250 goto bail; 2251 } 2252 2253 ATIClockPreInit(pScreenInfo, pATI); 2254 Strategy = LOOKUP_BEST_REFRESH; 2255 2256 /* 2257 * Mode validation. 2258 */ 2259 2260 if (pATI->Chip >= ATI_CHIP_264CT) 2261 { 2262 minPitch = 8; 2263 } 2264 else 2265 { 2266 minPitch = 16; 2267 } 2268 2269 pitchInc = minPitch * pATI->bitsPerPixel; 2270 2271 pScreenInfo->maxHValue = (MaxBits(CRTC_H_TOTAL) + 1) << 3; 2272 2273 if (pATI->Chip < ATI_CHIP_264VT) 2274 { 2275 /* 2276 * ATI finally fixed accelerated doublescanning in the 264VT 2277 * and later. On 88800's, the bit is documented to exist, but 2278 * only doubles the vertical timings. On the 264CT and 264ET, 2279 * the bit is ignored. 2280 */ 2281 ATIClockRange.doubleScanAllowed = FALSE; 2282 2283 /* CRTC_H_TOTAL is one bit narrower */ 2284 pScreenInfo->maxHValue >>= 1; 2285 } 2286 2287 pScreenInfo->maxVValue = MaxBits(CRTC_V_TOTAL) + 1; 2288 2289 maxPitch = minPitch * MaxBits(CRTC_PITCH); 2290 2291 if (pATI->OptionAccel) 2292 { 2293 /* 2294 * Set engine restrictions on coordinate space. Use maxPitch for the 2295 * horizontal and maxHeight for the vertical. 2296 */ 2297 if (maxPitch > (ATIMach64MaxX / pATI->XModifier)) 2298 maxPitch = ATIMach64MaxX / pATI->XModifier; 2299 2300 maxHeight = ATIMach64MaxY; 2301 2302 /* 2303 * For SGRAM & WRAM adapters, the display engine limits the pitch to 2304 * multiples of 64 bytes. 2305 */ 2306 if ((pATI->Chip >= ATI_CHIP_264CT) && 2307 ((pATI->Chip >= ATI_CHIP_264VTB) || 2308 (pATI->MemoryType >= MEM_264_SGRAM))) 2309 pitchInc = pATI->XModifier * (64 * 8); 2310 } 2311 2312 if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0)) 2313 { 2314 /* 2315 * Given LCD modes are more tightly controlled than CRT modes, allow 2316 * the user the option of not specifying a panel's horizontal sync 2317 * and/or vertical refresh tolerances. 2318 */ 2319 Strategy |= LOOKUP_OPTIONAL_TOLERANCES; 2320 2321 if (ModeType == M_T_BUILTIN) 2322 { 2323 /* 2324 * Add a mode to the end of the monitor's list for the panel's 2325 * native resolution. 2326 */ 2327 pMode = (DisplayModePtr)xnfcalloc(1, SizeOf(DisplayModeRec)); 2328 pMode->name = "Native panel mode"; 2329 pMode->type = M_T_BUILTIN; 2330 pMode->Clock = pATI->LCDClock; 2331 pMode->HDisplay = pATI->LCDHorizontal; 2332 pMode->VDisplay = pATI->LCDVertical; 2333 2334 /* 2335 * These timings are bogus, but enough to survive sync tolerance 2336 * checks. 2337 */ 2338 pMode->HSyncStart = pMode->HDisplay; 2339 pMode->HSyncEnd = pMode->HSyncStart + minPitch; 2340 pMode->HTotal = pMode->HSyncEnd + minPitch; 2341 pMode->VSyncStart = pMode->VDisplay; 2342 pMode->VSyncEnd = pMode->VSyncStart + 1; 2343 pMode->VTotal = pMode->VSyncEnd + 1; 2344 2345 pMode->CrtcHDisplay = pMode->HDisplay; 2346 pMode->CrtcHBlankStart = pMode->HDisplay; 2347 pMode->CrtcHSyncStart = pMode->HSyncStart; 2348 pMode->CrtcHSyncEnd = pMode->HSyncEnd; 2349 pMode->CrtcHBlankEnd = pMode->HTotal; 2350 pMode->CrtcHTotal = pMode->HTotal; 2351 2352 pMode->CrtcVDisplay = pMode->VDisplay; 2353 pMode->CrtcVBlankStart = pMode->VDisplay; 2354 pMode->CrtcVSyncStart = pMode->VSyncStart; 2355 pMode->CrtcVSyncEnd = pMode->VSyncEnd; 2356 pMode->CrtcVBlankEnd = pMode->VTotal; 2357 pMode->CrtcVTotal = pMode->VTotal; 2358 2359 if (!pScreenInfo->monitor->Modes) 2360 { 2361 pScreenInfo->monitor->Modes = pMode; 2362 } 2363 else 2364 { 2365 pScreenInfo->monitor->Last->next = pMode; 2366 pMode->prev = pScreenInfo->monitor->Last; 2367 } 2368 2369 pScreenInfo->monitor->Last = pMode; 2370 } 2371 2372 /* 2373 * Defeat Xconfigurator brain damage. Ignore all HorizSync and 2374 * VertRefresh specifications. For now, this does not take 2375 * SYNC_TOLERANCE into account. 2376 */ 2377 if (pScreenInfo->monitor->nHsync > 0) 2378 { 2379 double hsync = (double)pATI->LCDClock / 2380 (pATI->LCDHorizontal + pATI->LCDHBlankWidth); 2381 2382 for (i = 0; ; i++) 2383 { 2384 if (i >= pScreenInfo->monitor->nHsync) 2385 { 2386 xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE, 2387 "Conflicting XF86Config HorizSync specification(s)" 2388 " ignored.\n"); 2389 break; 2390 } 2391 2392 if ((hsync >= pScreenInfo->monitor->hsync[i].lo) && 2393 (hsync <= pScreenInfo->monitor->hsync[i].hi)) 2394 { 2395 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 2396 "Extraneous XF86Config HorizSync specification(s)" 2397 " ignored.\n"); 2398 break; 2399 } 2400 } 2401 2402 pScreenInfo->monitor->nHsync = 0; 2403 } 2404 2405 if (pScreenInfo->monitor->nVrefresh > 0) 2406 { 2407 double vrefresh = ((double)pATI->LCDClock * 1000.0) / 2408 ((pATI->LCDHorizontal + pATI->LCDHBlankWidth) * 2409 (pATI->LCDVertical + pATI->LCDVBlankWidth)); 2410 2411 for (i = 0; ; i++) 2412 { 2413 if (i >= pScreenInfo->monitor->nVrefresh) 2414 { 2415 xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE, 2416 "Conflicting XF86Config VertRefresh specification(s)" 2417 " ignored.\n"); 2418 break; 2419 } 2420 2421 if ((vrefresh >= pScreenInfo->monitor->vrefresh[i].lo) && 2422 (vrefresh <= pScreenInfo->monitor->vrefresh[i].hi)) 2423 { 2424 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 2425 "Extraneous XF86Config VertRefresh specification(s)" 2426 " ignored.\n"); 2427 break; 2428 } 2429 } 2430 2431 pScreenInfo->monitor->nVrefresh = 0; 2432 } 2433 } 2434 2435 i = xf86ValidateModes(pScreenInfo, 2436 pScreenInfo->monitor->Modes, pScreenInfo->display->modes, 2437 &ATIClockRange, NULL, minPitch, maxPitch, 2438 pitchInc, 0, maxHeight, 2439 pScreenInfo->display->virtualX, pScreenInfo->display->virtualY, 2440 ApertureSize, Strategy); 2441 if (i <= 0) 2442 goto bail; 2443 2444 /* Remove invalid modes */ 2445 xf86PruneDriverModes(pScreenInfo); 2446 2447 /* Set current mode to the first in the list */ 2448 pScreenInfo->currentMode = pScreenInfo->modes; 2449 2450 /* Print mode list */ 2451 xf86PrintModes(pScreenInfo); 2452 2453 /* Set display resolution */ 2454 xf86SetDpi(pScreenInfo, 0, 0); 2455 2456 /* Load required modules */ 2457 if (!ATILoadModules(pScreenInfo, pATI)) 2458 goto bail; 2459 2460 pATI->displayWidth = pScreenInfo->displayWidth; 2461 2462 /* Initialise for panning */ 2463 ATIAdjustPreInit(pATI); 2464 2465 /* 2466 * Warn about modes that are too small, or not aligned, to scroll to the 2467 * bottom right corner of the virtual screen. 2468 */ 2469 MinX = pScreenInfo->virtualX - pATI->AdjustMaxX; 2470 MinY = pScreenInfo->virtualY - pATI->AdjustMaxY; 2471 2472 pMode = pScreenInfo->modes; 2473 do 2474 { 2475 if ((pMode->VDisplay <= MinY) && 2476 ((pMode->VDisplay < MinY) || (pMode->HDisplay < MinX))) 2477 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 2478 "Mode \"%s\" too small to scroll to bottom right corner of" 2479 " virtual resolution.\n", pMode->name); 2480 else if ((pMode->HDisplay & ~pATI->AdjustMask) / pScreenInfo->xInc) 2481 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 2482 "Mode \"%s\" cannot scroll to bottom right corner of virtual" 2483 " resolution.\n Horizontal dimension not a multiple of %ld.\n", 2484 pMode->name, ~pATI->AdjustMask + 1); 2485 } while ((pMode = pMode->next) != pScreenInfo->modes); 2486 2487 /* Initialise XVideo extension support */ 2488 ATIXVPreInit(pATI); 2489 2490 /* Initialise CRTC code */ 2491 ATIModePreInit(pScreenInfo, pATI, &pATI->NewHW); 2492 2493 /* Set up for I2C */ 2494 ATII2CPreInit(pScreenInfo, pATI); 2495 2496 if (!pScreenInfo->chipset || !*pScreenInfo->chipset) 2497 pScreenInfo->chipset = "mach64"; 2498 2499 PreInitSuccess = TRUE; 2500 2501bail: 2502 ATILock(pATI); 2503 2504bail_locked: 2505 ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize); 2506 ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); 2507 2508 return PreInitSuccess; 2509} 2510