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