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