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