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