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