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