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