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