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