xgi_driver.c revision b83cc2c0
1/*
2 * XGI driver main code
3 *
4 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1) Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2) Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3) The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Author: Thomas Winischhofer <thomas@winischhofer.net>
29 *	- driver entirely rewritten since 2001, only basic structure taken from
30 *	  old code (except xgi_dri.c, xgi_shadow.c, xgi_accel.c and parts of
31 *	  xgi_dga.c; these were mostly taken over; xgi_dri.c was changed for
32 *	  new versions of the DRI layer)
33 *
34 * This notice covers the entire driver code unless otherwise indicated.
35 *
36 * Formerly based on code which is
37 * 	     Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
38 * Written by:
39 *           Alan Hourihane <alanh@fairlite.demon.co.uk>,
40 *           Mike Chapman <mike@paranoia.com>,
41 *           Juanjo Santamarta <santamarta@ctv.es>,
42 *           Mitani Hiroshi <hmitani@drl.mei.co.jp>,
43 *           David Thomas <davtom@dream.org.uk>.
44 */
45
46#ifdef HAVE_CONFIG_H
47#include "config.h"
48#endif
49
50#define  PACKAGE_VERSION_MAJOR   1
51#define  PACKAGE_VERSION_MINOR   6
52#define  PACKAGE_VERSION_PATCHLEVEL   0
53
54#include "fb.h"
55#include "micmap.h"
56#include "xf86.h"
57#include "xf86Priv.h"
58#include "xf86_OSproc.h"
59#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
60#include "xf86Resources.h"
61#include "xf86RAC.h"
62#endif
63#include "dixstruct.h"
64#include "xorgVersion.h"
65#include "xf86PciInfo.h"
66#include "xf86Pci.h"
67#include "xf86cmap.h"
68#include "vgaHW.h"
69#include "shadowfb.h"
70#include "vbe.h"
71
72#include "mipointer.h"
73#include "mibstore.h"
74
75#include "xgi.h"
76#include "xgi_regs.h"
77#include "xgi_vb.h"
78#include "xgi_dac.h"
79#include "vb_def.h"
80#include "vb_ext.h"
81#include "vb_i2c.h"
82#include "vb_setmode.h"
83#include "xgi_driver.h"
84#include "xgi_accel.h"
85#include "valid_mode.h"
86
87#define _XF86DGA_SERVER_
88#include <X11/extensions/xf86dgaproto.h>
89
90#include "globals.h"
91
92#ifdef HAVE_XEXTPROTO_71
93#include <X11/extensions/dpmsconst.h>
94#else
95#define DPMS_SERVER
96#include <X11/extensions/dpms.h>
97#endif
98
99
100#if defined(XvExtension)
101#include "xf86xv.h"
102#include <X11/extensions/Xv.h>
103#endif
104
105#ifdef XF86DRI
106#include "dri.h"
107#endif
108
109#ifdef HAVE_UNISTD_H
110#include <unistd.h>
111#endif
112
113#include <fcntl.h>
114#include <sys/ioctl.h>
115
116#ifdef XSERVER_LIBPCIACCESS
117static Bool XGIPciProbe(DriverPtr drv, int entity_num,
118    struct pci_device *dev, intptr_t match_data);
119#else
120static Bool XGIProbe(DriverPtr drv, int flags);
121#endif
122
123void Volari_EnableAccelerator(ScrnInfoPtr pScrn);
124/* Globals (yes, these ARE really required to be global) */
125
126#ifdef XGIDUALHEAD
127static int XGIEntityIndex = -1;
128#endif
129
130/* Jong 09/19/2007; support modeline */
131int g_CountOfUserDefinedModes=0;
132xf86MonPtr  g_pMonitorDVI=NULL; /* Jong 12/04/2007; used for filtering of CRT1 modes */
133
134/* Jong 07/27/2009; use run-time debug instead except for HW acceleration routines */
135/* Set Option "RunTimeDebug" to "true" in X configuration file */
136Bool g_bRunTimeDebug=0;
137
138/* Jong@09072009 */
139unsigned char g_DVI_I_SignalType = 0x00;
140
141/*
142 * This is intentionally screen-independent.  It indicates the binding
143 * choice made in the first PreInit.
144 */
145static int pix24bpp = 0;
146int FbDevExist;
147
148#define FBIOGET_FSCREENINFO	0x4602
149#define FB_ACCEL_XGI_GLAMOUR	41
150
151struct fb_fix_screeninfo
152{
153    char id[16];                /* identification string eg "TT Builtin" */
154    unsigned long smem_start;   /* Start of frame buffer mem */
155    /* (physical address) */
156    unsigned long smem_len;     /* Length of frame buffer mem */
157    unsigned long type;         /* see FB_TYPE_*                */
158    unsigned long type_aux;     /* Interleave for interleaved Planes */
159    unsigned long visual;       /* see FB_VISUAL_*              */
160    unsigned short xpanstep;    /* zero if no hardware panning  */
161    unsigned short ypanstep;    /* zero if no hardware panning  */
162    unsigned short ywrapstep;   /* zero if no hardware ywrap    */
163    unsigned long line_length;  /* length of a line in bytes    */
164    unsigned long mmio_start;   /* Start of Memory Mapped I/O   */
165    /* (physical address) */
166    unsigned long mmio_len;     /* Length of Memory Mapped I/O  */
167    unsigned long accel;        /* Type of acceleration available */
168    unsigned short reserved[3]; /* Reserved for future compatibility */
169};
170
171#ifdef XSERVER_LIBPCIACCESS
172#define XGI_DEVICE_MATCH(d, i) \
173    { 0x18ca, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
174
175static const struct pci_id_match xgi_device_match[] = {
176    XGI_DEVICE_MATCH(PCI_CHIP_XGIXG40, 0),
177    XGI_DEVICE_MATCH(PCI_CHIP_XGIXG20, 1),
178    XGI_DEVICE_MATCH(PCI_CHIP_XGIXG21, 2),
179    XGI_DEVICE_MATCH(PCI_CHIP_XGIXG27, 3),
180    { 0, 0, 0 },
181};
182#endif
183
184/*
185 * This contains the functions needed by the server after loading the driver
186 * module.  It must be supplied, and gets passed back by the SetupProc
187 * function in the dynamic case.  In the static case, a reference to this
188 * is compiled in, and this requires that the name of this DriverRec be
189 * an upper-case version of the driver name.
190 */
191
192DriverRec XGI = {
193    XGI_CURRENT_VERSION,
194    XGI_DRIVER_NAME,
195    XGIIdentify,
196#ifdef XSERVER_LIBPCIACCESS
197    NULL,
198#else
199    XGIProbe,
200#endif
201    XGIAvailableOptions,
202    NULL,
203    0,
204    NULL,
205
206#ifdef XSERVER_LIBPCIACCESS
207    xgi_device_match,
208    XGIPciProbe
209#endif
210};
211
212static SymTabRec XGIChipsets[] = {
213    {PCI_CHIP_XGIXG40, "Volari V8_V5_V3XT"},
214    {PCI_CHIP_XGIXG20, "Volari Z7_Z9_Z9s"},
215    {PCI_CHIP_XGIXG21, "Volari Z9_Z9s"},
216    {PCI_CHIP_XGIXG27, "Volari Z11"},
217    {-1, NULL}
218};
219
220static PciChipsets XGIPciChipsets[] = {
221    {PCI_CHIP_XGIXG40, PCI_CHIP_XGIXG40, RES_SHARED_VGA},
222    {PCI_CHIP_XGIXG20, PCI_CHIP_XGIXG20, RES_SHARED_VGA},
223    {PCI_CHIP_XGIXG21, PCI_CHIP_XGIXG21, RES_SHARED_VGA },
224    {PCI_CHIP_XGIXG27, PCI_CHIP_XGIXG27, RES_SHARED_VGA },
225    {-1, -1, RES_UNDEFINED}
226};
227
228static const char *xaaSymbols[] = {
229    "XAACopyROP",
230    "XAACreateInfoRec",
231    "XAADestroyInfoRec",
232    "XAAFillMono8x8PatternRects",
233    "XAAPatternROP",
234    "XAAHelpPatternROP",
235    "XAAInit",
236    NULL
237};
238
239#ifdef XGI_USE_EXA
240static const char *exaSymbols[] = {
241    "exaGetVersion",
242    "exaDriverInit",
243    "exaDriverFini",
244    "exaOffscreenAlloc",
245    "exaOffscreenFree",
246    NULL
247};
248#endif
249
250static const char *vgahwSymbols[] = {
251    "vgaHWFreeHWRec",
252    "vgaHWGetHWRec",
253    "vgaHWGetIOBase",
254    "vgaHWGetIndex",
255    "vgaHWInit",
256    "vgaHWLock",
257    "vgaHWMapMem",
258    "vgaHWUnmapMem",
259    "vgaHWProtect",
260    "vgaHWRestore",
261    "vgaHWSave",
262    "vgaHWSaveScreen",
263    "vgaHWUnlock",
264    NULL
265};
266
267static const char *fbSymbols[] = {
268    "fbPictureInit",
269    "fbScreenInit",
270    NULL
271};
272
273static const char *shadowSymbols[] = {
274    "ShadowFBInit",
275    NULL
276};
277
278static const char *ramdacSymbols[] = {
279    "xf86CreateCursorInfoRec",
280    "xf86DestroyCursorInfoRec",
281    "xf86InitCursor",
282    NULL
283};
284
285
286static const char *ddcSymbols[] = {
287    "xf86PrintEDID",
288    "xf86SetDDCproperties",
289    "xf86InterpretEDID",
290    NULL
291};
292
293
294/* static const char *i2cSymbols[] = {
295    "xf86I2CBusInit",
296    "xf86CreateI2CBusRec",
297    NULL
298}; */
299
300static const char *int10Symbols[] = {
301    "xf86FreeInt10",
302    "xf86InitInt10",
303    "xf86ExecX86int10",
304    NULL
305};
306
307static const char *vbeSymbols[] = {
308    "VBEExtendedInit",
309    "vbeDoEDID",
310    "vbeFree",
311    "VBEGetVBEInfo",
312    "VBEFreeVBEInfo",
313    "VBEGetModeInfo",
314    "VBEFreeModeInfo",
315    "VBESaveRestore",
316    "VBESetVBEMode",
317    "VBEGetVBEMode",
318    "VBESetDisplayStart",
319    "VBESetGetLogicalScanlineLength",
320    NULL
321};
322
323#ifdef XF86DRI
324static const char *drmSymbols[] = {
325    "drmAddMap",
326    "drmAgpAcquire",
327    "drmAgpAlloc",
328    "drmAgpBase",
329    "drmAgpBind",
330    "drmAgpEnable",
331    "drmAgpFree",
332    "drmAgpGetMode",
333    "drmAgpRelease",
334    "drmCtlInstHandler",
335    "drmGetInterruptFromBusID",
336    "drmXGIAgpInit",
337    NULL
338};
339
340static const char *driSymbols[] = {
341    "DRICloseScreen",
342    "DRICreateInfoRec",
343    "DRIDestroyInfoRec",
344    "DRIFinishScreenInit",
345    "DRIGetSAREAPrivate",
346    "DRILock",
347    "DRIQueryVersion",
348    "DRIScreenInit",
349    "DRIUnlock",
350#ifdef XGINEWDRI2
351    "GlxSetVisualConfigs",
352    "DRICreatePCIBusID",
353#endif
354    NULL
355};
356#endif
357
358static MODULESETUPPROTO(xgiSetup);
359
360static XF86ModuleVersionInfo xgiVersRec = {
361    XGI_DRIVER_NAME,
362    MODULEVENDORSTRING,
363    MODINFOSTRING1,
364    MODINFOSTRING2,
365#ifdef XORG_VERSION_CURRENT
366    XORG_VERSION_CURRENT,
367#else
368    XF86_VERSION_CURRENT,
369#endif
370    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
371    ABI_CLASS_VIDEODRV,         /* This is a video driver */
372#ifdef ABI_VIDEODRV_VERSION
373    ABI_VIDEODRV_VERSION,
374#else
375    6,
376#endif
377    MOD_CLASS_VIDEODRV,
378    {0, 0, 0, 0}
379};
380
381XF86ModuleData xgiModuleData = { &xgiVersRec, xgiSetup, NULL };
382
383/*** static string ***/
384#ifdef XGIMERGED
385static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n";
386static const char *mergednocrt2 =
387    "No CRT2 output selected or no bridge detected. %s.\n";
388static const char *mergeddisstr = "MergedFB mode disabled";
389static const char *modesforstr =
390    "Modes for CRT%d: *********************************************\n";
391static const char *crtsetupstr =
392    "------------------------ CRT%d setup -------------------------\n";
393#endif
394
395typedef struct
396{
397    int width, height;
398    float VRefresh, HSync, DCLK;
399} ModeTiming;
400
401static const ModeTiming establish_timing[] = {
402    {800, 600, 60, 37.9, 40},   /* t1 D[0] */
403    {800, 600, 56, 35.1, 36},   /* t1 D[1] */
404    {640, 480, 75, 37.5, 31.5}, /* t1 D[2] */
405    {640, 480, 72, 37.9, 31.5}, /* t1 D[3] */
406    {-1, -1, -1, -1},           /* t1 D[4] 640x480@67Hz, ignore */
407    {640, 480, 60, 31.5, 25.175},       /* t1 D[5] */
408    {-1, -1, -1, -1},           /* t1 D[6] */
409    {-1, -1, -1, -1},           /* t1 D[7] */
410    {1280, 1024, 75, 80.0, 135},        /* t2 D[0] */
411    {1024, 768, 75, 60.0, 78.75},       /* t2 D[1] */
412    {1024, 768, 70, 56.5, 75},  /* t2 D[2] */
413    {1024, 768, 60, 48.4, 65},  /* t2 D[3] */
414    {-1, -1, -1, -1},           /* t2 D[4] 1024x768@87I, ignore */
415    {-1, -1, -1, -1},           /* t2 D[5] 832x624@75Hz, ignore */
416    {800, 600, 75, 46.9, 49.5}, /* t2 D[6] */
417    {800, 600, 72, 48.1, 50}    /* t2 D[7] */
418};
419
420static const ModeTiming StdTiming[] = {
421    {640, 480, 60, 31.5, 25.175},
422    {640, 480, 72, 37.9, 31.5},
423    {640, 480, 75, 37.5, 31.5},
424    {640, 480, 85, 43.3, 36.0},
425
426    {800, 600, 56, 35.1, 36},
427    {800, 600, 60, 37.9, 40},
428    {800, 600, 72, 48.1, 50},
429    {800, 600, 75, 46.9, 49.5},
430    {800, 600, 85, 53.7, 56.25},
431
432    {1024, 768, 43, 35.5, 44.9},
433    {1024, 768, 60, 48.4, 65},
434    {1024, 768, 70, 56.5, 75},
435    {1024, 768, 75, 60, 78.75},
436    {1024, 768, 85, 68.7, 94.5},
437
438    {1152, 864, 75, 67.5, 108},
439
440    {1280, 960, 60, 60, 108},
441    {1280, 960, 85, 85.9, 148.5},
442    {1280, 1024, 60, 64.0, 108},
443    {1280, 1024, 75, 80, 135},
444    {1280, 1024, 85, 91.1, 157.5},
445
446    {1600, 1200, 60, 75, 162.0},
447    {1600, 1200, 65, 81.3, 175.5},
448    {1600, 1200, 70, 87.5, 189},
449    {1600, 1200, 75, 93.8, 202},
450    {1600, 1200, 85, 106.3, 229.5},
451
452    {1792, 1344, 60, 83.64, 204.75},
453    {1792, 1344, 75, 106.27, 261},
454
455    {1856, 1392, 60, 86.33, 218.25},
456    {1856, 1392, 75, 112.50, 288},
457
458    {1920, 1440, 60, 90, 234},
459    {1920, 1440, 75, 112.5, 297},
460    {-1, -1, -1, -1, -1},
461};
462
463
464static void XGIDumpPalette(ScrnInfoPtr pScrn);
465#ifdef DEBUG
466void XGIDumpSR(ScrnInfoPtr pScrn);
467void XGIDumpCR(ScrnInfoPtr pScrn);
468static void XGIDumpGR(ScrnInfoPtr pScrn);
469static void XGIDumpPart1(ScrnInfoPtr pScrn);
470static void XGIDumpPart2(ScrnInfoPtr pScrn);
471static void XGIDumpPart3(ScrnInfoPtr pScrn);
472static void XGIDumpPart4(ScrnInfoPtr pScrn);
473static void XGIDumpMMIO(ScrnInfoPtr pScrn);
474#endif
475
476static int XGICalcVRate(DisplayModePtr mode);
477static unsigned char XGISearchCRT1Rate(ScrnInfoPtr pScrn,
478                                       DisplayModePtr mode);
479static void xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
480                                         unsigned char *reg2);
481static void xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1,
482                                      unsigned char reg2);
483
484/* Jong 12/05/2007; check mode with monitor DDC */
485static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC);
486
487/* Jong 12/05/2007; filter mode list by monitor DDC */
488static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC);
489
490static pointer
491xgiSetup(pointer module, pointer opts, int *errmaj, int *errmin)
492{
493    static Bool setupDone = FALSE;
494
495    if (!setupDone) {
496        setupDone = TRUE;
497/* Jong@09022009 */
498#if (XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(6,9,0,0,0) )
499        xf86AddDriver(&XGI, module, HaveDriverFuncs);
500#else
501        xf86AddDriver(&XGI, module, 0);
502#endif
503
504#if 0
505        LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
506                          shadowSymbols, ramdacSymbols, ddcSymbols,
507                          vbeSymbols, int10Symbols,
508#ifdef XF86DRI
509                          drmSymbols, driSymbols,
510#endif
511                          NULL);
512#endif
513        return (pointer) TRUE;
514    }
515
516    if (errmaj)
517        *errmaj = LDR_ONCEONLY;
518    return NULL;
519}
520
521
522static XGIPtr
523XGIGetRec(ScrnInfoPtr pScrn)
524{
525    /*
526     * Allocate an XGIRec, and hook it into pScrn->driverPrivate.
527     * pScrn->driverPrivate is initialised to NULL, so we can check if
528     * the allocation has already been done.
529     */
530    if (pScrn->driverPrivate == NULL) {
531        XGIPtr pXGI = xnfcalloc(sizeof(XGIRec), 1);
532
533        /* Initialise it to 0 */
534        memset(pXGI, 0, sizeof(XGIRec));
535
536        pScrn->driverPrivate = pXGI;
537        pXGI->pScrn = pScrn;
538    }
539
540    return (XGIPtr) pScrn->driverPrivate;
541}
542
543static void
544XGIFreeRec(ScrnInfoPtr pScrn)
545{
546    XGIPtr pXGI = XGIPTR(pScrn);
547    XGIEntPtr pXGIEnt = NULL;
548
549    /* Just to make sure... */
550    if (!pXGI)
551        return;
552
553    pXGIEnt = ENTITY_PRIVATE(pXGI);
554    if (pXGIEnt) {
555        if (!IS_SECOND_HEAD(pXGI)) {
556            /* Free memory only if we are first head; in case of an error
557             * during init of the second head, the server will continue -
558             * and we need the BIOS image and VB_DEVICE_INFO for the first
559             * head.
560             */
561            if (pXGIEnt->BIOS)
562                xfree(pXGIEnt->BIOS);
563            pXGIEnt->BIOS = pXGI->BIOS = NULL;
564            if (pXGIEnt->XGI_Pr)
565                xfree(pXGIEnt->XGI_Pr);
566            pXGIEnt->XGI_Pr = pXGI->XGI_Pr = NULL;
567            if (pXGIEnt->RenderAccelArray)
568                xfree(pXGIEnt->RenderAccelArray);
569            pXGIEnt->RenderAccelArray = pXGI->RenderAccelArray = NULL;
570        }
571        else {
572            pXGI->BIOS = NULL;
573            pXGI->XGI_Pr = NULL;
574            pXGI->RenderAccelArray = NULL;
575        }
576    }
577    else {
578        if (pXGI->BIOS)
579            xfree(pXGI->BIOS);
580        pXGI->BIOS = NULL;
581        if (pXGI->XGI_Pr)
582            xfree(pXGI->XGI_Pr);
583        pXGI->XGI_Pr = NULL;
584        if (pXGI->RenderAccelArray)
585            xfree(pXGI->RenderAccelArray);
586        pXGI->RenderAccelArray = NULL;
587    }
588
589#ifdef XGIMERGED
590    if (pXGI->MetaModes)
591        xfree(pXGI->MetaModes);
592    pXGI->MetaModes = NULL;
593
594    if (pXGI->CRT1Modes) {
595        if (pXGI->CRT1Modes != pScrn->modes) {
596            if (pScrn->modes) {
597                pScrn->currentMode = pScrn->modes;
598                do {
599                    DisplayModePtr p = pScrn->currentMode->next;
600                    if (pScrn->currentMode->Private)
601                        xfree(pScrn->currentMode->Private);
602                    xfree(pScrn->currentMode);
603                    pScrn->currentMode = p;
604                } while (pScrn->currentMode != pScrn->modes);
605            }
606            pScrn->currentMode = pXGI->CRT1CurrentMode;
607            pScrn->modes = pXGI->CRT1Modes;
608            pXGI->CRT1CurrentMode = NULL;
609            pXGI->CRT1Modes = NULL;
610        }
611    }
612#endif
613    if (pXGI->pVbe)
614        vbeFree(pXGI->pVbe);
615    pXGI->pVbe = NULL;
616    if (pScrn->driverPrivate == NULL)
617        return;
618    xfree(pScrn->driverPrivate);
619    pScrn->driverPrivate = NULL;
620}
621
622/*
623	SR1F Power management register
624	D7	Force CRT1 into DPMS suspend mode
625		0: disable
626		1: enable
627	D6	Force CRT1 into DPMS stand-by mode
628		0: disable
629		1: enable
630*/
631static void
632XGIDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
633                             int flags)
634{
635    XGIPtr pXGI = XGIPTR(pScrn);
636    BOOLEAN docrt1 = TRUE, docrt2 = TRUE;
637    unsigned char sr1 = 0, cr17 = 0, cr63 = 0, sr11 = 0, pmreg = 0, sr7 = 0;
638    unsigned char p1_13 = 0, p2_0 = 0, oldpmreg = 0;
639    BOOLEAN backlight = TRUE;
640
641    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
642                   "XGIDisplayPowerManagementSet(%d)\n", PowerManagementMode);
643
644#if 1
645	PVB_DEVICE_INFO pVBInfo = pXGI->XGI_Pr;
646    PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt;
647	ULONG  PowerState = 0xFFFFFFFF;
648
649	if((PowerManagementMode != 0) && (PowerManagementMode <= 3))
650		PowerState = 0x00000001 << (PowerManagementMode + 7);
651	else
652		PowerState = 0x0;
653
654	XGISetDPMS(pScrn, pVBInfo, pHwDevInfo, PowerState);
655#else
656    if (IS_DUAL_HEAD(pXGI)) {
657        if (IS_SECOND_HEAD(pXGI))
658            docrt2 = FALSE;
659        else
660            docrt1 = FALSE;
661    }
662
663#ifdef UNLOCK_ALWAYS
664    xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
665#endif
666
667    switch (PowerManagementMode) {
668
669    case DPMSModeOn:           /* HSync: On, VSync: On */
670		PDEBUG(ErrorF("!-DPMSMode-On...\n"));
671
672        if (docrt1)
673            pXGI->Blank = FALSE;
674
675        sr1 = 0x00;
676        cr17 = 0x80;
677        pmreg = 0x00;
678        cr63 = 0x00;
679        sr7 = 0x10;
680        sr11 = (pXGI->LCDon & 0x0C);
681        p2_0 = 0x20;
682        p1_13 = 0x00;
683        backlight = TRUE;
684        break;
685
686    case DPMSModeSuspend:      /* HSync: On, VSync: Off */
687		PDEBUG(ErrorF("!-DPMSMode-Suspend...\n"));
688
689        if (docrt1)
690            pXGI->Blank = TRUE;
691
692        sr1 = 0x20;
693        cr17 = 0x80;
694        pmreg = 0x80;
695        cr63 = 0x40;
696        sr7 = 0x00;
697        sr11 = 0x08;
698        p2_0 = 0x40;
699        p1_13 = 0x80;
700        backlight = FALSE;
701        break;
702
703    case DPMSModeStandby:      /* HSync: Off, VSync: On */
704		PDEBUG(ErrorF("!-DPMSMode-Standby...\n"));
705
706        if (docrt1)
707            pXGI->Blank = TRUE;
708
709        sr1 = 0x20;
710        cr17 = 0x80;
711        pmreg = 0x40;
712        cr63 = 0x40;
713        sr7 = 0x00;
714        sr11 = 0x08;
715        p2_0 = 0x80;
716        p1_13 = 0x40;
717        backlight = FALSE;
718        break;
719
720    case DPMSModeOff:          /* HSync: Off, VSync: Off */
721		PDEBUG(ErrorF("!-DPMSMode-Off...\n"));
722
723        if (docrt1)
724            pXGI->Blank = TRUE;
725
726        sr1 = 0x20;
727        cr17 = 0x00;
728        pmreg = 0xc0;
729        cr63 = 0x40;
730        sr7 = 0x00;
731        sr11 = 0x08;
732        p2_0 = 0xc0;
733        p1_13 = 0xc0;
734        backlight = FALSE;
735        break;
736
737    default:
738        return;
739    }
740
741    if (docrt1) {
742        /* Set/Clear "Display On" bit
743         */
744        setXGIIDXREG(XGISR, 0x01, ~0x20, sr1);
745
746        if ((!(pXGI->VBFlags & CRT1_LCDA))
747            || (pXGI->XGI_Pr->VBType & VB_XGI301C)) {
748            inXGIIDXREG(XGISR, 0x1f, oldpmreg);
749            if (!pXGI->CRT1off) {
750                setXGIIDXREG(XGISR, 0x1f, 0x3f, pmreg);
751            }
752        }
753        oldpmreg &= 0xc0;
754    }
755
756    if ((docrt1) && (pmreg != oldpmreg)
757        && ((!(pXGI->VBFlags & CRT1_LCDA))
758            || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
759        outXGIIDXREG(XGISR, 0x00, 0x01);        /* Synchronous Reset */
760        usleep(10000);
761        outXGIIDXREG(XGISR, 0x00, 0x03);        /* End Reset */
762    }
763#endif
764}
765
766typedef struct
767{
768    char   name[10];
769    unsigned int    DCLK;
770    unsigned int    HDisplay;
771    unsigned int    HSyncStart;
772    unsigned int    HSyncEnd;
773    unsigned int    HTotal;
774    unsigned int    VDisplay;
775    unsigned int    VSyncStart;
776    unsigned int    VSyncEnd;
777    unsigned int    VTotal;
778} XGITimingInfo;
779
780XGITimingInfo ExtraAvailableModeTiming[]=
781{
782  {"1440x900",
783   106470,
784   1440, 1520, 1672, 1904,
785   900, 901, 904, 932},
786  {"1680x1050",
787   146250,
788   1680, 1784, 1960, 2240,
789   1050, 1053, 1059, 1089},
790  {"0x0",
791   106470,
792   1440, 1520, 1672, 1904,
793   900, 901, 904, 932}
794};
795
796int	  ExtraAvailableModeTimingCount = 1;
797
798void XGIAddAvailableModes(DisplayModePtr availModes)
799{
800	DisplayModePtr p;
801	DisplayModePtr q;
802	DisplayModePtr last;
803	DisplayModePtr first;
804	int	i;
805
806	/* Scan to last node */
807	for (q = availModes; q != NULL; q = q->next){
808		last = q;
809	}
810
811	/* first = availModes->next; */
812
813	/* Add all modes of ExtraAvailableModeTiming[] */
814	for(i=0; /* i < ExtraAvailableModeTimingCount */ xf86NameCmp(ExtraAvailableModeTiming[i].name, "0x0") != 0 ; i++)
815	{
816		p = xnfcalloc(1, sizeof(DisplayModeRec));
817
818		p->prev = last;
819		p->next = NULL;
820		last->next = p;
821
822		/*
823		first->next->prev = p;
824		p->prev = first;
825		p->next = first->next;
826		first->next = p;
827		*/
828
829		p->name = xnfalloc(strlen(ExtraAvailableModeTiming[i].name) + 1);
830		p->name = ExtraAvailableModeTiming[i].name;
831		p->status = MODE_OK;
832
833		p->type = M_T_CLOCK_CRTC_C /* M_T_BUILTIN */ 	/* M_T_USERDEF */ ;
834
835		p->Clock = ExtraAvailableModeTiming[i].DCLK;
836		p->HDisplay = ExtraAvailableModeTiming[i].HDisplay;
837		p->HSyncStart = ExtraAvailableModeTiming[i].HSyncStart;
838		p->HSyncEnd = ExtraAvailableModeTiming[i].HSyncEnd;
839		p->HTotal = ExtraAvailableModeTiming[i].HTotal;
840
841		p->VDisplay = ExtraAvailableModeTiming[i].VDisplay;
842		p->VSyncStart = ExtraAvailableModeTiming[i].VSyncStart;
843		p->VSyncEnd = ExtraAvailableModeTiming[i].VSyncEnd;
844		p->VTotal = ExtraAvailableModeTiming[i].VTotal;
845
846		p->Flags = 5;
847
848		last = p;
849	}
850}
851
852/* Mandatory */
853static void
854XGIIdentify(int flags)
855{
856    xf86PrintChipsets(XGI_NAME, "driver for XGI chipsets", XGIChipsets);
857    PDEBUG(ErrorF(" --- XGIIdentify \n"));
858}
859
860static void
861XGIErrorLog(ScrnInfoPtr pScrn, const char *format, ...)
862{
863    va_list ap;
864    static const char *str =
865        "**************************************************\n";
866
867    va_start(ap, format);
868    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s", str);
869    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "                      ERROR:\n");
870    xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap);
871    va_end(ap);
872    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
873               "                  END OF MESSAGE\n");
874    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s", str);
875}
876
877#ifdef XSERVER_LIBPCIACCESS
878static Bool XGIPciProbe(DriverPtr drv, int entity_num,
879                        struct pci_device *dev, intptr_t match_data)
880{
881    ScrnInfoPtr pScrn;
882
883
884    pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL,
885                                NULL, NULL, NULL, NULL, NULL);
886    if (pScrn != NULL) {
887        XGIPtr pXGI;
888
889        /* Fill in what we can of the ScrnInfoRec */
890        pScrn->driverVersion = XGI_CURRENT_VERSION;
891        pScrn->driverName = XGI_DRIVER_NAME;
892        pScrn->name = XGI_NAME;
893        pScrn->Probe = NULL;
894        pScrn->PreInit = XGIPreInit;
895        pScrn->ScreenInit = XGIScreenInit;
896        pScrn->SwitchMode = XGISwitchMode;
897        pScrn->AdjustFrame = XGIAdjustFrame;
898        pScrn->EnterVT = XGIEnterVT;
899        pScrn->LeaveVT = XGILeaveVT;
900        pScrn->FreeScreen = XGIFreeScreen;
901        pScrn->ValidMode = XGIValidMode;
902
903
904        pXGI = XGIGetRec(pScrn);
905        if (pXGI == NULL) {
906            return FALSE;
907        }
908
909        pXGI->PciInfo = dev;
910    }
911
912    return (pScrn != NULL);
913}
914
915#else
916
917/* Mandatory */
918static Bool
919XGIProbe(DriverPtr drv, int flags)
920{
921    int i;
922    GDevPtr *devSections;
923    int *usedChips;
924    int numDevSections;
925    int numUsed;
926    Bool foundScreen = FALSE;
927
928    /*
929     * The aim here is to find all cards that this driver can handle,
930     * and for the ones not already claimed by another driver, claim the
931     * slot, and allocate a ScrnInfoRec.
932     *
933     * This should be a minimal probe, and it should under no circumstances
934     * change the state of the hardware.  Because a device is found, don't
935     * assume that it will be used.  Don't do any initialisations other than
936     * the required ScrnInfoRec initialisations.  Don't allocate any new
937     * data structures.
938     *
939     */
940
941    /*
942     * Next we check, if there has been a chipset override in the config file.
943     * For this we must find out if there is an active device section which
944     * is relevant, i.e., which has no driver specified or has THIS driver
945     * specified.
946     */
947
948    if ((numDevSections =
949         xf86MatchDevice(XGI_DRIVER_NAME, &devSections)) <= 0) {
950        /*
951         * There's no matching device section in the config file, so quit
952         * now.
953         */
954        return FALSE;
955    }
956
957    PDEBUG(ErrorF(" --- XGIProbe \n"));
958    /*
959     * We need to probe the hardware first.  We then need to see how this
960     * fits in with what is given in the config file, and allow the config
961     * file info to override any contradictions.
962     */
963
964    /*
965     * All of the cards this driver supports are PCI, so the "probing" just
966     * amounts to checking the PCI data that the server has already collected.
967     */
968    if (xf86GetPciVideoInfo() == NULL) {
969        /*
970         * We won't let anything in the config file override finding no
971         * PCI video cards at all.  This seems reasonable now, but we'll see.
972         */
973        return FALSE;
974    }
975
976    numUsed = xf86MatchPciInstances(XGI_NAME, PCI_VENDOR_XGI,
977                                    XGIChipsets, XGIPciChipsets, devSections,
978                                    numDevSections, drv, &usedChips);
979
980    /* Free it since we don't need that list after this */
981    xfree(devSections);
982    if (numUsed <= 0)
983        return FALSE;
984
985    if (flags & PROBE_DETECT) {
986        foundScreen = TRUE;
987    }
988    else
989        for (i = 0; i < numUsed; i++) {
990            ScrnInfoPtr pScrn;
991#ifdef XGIDUALHEAD
992            EntityInfoPtr pEnt;
993#endif
994
995            /* Allocate a ScrnInfoRec and claim the slot */
996            pScrn = NULL;
997
998            if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
999                                             XGIPciChipsets, NULL, NULL,
1000                                             NULL, NULL, NULL))) {
1001                /* Fill in what we can of the ScrnInfoRec */
1002                pScrn->driverVersion = XGI_CURRENT_VERSION;
1003                pScrn->driverName = XGI_DRIVER_NAME;
1004                pScrn->name = XGI_NAME;
1005                pScrn->Probe = XGIProbe;
1006                pScrn->PreInit = XGIPreInit;
1007                pScrn->ScreenInit = XGIScreenInit;
1008                pScrn->SwitchMode = XGISwitchMode;
1009                pScrn->AdjustFrame = XGIAdjustFrame;
1010                pScrn->EnterVT = XGIEnterVT;
1011                pScrn->LeaveVT = XGILeaveVT;
1012                pScrn->FreeScreen = XGIFreeScreen;
1013                pScrn->ValidMode = XGIValidMode;
1014                foundScreen = TRUE;
1015            }
1016#ifdef XGIDUALHEAD
1017            pEnt = xf86GetEntityInfo(usedChips[i]);
1018
1019#endif
1020        }
1021    xfree(usedChips);
1022
1023    return foundScreen;
1024}
1025#endif
1026
1027
1028/* Some helper functions for MergedFB mode */
1029
1030#ifdef XGIMERGED
1031
1032/* Copy and link two modes form mergedfb mode
1033 * (Code base taken from mga driver)
1034 * Copys mode i, links the result to dest, and returns it.
1035 * Links i and j in Private record.
1036 * If dest is NULL, return value is copy of i linked to itself.
1037 * For mergedfb auto-config, we only check the dimension
1038 * against virtualX/Y, if they were user-provided.
1039 */
1040static DisplayModePtr
1041XGICopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
1042                 DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
1043{
1044    XGIPtr pXGI = XGIPTR(pScrn);
1045    DisplayModePtr mode;
1046    int dx = 0, dy = 0;
1047
1048	ErrorF("XGICopyModeNLink()...Use Virtual Size-1\n");
1049
1050    if (!((mode = xalloc(sizeof(DisplayModeRec)))))
1051        return dest;
1052    memcpy(mode, i, sizeof(DisplayModeRec));
1053    if (!((mode->Private = xalloc(sizeof(XGIMergedDisplayModeRec))))) {
1054        xfree(mode);
1055        return dest;
1056    }
1057    ((XGIMergedDisplayModePtr) mode->Private)->CRT1 = i;
1058    ((XGIMergedDisplayModePtr) mode->Private)->CRT2 = j;
1059    ((XGIMergedDisplayModePtr) mode->Private)->CRT2Position = srel;
1060    mode->PrivSize = 0;
1061
1062    switch (srel) {
1063    case xgiLeftOf:
1064    case xgiRightOf:
1065        if (!(pScrn->display->virtualX)) {
1066            dx = i->HDisplay + j->HDisplay;
1067        }
1068        else {
1069            dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
1070        }
1071        dx -= mode->HDisplay;
1072        if (!(pScrn->display->virtualY)) {
1073            dy = max(i->VDisplay, j->VDisplay);
1074        }
1075        else {
1076            dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
1077        }
1078        dy -= mode->VDisplay;
1079        break;
1080    case xgiAbove:
1081    case xgiBelow:
1082        if (!(pScrn->display->virtualY)) {
1083            dy = i->VDisplay + j->VDisplay;
1084        }
1085        else {
1086            dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
1087        }
1088        dy -= mode->VDisplay;
1089        if (!(pScrn->display->virtualX)) {
1090            dx = max(i->HDisplay, j->HDisplay);
1091        }
1092        else {
1093            dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
1094        }
1095        dx -= mode->HDisplay;
1096        break;
1097    case xgiClone:
1098        if (!(pScrn->display->virtualX)) {
1099            dx = max(i->HDisplay, j->HDisplay);
1100        }
1101        else {
1102            dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
1103        }
1104        dx -= mode->HDisplay;
1105        if (!(pScrn->display->virtualY)) {
1106            dy = max(i->VDisplay, j->VDisplay);
1107        }
1108        else {
1109            dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
1110        }
1111        dy -= mode->VDisplay;
1112        break;
1113    }
1114    mode->HDisplay += dx;
1115    mode->HSyncStart += dx;
1116    mode->HSyncEnd += dx;
1117    mode->HTotal += dx;
1118    mode->VDisplay += dy;
1119    mode->VSyncStart += dy;
1120    mode->VSyncEnd += dy;
1121    mode->VTotal += dy;
1122    mode->Clock = 0;
1123
1124    if (((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) >
1125         pXGI->maxxfbmem) || (mode->HDisplay > 4088)
1126        || (mode->VDisplay > 4096)) {
1127
1128        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1129                   "Skipped %dx%d, not enough video RAM or beyond hardware specs\n",
1130                   mode->HDisplay, mode->VDisplay);
1131        xfree(mode->Private);
1132        xfree(mode);
1133
1134        return dest;
1135    }
1136
1137#ifdef XGIXINERAMA
1138    if (srel != xgiClone) {
1139        pXGI->AtLeastOneNonClone = TRUE;
1140    }
1141#endif
1142
1143    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1144               "Merged %dx%d and %dx%d to %dx%d%s\n",
1145               i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay,
1146               mode->HDisplay, mode->VDisplay,
1147               (srel == xgiClone) ? " (Clone)" : "");
1148
1149    mode->next = mode;
1150    mode->prev = mode;
1151
1152    if (dest) {
1153        mode->next = dest->next;        /* Insert node after "dest" */
1154        dest->next->prev = mode;
1155        mode->prev = dest;
1156        dest->next = mode;
1157    }
1158
1159    return mode;
1160}
1161
1162/* Helper function to find a mode from a given name
1163 * (Code base taken from mga driver)
1164 */
1165static DisplayModePtr
1166XGIGetModeFromName(char *str, DisplayModePtr i)
1167{
1168    DisplayModePtr c = i;
1169    if (!i)
1170        return NULL;
1171    do {
1172        if (strcmp(str, c->name) == 0)
1173            return c;
1174        c = c->next;
1175    } while (c != i);
1176    return NULL;
1177}
1178
1179static DisplayModePtr
1180XGIFindWidestTallestMode(DisplayModePtr i, Bool tallest)
1181{
1182    DisplayModePtr c = i, d = NULL;
1183    int max = 0;
1184    if (!i)
1185        return NULL;
1186    do {
1187        if (tallest) {
1188            if (c->VDisplay > max) {
1189                max = c->VDisplay;
1190                d = c;
1191            }
1192        }
1193        else {
1194            if (c->HDisplay > max) {
1195                max = c->HDisplay;
1196                d = c;
1197            }
1198        }
1199        c = c->next;
1200    } while (c != i);
1201    return d;
1202}
1203
1204static DisplayModePtr
1205XGIGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
1206                                    DisplayModePtr i, DisplayModePtr j,
1207                                    XGIScrn2Rel srel)
1208{
1209#ifdef XGIXINERAMA
1210    XGIPtr pXGI = XGIPTR(pScrn);
1211#endif
1212    DisplayModePtr mode1 = NULL;
1213    DisplayModePtr mode2 = NULL;
1214    DisplayModePtr result = NULL;
1215
1216#ifdef XGIXINERAMA
1217    pXGI->AtLeastOneNonClone = FALSE;
1218#endif
1219
1220    switch (srel) {
1221    case xgiLeftOf:
1222    case xgiRightOf:
1223        mode1 = XGIFindWidestTallestMode(i, FALSE);
1224        mode2 = XGIFindWidestTallestMode(j, FALSE);
1225        break;
1226    case xgiAbove:
1227    case xgiBelow:
1228        mode1 = XGIFindWidestTallestMode(i, TRUE);
1229        mode2 = XGIFindWidestTallestMode(j, TRUE);
1230        break;
1231    case xgiClone:
1232        mode1 = i;
1233        mode2 = j;
1234    }
1235
1236    if (mode1 && mode2) {
1237        return (XGICopyModeNLink(pScrn, result, mode1, mode2, srel));
1238    }
1239    else {
1240        return NULL;
1241    }
1242}
1243
1244/* Generate the merged-fb mode modelist from metamodes
1245 * (Code base taken from mga driver)
1246 */
1247static DisplayModePtr
1248XGIGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char *str,
1249                                 DisplayModePtr i, DisplayModePtr j,
1250                                 XGIScrn2Rel srel)
1251{
1252#ifdef XGIXINERAMA
1253    XGIPtr pXGI = XGIPTR(pScrn);
1254#endif
1255    char *strmode = str;
1256    char modename[256];
1257    Bool gotdash = FALSE;
1258    XGIScrn2Rel sr;
1259    DisplayModePtr mode1 = NULL;
1260    DisplayModePtr mode2 = NULL;
1261    DisplayModePtr result = NULL;
1262
1263#ifdef XGIXINERAMA
1264    pXGI->AtLeastOneNonClone = FALSE;
1265#endif
1266
1267    do {
1268        switch (*str) {
1269        case 0:
1270        case '-':
1271        case ' ':
1272            if ((strmode != str)) {
1273
1274                strncpy(modename, strmode, str - strmode);
1275                modename[str - strmode] = 0;
1276
1277                if (gotdash) {
1278                    if (mode1 == NULL)
1279                        return NULL;
1280                    mode2 = XGIGetModeFromName(modename, j);
1281                    if (!mode2) {
1282                        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1283                                   "Mode \"%s\" is not a supported mode for CRT2\n",
1284                                   modename);
1285                        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1286                                   "Skipping metamode \"%s-%s\".\n",
1287                                   mode1->name, modename);
1288                        mode1 = NULL;
1289                    }
1290                }
1291                else {
1292                    mode1 = XGIGetModeFromName(modename, i);
1293                    if (!mode1) {
1294                        char *tmps = str;
1295                        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1296                                   "Mode \"%s\" is not a supported mode for CRT1\n",
1297                                   modename);
1298                        gotdash = FALSE;
1299                        while (*tmps == ' ')
1300                            tmps++;
1301                        if (*tmps == '-') {     /* skip the next mode */
1302                            tmps++;
1303                            while ((*tmps == ' ') && (*tmps != 0))
1304                                tmps++; /* skip spaces */
1305                            while ((*tmps != ' ') && (*tmps != '-')
1306                                   && (*tmps != 0))
1307                                tmps++; /* skip modename */
1308                            strncpy(modename, strmode, tmps - strmode);
1309                            modename[tmps - strmode] = 0;
1310                            str = tmps - 1;
1311                        }
1312                        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1313                                   "Skipping metamode \"%s\".\n", modename);
1314                        mode1 = NULL;
1315                    }
1316                }
1317                gotdash = FALSE;
1318            }
1319            strmode = str + 1;
1320            gotdash |= (*str == '-');
1321
1322            if (*str != 0)
1323                break;
1324            /* Fall through otherwise */
1325
1326        default:
1327            if (!gotdash && mode1) {
1328                sr = srel;
1329                if (!mode2) {
1330                    mode2 = XGIGetModeFromName(mode1->name, j);
1331                    sr = xgiClone;
1332                }
1333                if (!mode2) {
1334                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1335                               "Mode: \"%s\" is not a supported mode for CRT2\n",
1336                               mode1->name);
1337                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1338                               "Skipping metamode \"%s\".\n", modename);
1339                    mode1 = NULL;
1340                }
1341                else {
1342                    result =
1343                        XGICopyModeNLink(pScrn, result, mode1, mode2, sr);
1344                    mode1 = NULL;
1345                    mode2 = NULL;
1346                }
1347            }
1348            break;
1349
1350        }
1351
1352    } while (*(str++) != 0);
1353
1354    return result;
1355}
1356
1357static DisplayModePtr
1358XGIGenerateModeList(ScrnInfoPtr pScrn, char *str,
1359                    DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
1360{
1361    if (str != NULL) {
1362        return (XGIGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
1363    }
1364    else {
1365        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1366                   "No MetaModes given, linking %s modes by default\n",
1367                   (srel == xgiClone) ? "first" :
1368                   (((srel == xgiLeftOf)
1369                     || (srel == xgiRightOf)) ? "widest" : "tallest"));
1370        return (XGIGenerateModeListFromLargestModes(pScrn, i, j, srel));
1371    }
1372}
1373
1374static void
1375XGIRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
1376{
1377    DisplayModePtr mode, bmode;
1378    int max;
1379    static const char *str = "MergedFB: Virtual %s %d\n";
1380
1381	ErrorF("XGIRecalcDefaultVirtualSize()...Update Virtual Size-1\n");
1382    if (!(pScrn->display->virtualX)) {
1383        mode = bmode = pScrn->modes;
1384        max = 0;
1385        do {
1386            if (mode->HDisplay > max)
1387                max = mode->HDisplay;
1388            mode = mode->next;
1389        } while (mode != bmode);
1390        pScrn->virtualX = max;
1391        pScrn->displayWidth = max;
1392		ErrorF("XGIRecalcDefaultVirtualSize()...Update Virtual Size-2-pScrn->virtualX=%d\n", pScrn->virtualX);
1393        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max);
1394    }
1395    if (!(pScrn->display->virtualY)) {
1396        mode = bmode = pScrn->modes;
1397        max = 0;
1398        do {
1399            if (mode->VDisplay > max)
1400                max = mode->VDisplay;
1401            mode = mode->next;
1402        } while (mode != bmode);
1403        pScrn->virtualY = max;
1404        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max);
1405    }
1406}
1407
1408static void
1409XGIMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, XGIScrn2Rel srel)
1410{
1411    XGIPtr pXGI = XGIPTR(pScrn1);
1412    MessageType from = X_DEFAULT;
1413    xf86MonPtr DDC1 = (xf86MonPtr) (pScrn1->monitor->DDC);
1414    xf86MonPtr DDC2 = (xf86MonPtr) (pScrn2->monitor->DDC);
1415    int ddcWidthmm = 0, ddcHeightmm = 0;
1416    const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n";
1417
1418	ErrorF("XGIMergedFBSetDpi()...Use Virtual Size -1\n");
1419
1420    /* This sets the DPI for MergedFB mode. The problem is that
1421     * this can never be exact, because the output devices may
1422     * have different dimensions. This function tries to compromise
1423     * through a few assumptions, and it just calculates an average DPI
1424     * value for both monitors.
1425     */
1426
1427    /* Given DisplaySize should regard BOTH monitors */
1428    pScrn1->widthmm = pScrn1->monitor->widthmm;
1429    pScrn1->heightmm = pScrn1->monitor->heightmm;
1430
1431    /* Get DDC display size; if only either CRT1 or CRT2 provided these,
1432     * assume equal dimensions for both, otherwise add dimensions
1433     */
1434    if ((DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
1435        (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0))) {
1436        ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
1437        ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
1438        switch (srel) {
1439        case xgiLeftOf:
1440        case xgiRightOf:
1441            ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
1442            break;
1443        case xgiAbove:
1444        case xgiBelow:
1445            ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
1446        default:
1447            break;
1448        }
1449    }
1450    else if (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
1451        ddcWidthmm = DDC1->features.hsize * 10;
1452        ddcHeightmm = DDC1->features.vsize * 10;
1453        switch (srel) {
1454        case xgiLeftOf:
1455        case xgiRightOf:
1456            ddcWidthmm *= 2;
1457            break;
1458        case xgiAbove:
1459        case xgiBelow:
1460            ddcHeightmm *= 2;
1461        default:
1462            break;
1463        }
1464    }
1465    else if (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) {
1466        ddcWidthmm = DDC2->features.hsize * 10;
1467        ddcHeightmm = DDC2->features.vsize * 10;
1468        switch (srel) {
1469        case xgiLeftOf:
1470        case xgiRightOf:
1471            ddcWidthmm *= 2;
1472            break;
1473        case xgiAbove:
1474        case xgiBelow:
1475            ddcHeightmm *= 2;
1476        default:
1477            break;
1478        }
1479    }
1480
1481    if (monitorResolution > 0) {
1482
1483        /* Set command line given values (overrules given options) */
1484        pScrn1->xDpi = monitorResolution;
1485        pScrn1->yDpi = monitorResolution;
1486        from = X_CMDLINE;
1487
1488    }
1489    else if (pXGI->MergedFBXDPI) {
1490
1491        /* Set option-wise given values (overrule DisplaySize) */
1492        pScrn1->xDpi = pXGI->MergedFBXDPI;
1493        pScrn1->yDpi = pXGI->MergedFBYDPI;
1494        from = X_CONFIG;
1495
1496    }
1497    else if (pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
1498
1499        /* Set values calculated from given DisplaySize */
1500        from = X_CONFIG;
1501        if (pScrn1->widthmm > 0) {
1502            pScrn1->xDpi =
1503                (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
1504        }
1505        if (pScrn1->heightmm > 0) {
1506            pScrn1->yDpi =
1507                (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
1508        }
1509        xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm,
1510                   pScrn1->heightmm);
1511
1512    }
1513    else if (ddcWidthmm && ddcHeightmm) {
1514
1515        /* Set values from DDC-provided display size */
1516        from = X_PROBED;
1517        xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
1518        pScrn1->widthmm = ddcWidthmm;
1519        pScrn1->heightmm = ddcHeightmm;
1520        if (pScrn1->widthmm > 0) {
1521            pScrn1->xDpi =
1522                (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
1523        }
1524        if (pScrn1->heightmm > 0) {
1525            pScrn1->yDpi =
1526                (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
1527        }
1528
1529    }
1530    else {
1531
1532        pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
1533
1534    }
1535
1536    /* Sanity check */
1537    if (pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
1538        pScrn1->yDpi = pScrn1->xDpi;
1539    if (pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
1540        pScrn1->xDpi = pScrn1->yDpi;
1541
1542    pScrn2->xDpi = pScrn1->xDpi;
1543    pScrn2->yDpi = pScrn1->yDpi;
1544
1545    xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
1546               pScrn1->xDpi, pScrn1->yDpi);
1547}
1548
1549static void
1550XGIFreeCRT2Structs(XGIPtr pXGI)
1551{
1552    if (pXGI->CRT2pScrn) {
1553        if (pXGI->CRT2pScrn->modes) {
1554            while (pXGI->CRT2pScrn->modes)
1555                xf86DeleteMode(&pXGI->CRT2pScrn->modes,
1556                               pXGI->CRT2pScrn->modes);
1557        }
1558        if (pXGI->CRT2pScrn->monitor) {
1559            if (pXGI->CRT2pScrn->monitor->Modes) {
1560                while (pXGI->CRT2pScrn->monitor->Modes)
1561                    xf86DeleteMode(&pXGI->CRT2pScrn->monitor->Modes,
1562                                   pXGI->CRT2pScrn->monitor->Modes);
1563            }
1564            if (pXGI->CRT2pScrn->monitor->DDC)
1565                xfree(pXGI->CRT2pScrn->monitor->DDC);
1566            xfree(pXGI->CRT2pScrn->monitor);
1567        }
1568        xfree(pXGI->CRT2pScrn);
1569        pXGI->CRT2pScrn = NULL;
1570    }
1571}
1572
1573#endif /* End of MergedFB helpers */
1574
1575static xf86MonPtr
1576XGIInternalDDC(ScrnInfoPtr pScrn, int crtno)
1577{
1578    XGIPtr pXGI = XGIPTR(pScrn);
1579    unsigned char buffer[256];
1580
1581    int RealOff;
1582    unsigned char *page;
1583
1584    xf86MonPtr pMonitor = NULL;
1585    xf86Int10InfoPtr pInt = NULL;       /* Our int10 */
1586
1587	/*yilin 03/10/2008: set the monitor default size to 310mm x 240mm to fix KDE font too small problem*/
1588	pScrn->monitor->widthmm = 310;
1589	pScrn->monitor->heightmm = 240;
1590
1591    static char *crtno_means_str[] = {
1592        "CRT1", "DVI", "CRT2"
1593    };
1594
1595    if (crtno > 2 || crtno < 0) {
1596        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1597                   "XGIInternalDDC(): Can not get EDID for crtno = %d,abort.\n",
1598                   crtno);
1599    }
1600    else {
1601        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1602                   "XGIInternalDDC(): getting EDID for %s.\n",
1603                   crtno_means_str[crtno]);
1604    }
1605
1606/* Jong 08/03/2009; get EDID with I2C function instead of VBIOS call */
1607#if 1
1608    ErrorF("get EDID with I2C function instead of VBIOS call...\n");
1609
1610	PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt;
1611    PUCHAR pjEDIDBuffer = buffer;
1612    ULONG  ulBufferSize = 256;
1613
1614	pHwDevInfo->crtno = crtno;
1615	int bEDID = bGetEDID(pHwDevInfo, crtno, pjEDIDBuffer, ulBufferSize);
1616
1617#else
1618    ErrorF("get EDID with VBIOS call...\n");
1619    if (xf86LoadSubModule(pScrn, "int10"))
1620	{
1621#if 0
1622        xf86LoaderReqSymLists(int10Symbols, NULL);
1623#endif
1624        pInt = xf86InitInt10(pXGI->pEnt->index);
1625        if (pInt == NULL) {
1626            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1627                       "XGIInternalDDC(): Can not initialize pInt, abort.\n");
1628            return NULL;
1629        }
1630
1631        page = xf86Int10AllocPages(pInt, 1, &RealOff);
1632        if (page == NULL) {
1633            xf86FreeInt10(pInt);
1634            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1635                       "XGIInternalDDC(): Can not initialize real mode buffer, abort.\n");
1636            return NULL;
1637        }
1638    }
1639
1640    if (pInt)
1641	{
1642        pInt->ax = 0x4f15;      /* VESA DDC supporting */
1643        pInt->bx = 1;           /* get EDID */
1644        pInt->cx = crtno;       /* port 0 or 1 for CRT 1 or 2 */
1645        pInt->es = SEG_ADDR(RealOff);
1646        pInt->di = SEG_OFF(RealOff);
1647        pInt->num = 0x10;
1648        xf86ExecX86int10(pInt);
1649
1650        PDEBUG3(ErrorF
1651                ("ax = %04X bx = %04X cx = %04X dx = %04X si = %04X di = %04X es = %04X\n",
1652                 pInt->ax, pInt->bx, pInt->cx, pInt->dx, pInt->si, pInt->di,
1653                 pInt->es));
1654#endif
1655
1656#if 0
1657        if ((pInt->ax & 0xff00) == 0)
1658		{
1659            int i;
1660
1661            for (i = 0; i < 128; i++) {
1662                buffer[i] = page[i];
1663            }
1664#else /* Jong 08/03/2009; get EDID with I2C function instead of VBIOS call */
1665		if(bEDID == 1)
1666		{
1667            int i;
1668#endif
1669            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1670                       "XGIInternalDDC(): VESA get DDC success for output channel %d.\n",
1671                       crtno + 1);
1672
1673            for (i = 0; i < 128; i += 16) {
1674                unsigned j;
1675                ErrorF("EDID[%02X]", i);
1676                for (j = 0; j < 16; j++) {
1677                    ErrorF(" %02X", buffer[i + j]);
1678                }
1679                ErrorF("\n");
1680            }
1681
1682			g_DVI_I_SignalType = (buffer[20] & 0x80) >> 7;
1683			ErrorF("DVI-I : %s signal ...\n", (g_DVI_I_SignalType == 0x01) ? "DVI" : "CRT" );
1684#if 0
1685            xf86LoaderReqSymLists(ddcSymbols, NULL);
1686#endif
1687			/* Jong 09/04/2007; Alan fixed abnormal EDID data */
1688			/* pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer) ; */
1689			if ( (buffer[0]==0) && (buffer[7]==0) )
1690            {
1691                for (i=1;i<7;i++)
1692                {
1693                    if (buffer[i]!=0xFF)
1694                        break;
1695                }
1696                if (i==7)
1697                {
1698                    pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer);
1699                }
1700            }
1701
1702            if (pMonitor == NULL) {
1703                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1704                           "CRT%d DDC EDID corrupt\n", crtno + 1);
1705                return (NULL);
1706            }
1707            xf86UnloadSubModule("ddc");
1708        }
1709        else {
1710            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1711                       "XGIInternalDDC(): VESA get DDC fail for output channel %d.\n",
1712                       crtno + 1);
1713        }
1714
1715/* Jong 08/03/2009; get EDID with I2C function instead of VBIOS call */
1716#if 0
1717        xf86Int10FreePages(pInt, page, 1);
1718        xf86FreeInt10(pInt);
1719    }
1720#endif
1721
1722    return pMonitor;
1723}
1724
1725/* static xf86MonPtr
1726XGIDoPrivateDDC(ScrnInfoPtr pScrn, int *crtnum)
1727{
1728    XGIPtr pXGI = XGIPTR(pScrn);
1729
1730    if(IS_DUAL_HEAD(pXGI))
1731    {
1732       if(IS_SECOND_HEAD(pXGI))
1733       {
1734          *crtnum = 1;
1735      return(XGIInternalDDC(pScrn, 0));
1736       }
1737       else
1738       {
1739          *crtnum = 2;
1740      return(XGIInternalDDC(pScrn, 1));
1741       }
1742    }
1743    else if(pXGI->CRT1off)
1744    {
1745       *crtnum = 2;
1746       return(XGIInternalDDC(pScrn, 1));
1747    }
1748    else
1749    {
1750       *crtnum = 1;
1751       return(XGIInternalDDC(pScrn, 0));
1752    }
1753} */
1754
1755
1756#ifdef DEBUG5
1757static void
1758XGIDumpMonitorInfo(xf86MonPtr pMonitor)
1759{
1760    struct detailed_timings *pd_timings;
1761    Uchar *pserial;
1762    Uchar *pascii_data;
1763    Uchar *pname;
1764    struct monitor_ranges *pranges;
1765    struct std_timings *pstd_t;
1766    struct whitePoints *pwp;
1767    int i, j;
1768
1769    if (pMonitor == NULL) {
1770        ErrorF("Monitor is NULL");
1771        return;
1772    }
1773
1774    ErrorF("pMonitor->scrnIndex = %d\n", pMonitor->scrnIndex);
1775    ErrorF
1776        ("vendor = %c%c%c%c, prod_id = %x serial = %d week = %d year = %d\n",
1777         pMonitor->vendor.name[0], pMonitor->vendor.name[1],
1778         pMonitor->vendor.name[2], pMonitor->vendor.name[3],
1779         pMonitor->vendor.prod_id, pMonitor->vendor.serial,
1780         pMonitor->vendor.week, pMonitor->vendor.year);
1781
1782    ErrorF("ver = %d %d\n", pMonitor->ver.version, pMonitor->ver.revision);
1783    ErrorF("intput type = %d voltage = %d setup = %d sync = %d\n",
1784           pMonitor->features.input_type,
1785           pMonitor->features.input_voltage,
1786           pMonitor->features.input_setup, pMonitor->features.input_sync);
1787    ErrorF("hsize = %d vsize = %d gamma=%8.3f\n",
1788           pMonitor->features.hsize,
1789           pMonitor->features.vsize, pMonitor->features.gamma);
1790
1791    ErrorF("dpms = %d display_type = %d msc = %d\n",
1792           pMonitor->features.dpms,
1793           pMonitor->features.display_type, pMonitor->features.msc);
1794    ErrorF
1795        ("redx,redy,greenx,greeny,bluex,bluey,whitex,whitey = %8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f\n",
1796         pMonitor->features.redx, pMonitor->features.redy,
1797         pMonitor->features.greenx, pMonitor->features.greeny,
1798         pMonitor->features.bluex, pMonitor->features.bluey,
1799         pMonitor->features.whitex, pMonitor->features.whitey);
1800
1801    ErrorF("established_timings = (t1)%d%d%d%d%d%d%d%d",
1802           (pMonitor->timings1.t1 >> 7) & 1,
1803           (pMonitor->timings1.t1 >> 6) & 1,
1804           (pMonitor->timings1.t1 >> 5) & 1,
1805           (pMonitor->timings1.t1 >> 4) & 1,
1806           (pMonitor->timings1.t1 >> 3) & 1,
1807           (pMonitor->timings1.t1 >> 2) & 1,
1808           (pMonitor->timings1.t1 >> 1) & 1,
1809           (pMonitor->timings1.t1 >> 0) & 1);
1810    ErrorF("(t2) %d%d%d%d%d%d%d%d",
1811           (pMonitor->timings1.t1 >> 7) & 1,
1812           (pMonitor->timings1.t1 >> 6) & 1,
1813           (pMonitor->timings1.t1 >> 5) & 1,
1814           (pMonitor->timings1.t1 >> 4) & 1,
1815           (pMonitor->timings1.t1 >> 3) & 1,
1816           (pMonitor->timings1.t1 >> 2) & 1,
1817           (pMonitor->timings1.t1 >> 1) & 1,
1818           (pMonitor->timings1.t1 >> 0) & 1);
1819    ErrorF("(t_manu)%d%d%d%d%d%d%d%d\n",
1820           (pMonitor->timings1.t_manu >> 7) & 1,
1821           (pMonitor->timings1.t_manu >> 6) & 1,
1822           (pMonitor->timings1.t_manu >> 5) & 1,
1823           (pMonitor->timings1.t_manu >> 4) & 1,
1824           (pMonitor->timings1.t_manu >> 3) & 1,
1825           (pMonitor->timings1.t_manu >> 2) & 1,
1826           (pMonitor->timings1.t_manu >> 1) & 1,
1827           (pMonitor->timings1.t_manu >> 0) & 1);
1828
1829    for (i = 0; i < 7; i++) {
1830        ErrorF
1831            ("std timing %d: hsize = %d, vsize = %d, refresh = %d, id = %d\n",
1832             i, pMonitor->timings2[i].hsize, pMonitor->timings2[i].vsize,
1833             pMonitor->timings2[i].refresh, pMonitor->timings2[i].id);
1834    }
1835
1836    for (i = 0; i < 4; i++) {
1837        ErrorF("Detail timing section %d\n", i);
1838        ErrorF("type = %x\n", pMonitor->det_mon[i].type);
1839        switch (pMonitor->det_mon[i].type) {
1840        case DS_SERIAL:
1841            ErrorF("type = %x DS_SERIAL = %x\n", pMonitor->det_mon[i].type,
1842                   DS_SERIAL);
1843            break;
1844        case DS_ASCII_STR:
1845            ErrorF("type = %x DS_ASCII_STR = %x\n", pMonitor->det_mon[i].type,
1846                   DS_ASCII_STR);
1847            break;
1848        case DS_NAME:
1849            ErrorF("type = %x DS_NAME = %x\n", pMonitor->det_mon[i].type,
1850                   DS_NAME);
1851            break;
1852        case DS_RANGES:
1853            ErrorF("type = %x DS_RANGES = %x\n", pMonitor->det_mon[i].type,
1854                   DS_RANGES);
1855            break;
1856        case DS_WHITE_P:
1857            ErrorF("type = %x DS_WHITE_P = %x\n", pMonitor->det_mon[i].type,
1858                   DS_WHITE_P);
1859            break;
1860        case DS_STD_TIMINGS:
1861            ErrorF("type = %x DS_STD_TIMINGS = %x\n",
1862                   pMonitor->det_mon[i].type, DS_STD_TIMINGS);
1863            break;
1864        }
1865        switch (pMonitor->det_mon[i].type) {
1866        case DS_SERIAL:
1867            pserial = pMonitor->det_mon[i].section.serial;
1868            ErrorF("seial: ");
1869            for (j = 0; j < 13; j++) {
1870                ErrorF("%02X", pserial[j]);
1871            }
1872            ErrorF("\n");
1873            break;
1874        case DS_ASCII_STR:
1875            pascii_data = pMonitor->det_mon[i].section.ascii_data;
1876            ErrorF("ascii: ");
1877            for (j = 0; j < 13; j++) {
1878                ErrorF("%c", pascii_data[j]);
1879            }
1880            ErrorF("\n");
1881            break;
1882        case DS_NAME:
1883            pname = pMonitor->det_mon[i].section.name;
1884            ErrorF("name: ");
1885            for (j = 0; j < 13; j++) {
1886                ErrorF("%c", pname[j]);
1887            }
1888            ErrorF("\n");
1889            break;
1890        case DS_RANGES:
1891            pranges = &(pMonitor->det_mon[i].section.ranges);
1892            ErrorF
1893                ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
1894                 pranges->min_v, pranges->max_v, pranges->min_h,
1895                 pranges->max_h, pranges->max_clock);
1896            break;
1897        case DS_WHITE_P:
1898            pwp = pMonitor->det_mon[i].section.wp;
1899            for (j = 0; j < 2; j++) {
1900                ErrorF
1901                    ("wp[%d].index = %d white_x = %8.3f white_y = %8.3f white_gamma = %8.3f\n",
1902                     j, pwp[j].index, pwp[j].white_x, pwp[j].white_y,
1903                     pwp[j].white_gamma);
1904            }
1905            break;
1906        case DS_STD_TIMINGS:
1907            pstd_t = pMonitor->det_mon[i].section.std_t;
1908            for (j = 0; j < 5; j++) {
1909                ErrorF
1910                    ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
1911                     j, pstd_t[j].hsize, pstd_t[j].vsize, pstd_t[j].refresh,
1912                     pstd_t[j].id);
1913            }
1914            break;
1915        case DT:
1916
1917            pd_timings = &pMonitor->det_mon[i].section.d_timings;
1918            ErrorF("Detail Timing Descriptor\n");
1919            ErrorF("clock = %d\n", pd_timings->clock);
1920            ErrorF("h_active = %d\n", pd_timings->h_active);
1921            ErrorF("h_blanking = %d\n", pd_timings->h_blanking);
1922            ErrorF("v_active = %d\n", pd_timings->v_active);
1923            ErrorF("v_blanking = %d\n", pd_timings->v_blanking);
1924            ErrorF("h_sync_off = %d\n", pd_timings->h_sync_off);
1925            ErrorF("h_sync_width = %d\n", pd_timings->h_sync_width);
1926            ErrorF("v_sync_off = %d\n", pd_timings->v_sync_off);
1927            ErrorF("v_sync_width = %d\n", pd_timings->v_sync_width);
1928            ErrorF("h_size = %d\n", pd_timings->h_size);
1929            ErrorF("v_size = %d\n", pd_timings->v_size);
1930            ErrorF("h_border = %d\n", pd_timings->h_border);
1931            ErrorF("v_border = %d\n", pd_timings->v_border);
1932            ErrorF("interlaced = %d stereo = %x sync = %x misc = %x\n",
1933                   pd_timings->interlaced,
1934                   pd_timings->stereo, pd_timings->sync, pd_timings->misc);
1935            break;
1936        }
1937    }
1938
1939    for (i = 0; i < 128; i += 16) {
1940        ErrorF("rawData[%02X]:", i);
1941        for (j = 0; j < 16; j++) {
1942            ErrorF(" %02X", pMonitor->rawData[i + j]);
1943        }
1944        ErrorF("\n");
1945    }
1946}
1947#endif
1948
1949static void
1950XGIGetMonitorRangeByDDC(MonitorRangePtr range, xf86MonPtr pMonitor)
1951{
1952    int i, j;
1953    float VF, HF;
1954    struct detailed_timings *pd_timings;
1955    struct monitor_ranges *pranges;
1956    struct std_timings *pstd_t;
1957
1958    if ((range == NULL) || (pMonitor == NULL)) {
1959        return;                 /* ignore */
1960    }
1961
1962    PDEBUG5(ErrorF
1963            ("establish timing t1 = %02x t2=%02x\n", pMonitor->timings1.t1,
1964             pMonitor->timings1.t2));
1965
1966    for (i = 0, j = 0; i < 8; i++, j++)
1967	{
1968        if (establish_timing[j].width == -1) {
1969            continue;
1970        }
1971
1972        if (pMonitor->timings1.t1 & (1 << i))
1973		{
1974            PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
1975                           establish_timing[j].width,
1976                           establish_timing[j].height,
1977                           establish_timing[j].VRefresh,
1978                           establish_timing[j].HSync));
1979
1980            if (range->loH > establish_timing[j].HSync) {
1981                range->loH = establish_timing[j].HSync;
1982            }
1983
1984            if (range->hiH < establish_timing[j].HSync) {
1985                range->hiH = establish_timing[j].HSync;
1986            }
1987
1988            if (range->loV > establish_timing[j].VRefresh) {
1989                range->loV = establish_timing[j].VRefresh;
1990            }
1991
1992            if (range->hiV < establish_timing[j].VRefresh) {
1993                range->hiV = establish_timing[j].VRefresh;
1994            }
1995        }
1996    }
1997
1998    PDEBUG5(ErrorF
1999            ("check establish timing t1:range ( %8.3f %8.3f %8.3f %8.3f )\n",
2000             range->loH, range->loV, range->hiH, range->hiV));
2001
2002    for (i = 0; i < 8; i++, j++) {
2003        if (establish_timing[j].width == -1) {
2004            continue;
2005        }
2006
2007        if (pMonitor->timings1.t2 & (1 << i)) {
2008            PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
2009                           establish_timing[j].width,
2010                           establish_timing[j].height,
2011                           establish_timing[j].VRefresh,
2012                           establish_timing[j].HSync));
2013
2014            if (range->loH > establish_timing[j].HSync) {
2015                range->loH = establish_timing[j].HSync;
2016            }
2017
2018            if (range->hiH < establish_timing[j].HSync) {
2019                range->hiH = establish_timing[j].HSync;
2020            }
2021
2022            if (range->loV > establish_timing[j].VRefresh) {
2023                range->loV = establish_timing[j].VRefresh;
2024            }
2025
2026            if (range->hiV < establish_timing[j].VRefresh) {
2027                range->hiV = establish_timing[j].VRefresh;
2028            }
2029        }
2030    }
2031    PDEBUG5(ErrorF
2032            ("check establish timing t2:range ( %8.3f %8.3f %8.3f %8.3f )\n",
2033             range->loH, range->loV, range->hiH, range->hiV));
2034
2035    for (i = 0; i < 8; i++) {
2036        for (j = 0; StdTiming[j].width != -1; j++) {
2037            if ((StdTiming[j].width == pMonitor->timings2[i].hsize) &&
2038                (StdTiming[j].height == pMonitor->timings2[i].vsize) &&
2039                (StdTiming[j].VRefresh == pMonitor->timings2[i].refresh)) {
2040                PDEBUG5(ErrorF("pMonitor->timings2[%d]= %d %d %d %d\n",
2041                               i,
2042                               pMonitor->timings2[i].hsize,
2043                               pMonitor->timings2[i].vsize,
2044                               pMonitor->timings2[i].refresh,
2045                               pMonitor->timings2[i].id));
2046                HF = StdTiming[j].HSync;
2047                VF = StdTiming[j].VRefresh;
2048                if (range->loH > HF)
2049                    range->loH = HF;
2050                if (range->loV > VF)
2051                    range->loV = VF;
2052                if (range->hiH < HF)
2053                    range->hiH = HF;
2054                if (range->hiV < VF)
2055                    range->hiV = VF;
2056                break;
2057            }
2058        }
2059    }
2060    PDEBUG5(ErrorF
2061            ("check standard timing :range ( %8.3f %8.3f %8.3f %8.3f )\n",
2062             range->loH, range->loV, range->hiH, range->hiV));
2063
2064    for (i = 0; i < 4; i++) {
2065        switch (pMonitor->det_mon[i].type) {
2066        case DS_RANGES:
2067            pranges = &(pMonitor->det_mon[i].section.ranges);
2068            PDEBUG5(ErrorF
2069                    ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
2070                     pranges->min_v, pranges->max_v, pranges->min_h,
2071                     pranges->max_h, pranges->max_clock));
2072
2073            if (range->loH > pranges->min_h)
2074                range->loH = pranges->min_h;
2075            if (range->loV > pranges->min_v)
2076                range->loV = pranges->min_v;
2077            if (range->hiH < pranges->max_h)
2078                range->hiH = pranges->max_h;
2079            if (range->hiV < pranges->max_v)
2080                range->hiV = pranges->max_v;
2081            PDEBUG5(ErrorF
2082                    ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
2083                     range->loV, range->hiH, range->hiV));
2084            break;
2085
2086        case DS_STD_TIMINGS:
2087            pstd_t = pMonitor->det_mon[i].section.std_t;
2088            for (j = 0; j < 5; j++) {
2089                int k;
2090                PDEBUG5(ErrorF
2091                        ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
2092                         j, pstd_t[j].hsize, pstd_t[j].vsize,
2093                         pstd_t[j].refresh, pstd_t[j].id));
2094                for (k = 0; StdTiming[k].width != -1; k++) {
2095                    if ((StdTiming[k].width == pstd_t[j].hsize) &&
2096                        (StdTiming[k].height == pstd_t[j].vsize) &&
2097                        (StdTiming[k].VRefresh == pstd_t[j].refresh)) {
2098                        if (range->loH > StdTiming[k].HSync)
2099                            range->loH = StdTiming[k].HSync;
2100                        if (range->hiH < StdTiming[k].HSync)
2101                            range->hiH = StdTiming[k].HSync;
2102                        if (range->loV > StdTiming[k].VRefresh)
2103                            range->loV = StdTiming[k].VRefresh;
2104                        if (range->hiV < StdTiming[k].VRefresh)
2105                            range->hiV = StdTiming[k].VRefresh;
2106                        break;
2107                    }
2108
2109                }
2110            }
2111            break;
2112
2113        case DT:
2114
2115            pd_timings = &pMonitor->det_mon[i].section.d_timings;
2116
2117            HF = pd_timings->clock / (pd_timings->h_active +
2118                                      pd_timings->h_blanking);
2119            VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
2120            HF /= 1000;         /* into KHz Domain */
2121            if (range->loH > HF)
2122                range->loH = HF;
2123            if (range->hiH < HF)
2124                range->hiH = HF;
2125            if (range->loV > VF)
2126                range->loV = VF;
2127            if (range->hiV < VF)
2128                range->hiV = VF;
2129            PDEBUG(ErrorF
2130                   ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
2131                    HF, VF, range->loH, range->loV, range->hiH, range->hiV));
2132            break;
2133        }
2134    }
2135    PDEBUG5(ErrorF
2136            ("Done range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, range->loV,
2137             range->hiH, range->hiV));
2138
2139}
2140
2141static void
2142XGISyncDDCMonitorRange(MonPtr monitor, MonitorRangePtr range)
2143{
2144    int i;
2145    if ((monitor == NULL) || (range == NULL)) {
2146        return;
2147    }
2148
2149	monitor->nHsync++;
2150	monitor->nVrefresh++;
2151
2152#if 1
2153        monitor->hsync[monitor->nHsync-1].lo = range->loH;
2154        monitor->hsync[monitor->nHsync-1].hi = range->hiH;
2155        monitor->vrefresh[monitor->nVrefresh-1].lo = range->loV;
2156        monitor->vrefresh[monitor->nVrefresh-1].hi = range->hiV;
2157#else
2158    for (i = 0; i < monitor->nHsync; i++) {
2159        monitor->hsync[i].lo = range->loH;
2160        monitor->hsync[i].hi = range->hiH;
2161    }
2162
2163    for (i = 0; i < monitor->nVrefresh; i++) {
2164        monitor->vrefresh[i].lo = range->loV;
2165        monitor->vrefresh[i].hi = range->hiV;
2166    }
2167#endif
2168}
2169
2170/* Jong@08212009; defined in vb_ext.c */
2171extern void XGIPowerSaving(PVB_DEVICE_INFO pVBInfo, UCHAR PowerSavingStatus);
2172UCHAR g_PowerSavingStatus = 0x00;
2173
2174static void
2175XGIDDCPreInit(ScrnInfoPtr pScrn)
2176{
2177
2178    XGIPtr pXGI = XGIPTR(pScrn);
2179    xf86MonPtr pMonitor = NULL;
2180    xf86MonPtr pMonitorCRT1 = NULL;
2181    xf86MonPtr pMonitorDVI = NULL;
2182    xf86MonPtr pMonitorCRT2 = NULL;
2183    Bool didddc2;
2184
2185	UCHAR  PowerSavingStatus = 0xFF; /* 0x00; */
2186
2187	if(pXGI->IgnoreDDC)
2188	{
2189		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2190				   "Ignore DDC detection --> No EDID info...turn on all DAC and DVO\n");
2191		XGIPowerSaving(pXGI->XGI_Pr, 0x00);
2192		return;
2193	}
2194
2195    static const char *ddcsstr =
2196        "CRT%d DDC monitor info: ************************************\n";
2197    static const char *ddcestr =
2198        "End of CRT%d DDC monitor info ******************************\n";
2199
2200    /* Now for something completely different: DDC.
2201     * For 300 and 315/330 series, we provide our
2202     * own functions (in order to probe CRT2 as well)
2203     * If these fail, use the VBE.
2204     * All other chipsets will use VBE. No need to re-invent
2205     * the wheel there.
2206     */
2207
2208    pXGI->pVbe = NULL;
2209    didddc2 = FALSE;
2210
2211    /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */
2212    if (IS_DUAL_HEAD(pXGI) && (!didddc2) && !IS_SECOND_HEAD(pXGI))
2213        didddc2 = TRUE;
2214
2215    if (!didddc2) {
2216        /* If CRT1 is off or LCDA, skip DDC via VBE */
2217        if ((pXGI->CRT1off) || (pXGI->VBFlags & CRT1_LCDA))
2218            didddc2 = TRUE;
2219    }
2220
2221    /* Now (re-)load and initialize the DDC module */
2222    if (!didddc2) {
2223
2224        if (xf86LoadSubModule(pScrn, "ddc"))
2225		{
2226#if 0
2227            xf86LoaderReqSymLists(ddcSymbols, NULL);
2228#endif
2229            if (pXGI->xgi_HwDevExt.jChipType == XG27)
2230			{
2231				ErrorF("Getting CRT EDID (DAC1-CRT1)...\n");
2232				pMonitorCRT1 = XGIInternalDDC(pScrn, 0);
2233
2234				if (pMonitorCRT1 == NULL)
2235				{
2236					xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2237							   "Could not retrieve DDC data for CRT1\n");
2238					/* PowerSavingStatus |= 0x01; */ /* device is not detected through DAC1 */
2239
2240					ErrorF("Getting DVI EDID (DVO)...\n");
2241					pMonitorDVI = XGIInternalDDC(pScrn, 1);
2242
2243					if (pMonitorDVI == NULL) {
2244						/* PowerSavingStatus |= 0x02; */ /* device is not detected through DVO */
2245						xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2246							   "Could not retrieve DDC data for DVI\n");
2247					}
2248					else
2249					{
2250						PowerSavingStatus &= ~0x02; /* device is detected through DVO */
2251						xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2252								   "Succeed to retrieve DDC data for DVI\n");
2253					}
2254				}
2255				else
2256				{
2257					if(g_DVI_I_SignalType == 0x00) /* analog CRT */
2258						PowerSavingStatus &= ~0x01; /* CRT device is detected */
2259					else /* DVI digital */
2260						PowerSavingStatus &= ~0x02; /* DVI device is detected */
2261
2262
2263					xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2264						"Succeed to retrieve DDC data for %s\n", (g_DVI_I_SignalType == 0x01) ? "DVI" : "CRT");
2265				}
2266
2267				ErrorF("Getting CRT EDID (CRT2)...\n");
2268				pMonitorCRT2 = XGIInternalDDC(pScrn, 2);
2269
2270				if (pMonitorCRT2 == NULL) {
2271					/* PowerSavingStatus |= 0x04; */ /* device is not detected through DAC2 */
2272					xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2273							   "Could not retrieve DDC data for CRT2\n");
2274				}
2275				else /* Used for filtering of CRT1/DVI modes; g_pMonitorDVI is not a good naming; should be g_pMonitorFilter */
2276				{
2277					PowerSavingStatus &= ~0x04; /* device is detected through DAC2 */
2278					g_pMonitorDVI=pMonitorCRT2;
2279					xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2280							   "Succeed to retrieve DDC data for CRT2\n");
2281				}
2282
2283				if (pMonitorCRT1 != NULL)
2284					pMonitor = pMonitorCRT1;
2285				else if(pMonitorDVI != NULL)
2286					pMonitor = pMonitorDVI;
2287				else if(pMonitorCRT2 != NULL)
2288					pMonitor = pMonitorCRT2;
2289			}
2290			else /* for XG20/21 */
2291			{
2292				ErrorF("Getting CRT EDID (CRT1)...\n");
2293				pMonitor = XGIInternalDDC(pScrn, 0);
2294
2295				if (pMonitor == NULL) {
2296					PowerSavingStatus |= 0x01; /* device is not detected through DAC1 */
2297					xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2298							   "Could not retrieve DDC data\n");
2299				}
2300
2301				if (pXGI->xgi_HwDevExt.jChipType == XG21) /* CRT1 -DVI */
2302				{
2303					ErrorF("Getting XG21 DVI EDID (crt2)...\n");
2304					pMonitorDVI = XGIInternalDDC(pScrn, 1);
2305
2306					if (pMonitorDVI == NULL) {
2307						PowerSavingStatus |= 0x02; /* device is not detected through DVO */
2308						xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2309								   "Could not retrieve DVI DDC data\n");
2310					}
2311					else /* Jong 12/04/2007; used for filtering of CRT1 modes */
2312					{
2313						g_pMonitorDVI=pMonitorDVI;
2314					}
2315
2316					if ((pMonitor == NULL) && (pMonitorDVI != NULL)) {
2317						pMonitor = pMonitorDVI;
2318					}
2319				}
2320			}
2321        }
2322    }
2323
2324	ErrorF("PowerSavingStatus = 0x%x...\n", PowerSavingStatus);
2325
2326	if(PowerSavingStatus == 0xFF)
2327		PowerSavingStatus = 0x00;
2328
2329
2330/*	if((pXGI->xgi_HwDevExt.jChipType == XG27) && (PowerSavingStatus == 0x07))
2331		PowerSavingStatus = 0x00;
2332
2333	if((pXGI->xgi_HwDevExt.jChipType == XG21) && (PowerSavingStatus == 0x03))
2334		PowerSavingStatus = 0x00;
2335*/
2336
2337	XGIPowerSaving(pXGI->XGI_Pr, PowerSavingStatus);
2338	g_PowerSavingStatus = PowerSavingStatus;
2339
2340    /* initialize */
2341
2342    if (pXGI->xgi_HwDevExt.jChipType == XG27)
2343	{
2344		if (pMonitorCRT1) {
2345			pXGI->CRT1Range.loH = 1000;
2346			pXGI->CRT1Range.loV = 1000;
2347			pXGI->CRT1Range.hiH = 0;
2348			pXGI->CRT1Range.hiV = 0;
2349			XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitorCRT1);
2350
2351			if (pMonitorDVI) {
2352				XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitorDVI);
2353			}
2354		}
2355		else {
2356			if (pMonitorDVI) {
2357				pXGI->CRT1Range.loV = 1000;
2358				pXGI->CRT1Range.loH = 1000;
2359				pXGI->CRT1Range.hiH = 0;
2360				pXGI->CRT1Range.hiV = 0;
2361				XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitorDVI);
2362			}
2363			else {
2364				pXGI->CRT1Range.loH = 0;
2365				pXGI->CRT1Range.loV = 0;
2366				pXGI->CRT1Range.hiH = 1000;
2367				pXGI->CRT1Range.hiV = 1000;
2368			}
2369		}
2370
2371		if (pMonitorCRT2) {
2372			pXGI->CRT2Range.loV = 1000;
2373			pXGI->CRT2Range.loH = 1000;
2374			pXGI->CRT2Range.hiH = 0;
2375			pXGI->CRT2Range.hiV = 0;
2376			XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorCRT2);
2377		}
2378		else {
2379			pXGI->CRT2Range.loH = 0;
2380			pXGI->CRT2Range.loV = 0;
2381			pXGI->CRT2Range.hiH = 1000;
2382			pXGI->CRT2Range.hiV = 1000;
2383		}
2384	}
2385	else /* XG20/21 */
2386	{
2387		if (pMonitor) {
2388			pXGI->CRT1Range.loH = 1000;
2389			pXGI->CRT1Range.loV = 1000;
2390			pXGI->CRT1Range.hiH = 0;
2391			pXGI->CRT1Range.hiV = 0;
2392			XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitor);
2393		}
2394		else {
2395			pXGI->CRT1Range.loH = 0;
2396			pXGI->CRT1Range.loV = 0;
2397			pXGI->CRT1Range.hiH = 1000;
2398			pXGI->CRT1Range.hiV = 1000;
2399		}
2400
2401		if (pMonitorDVI) {
2402			pXGI->CRT2Range.loV = 1000;
2403			pXGI->CRT2Range.loH = 1000;
2404			pXGI->CRT2Range.hiH = 0;
2405			pXGI->CRT2Range.hiV = 0;
2406			XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorDVI);
2407		}
2408		else {
2409			pXGI->CRT2Range.loH = 0;
2410			pXGI->CRT2Range.loV = 0;
2411			pXGI->CRT2Range.hiH = 1000;
2412			pXGI->CRT2Range.hiV = 1000;
2413		}
2414	}
2415
2416	/* Jong@08132009 */
2417    /* if (pXGI->xgi_HwDevExt.jChipType == XG21) { */
2418    if ((pXGI->xgi_HwDevExt.jChipType == XG21) || (pXGI->xgi_HwDevExt.jChipType == XG27) ) {
2419        /* Mode range intersecting */
2420        if (pXGI->CRT1Range.loH < pXGI->CRT2Range.loH) {
2421            pXGI->CRT1Range.loH = pXGI->CRT2Range.loH;
2422        }
2423        if (pXGI->CRT1Range.loV < pXGI->CRT2Range.loV) {
2424            pXGI->CRT1Range.loV = pXGI->CRT2Range.loV;
2425        }
2426        if (pXGI->CRT1Range.hiH > pXGI->CRT2Range.hiH) {
2427            pXGI->CRT1Range.hiH = pXGI->CRT2Range.hiH;
2428        }
2429        if (pXGI->CRT1Range.hiV > pXGI->CRT2Range.hiV) {
2430            pXGI->CRT1Range.hiV = pXGI->CRT2Range.hiV;
2431        }
2432    }
2433
2434	if (pMonitor) {
2435		XGISyncDDCMonitorRange(pScrn->monitor, &pXGI->CRT1Range);
2436	}
2437
2438    if (pScrn->monitor) {
2439        pScrn->monitor->DDC = pMonitor;
2440    }
2441
2442    return;
2443
2444#ifdef XGIMERGED
2445    if (pXGI->MergedFB) {
2446        pXGI->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
2447        if (pXGI->CRT2pScrn->monitor) {
2448            DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
2449            memcpy(pXGI->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
2450            pXGI->CRT2pScrn->monitor->DDC = NULL;
2451            pXGI->CRT2pScrn->monitor->Modes = NULL;
2452            tempm = pScrn->monitor->Modes;
2453            while (tempm) {
2454                if (!(newm = xalloc(sizeof(DisplayModeRec))))
2455                    break;
2456                memcpy(newm, tempm, sizeof(DisplayModeRec));
2457                if (!(newm->name = xalloc(strlen(tempm->name) + 1))) {
2458                    xfree(newm);
2459                    break;
2460                }
2461                strcpy(newm->name, tempm->name);
2462                if (!pXGI->CRT2pScrn->monitor->Modes)
2463                    pXGI->CRT2pScrn->monitor->Modes = newm;
2464                if (currentm) {
2465                    currentm->next = newm;
2466                    newm->prev = currentm;
2467                }
2468                currentm = newm;
2469                tempm = tempm->next;
2470            }
2471
2472            if ((pMonitor = XGIInternalDDC(pXGI->CRT2pScrn, 1))) {
2473                xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, 2);
2474                xf86PrintEDID(pMonitor);
2475                xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, 2);
2476                xf86SetDDCproperties(pXGI->CRT2pScrn, pMonitor);
2477
2478                pXGI->CRT2pScrn->monitor->DDC = pMonitor;
2479
2480                /* use DDC data if no ranges in config file */
2481                if (!pXGI->CRT2HSync) {
2482                    pXGI->CRT2pScrn->monitor->nHsync = 0;
2483                }
2484                if (!pXGI->CRT2VRefresh) {
2485                    pXGI->CRT2pScrn->monitor->nVrefresh = 0;
2486                }
2487            }
2488            else {
2489                xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2490                           "Failed to read DDC data for CRT2\n");
2491            }
2492        }
2493        else {
2494            XGIErrorLog(pScrn,
2495                        "Failed to allocate memory for CRT2 monitor, %s.\n",
2496                        mergeddisstr);
2497            if (pXGI->CRT2pScrn)
2498                xfree(pXGI->CRT2pScrn);
2499            pXGI->CRT2pScrn = NULL;
2500            pXGI->MergedFB = FALSE;
2501        }
2502    }
2503#endif
2504
2505#ifdef XGIMERGED
2506    if (pXGI->MergedFB) {
2507        xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 1);
2508    }
2509#endif
2510
2511    /* end of DDC */
2512}
2513
2514#ifdef DEBUG5
2515static void
2516XGIDumpModePtr(DisplayModePtr mode)
2517{
2518    if (mode == NULL)
2519        return;
2520
2521    ErrorF("Dump DisplayModePtr mode\n");
2522    ErrorF("name = %s\n", mode->name);
2523    /* ModeStatus status; */
2524    ErrorF("type = %d\n", mode->type);
2525    ErrorF("Clock = %d\n", mode->Clock);
2526    ErrorF("HDisplay = %d\n", mode->HDisplay);
2527    ErrorF("HSyncStart = %d\n", mode->HSyncStart);
2528    ErrorF("HSyncEnd = %d\n", mode->HSyncEnd);
2529    ErrorF("HTotal = %d\n", mode->HTotal);
2530    ErrorF("HSkew = %d\n", mode->HSkew);
2531    ErrorF("VDisplay = %d\n", mode->VDisplay);
2532    ErrorF("VSyncStart = %d\n", mode->VSyncStart);
2533    ErrorF("VSyncEnd = %d\n", mode->VSyncEnd);
2534    ErrorF("VTotal = %d\n", mode->VTotal);
2535    ErrorF("VScan = %d\n", mode->VScan);
2536    ErrorF("Flags = %d\n", mode->Flags);
2537
2538
2539    ErrorF("ClockIndex = %d\n", mode->ClockIndex);
2540    ErrorF("SynthClock = %d\n", mode->SynthClock);
2541    ErrorF("CrtcHDisplay = %d\n", mode->CrtcHDisplay);
2542    ErrorF("CrtcHBlankStart = %d\n", mode->CrtcHBlankStart);
2543    ErrorF("CrtcHSyncStart = %d\n", mode->CrtcHSyncStart);
2544    ErrorF("CrtcHSyncEnd = %d\n", mode->CrtcHSyncEnd);
2545    ErrorF("CrtcHBlankEnd = %d\n", mode->CrtcHBlankEnd);
2546    ErrorF("CrtcHTotal = %d\n", mode->CrtcHTotal);
2547    ErrorF("CrtcHSkew = %d\n", mode->CrtcHSkew);
2548    ErrorF("CrtcVDisplay = %d\n", mode->CrtcVDisplay);
2549    ErrorF("CrtcVBlankStart = %d\n", mode->CrtcVBlankStart);
2550    ErrorF("CrtcVSyncStart = %d\n", mode->CrtcVSyncStart);
2551    ErrorF("CrtcVSyncEnd = %d\n", mode->CrtcVSyncEnd);
2552    ErrorF("CrtcVBlankEnd = %d\n", mode->CrtcVBlankEnd);
2553    ErrorF("CrtcVTotal = %d\n", mode->CrtcVTotal);
2554    ErrorF("CrtcHAdjusted = %s\n", (mode->CrtcHAdjusted) ? "TRUE" : "FALSE");
2555    ErrorF("CrtcVAdjusted = %s\n", (mode->CrtcVAdjusted) ? "TRUE" : "FALSE");
2556    ErrorF("PrivSize = %d\n", mode->PrivSize);
2557    /* INT32 * Private; */
2558    ErrorF("PrivFlags = %d\n", mode->PrivFlags);
2559    ErrorF("HSync = %8.3f\n", mode->HSync);
2560    ErrorF("VRefresh = %8.3f\n", mode->VRefresh);
2561}
2562#endif
2563
2564static void
2565XGIDumpMonPtr(MonPtr pMonitor)
2566{
2567#ifdef DEBUG5
2568    int i;
2569# if 0
2570    DisplayModePtr mode;
2571#endif
2572
2573    ErrorF("XGIDumpMonPtr() ... \n");
2574    if (pMonitor == NULL) {
2575        ErrorF("pMonitor is NULL\n");
2576    }
2577
2578    ErrorF("id = %s, vendor = %s model = %s\n",
2579           pMonitor->id, pMonitor->vendor, pMonitor->model);
2580    ErrorF("nHsync = %d\n", pMonitor->nHsync);
2581    ErrorF("nVrefresh = %d\n", pMonitor->nVrefresh);
2582
2583    for (i = 0; i < MAX_HSYNC; i++) {
2584        ErrorF("hsync[%d] = (%8.3f,%8.3f)\n", i, pMonitor->hsync[i].lo,
2585               pMonitor->hsync[i].hi);
2586    }
2587
2588    for (i = 0; i < MAX_VREFRESH; i++) {
2589        ErrorF("vrefresh[%d] = (%8.3f,%8.3f)\n", i, pMonitor->vrefresh[i].lo,
2590               pMonitor->vrefresh[i].hi);
2591    }
2592
2593    ErrorF("widthmm = %d, heightmm = %d\n",
2594           pMonitor->widthmm, pMonitor->heightmm);
2595    ErrorF("options = %p, DDC = %p\n", pMonitor->options, pMonitor->DDC);
2596# if 0
2597    mode = pMonitor->Modes;
2598    while (1) {
2599        XGIDumpModePtr(mode);
2600        if (mode == pMonitor->Last) {
2601            break;
2602        }
2603        mode = mode->next;
2604    }
2605# endif
2606#endif /* DEBUG5 */
2607}
2608
2609/* Jong 09/19/2007; support modeline of custom modes */
2610int	ModifyTypeOfSupportMode(DisplayModePtr availModes)
2611{
2612	int CountOfModifiedModes=0;
2613	DisplayModePtr p=availModes;
2614
2615	while(p)
2616	{
2617		/* if( (p->HDisplay == 1440) && (p->VDisplay == 900)) */
2618		if( p->type == 0) /* externel support modeline */
2619		{
2620			p->type = M_T_USERDEF;
2621			CountOfModifiedModes++;
2622		}
2623
2624		p=p->next;
2625	}
2626
2627	return(CountOfModifiedModes);
2628}
2629
2630
2631/* Mandatory */
2632static Bool
2633XGIPreInit(ScrnInfoPtr pScrn, int flags)
2634{
2635    XGIPtr pXGI;
2636    MessageType from;
2637    unsigned long int i;
2638    int temp;
2639    ClockRangePtr clockRanges;
2640    int pix24flags;
2641    int fd;
2642    struct fb_fix_screeninfo fix;
2643    XGIEntPtr pXGIEnt = NULL;
2644    size_t memreq;
2645
2646#if defined(XGIMERGED) || defined(XGIDUALHEAD)
2647    DisplayModePtr first, p, n;
2648#endif
2649    unsigned char srlockReg, crlockReg;
2650    vbeInfoPtr pVbe;
2651
2652        /****************** Code Start ***********************/
2653
2654    ErrorF("XGIPreInit\n");
2655
2656    if (flags & PROBE_DETECT) {
2657        if (xf86LoadSubModule(pScrn, "vbe")) {
2658            int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
2659
2660            if ((pVbe = VBEExtendedInit(NULL, index, 0))) {
2661                ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
2662                vbeFree(pVbe);
2663            }
2664        }
2665        return TRUE;
2666    }
2667
2668    /*
2669     * Note: This function is only called once at server startup, and
2670     * not at the start of each server generation.  This means that
2671     * only things that are persistent across server generations can
2672     * be initialised here.  xf86Screens[] is the array of all screens,
2673     * (pScrn is a pointer to one of these).  Privates allocated using
2674     * xf86AllocateScrnInfoPrivateIndex() are too, and should be used
2675     * for data that must persist across server generations.
2676     *
2677     * Per-generation data should be allocated with
2678     * AllocateScreenPrivateIndex() from the ScreenInit() function.
2679     */
2680
2681    /* Check the number of entities, and fail if it isn't one. */
2682    if (pScrn->numEntities != 1) {
2683        XGIErrorLog(pScrn, "Number of entities is not 1\n");
2684        return FALSE;
2685    }
2686
2687    /* The vgahw module should be loaded here when needed */
2688    if (!xf86LoadSubModule(pScrn, "vgahw")) {
2689        XGIErrorLog(pScrn, "Could not load vgahw module\n");
2690        return FALSE;
2691    }
2692#if 0
2693    xf86LoaderReqSymLists(vgahwSymbols, NULL);
2694#endif
2695    /* Due to the liberal license terms this is needed for
2696     * keeping the copyright notice readable and intact in
2697     * binary distributions. Removing this is a copyright
2698     * infringement. Please read the license terms above.
2699     */
2700
2701    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2702               "XGI driver (%s)\n", "01/21/2009" /*XGI_RELEASE_DATE*/);
2703
2704    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2705               "Copyright (C) 2001-2004 Thomas Winischhofer <thomas@winischhofer.net> and others\n");
2706
2707    /* Allocate a vgaHWRec */
2708    if (!vgaHWGetHWRec(pScrn)) {
2709        XGIErrorLog(pScrn, "Could not allocate VGA private\n");
2710        return FALSE;
2711    }
2712
2713    /* Allocate the XGIRec driverPrivate */
2714    pXGI = XGIGetRec(pScrn);
2715    if (pXGI == NULL) {
2716        XGIErrorLog(pScrn, "Could not allocate memory for pXGI private\n");
2717        return FALSE;
2718    }
2719
2720    pXGI->IODBase = pScrn->domainIOBase;
2721
2722
2723    /* Get the entity, and make sure it is PCI. */
2724    pXGI->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
2725    if (pXGI->pEnt->location.type != BUS_PCI) {
2726        XGIErrorLog(pScrn, "Entity's bus type is not PCI\n");
2727        XGIFreeRec(pScrn);
2728        return FALSE;
2729    }
2730
2731#ifdef XGIDUALHEAD
2732    /* Allocate an entity private if necessary */
2733    if (xf86IsEntityShared(pScrn->entityList[0])) {
2734        pXGIEnt = xf86GetEntityPrivate(pScrn->entityList[0],
2735                                       XGIEntityIndex)->ptr;
2736        pXGI->entityPrivate = pXGIEnt;
2737
2738        /* If something went wrong, quit here */
2739        if ((pXGIEnt->DisableDual) || (pXGIEnt->ErrorAfterFirst)) {
2740            XGIErrorLog(pScrn,
2741                        "First head encountered fatal error, can't continue\n");
2742            XGIFreeRec(pScrn);
2743            return FALSE;
2744        }
2745    }
2746#endif
2747
2748    /* Find the PCI info for this screen */
2749#ifndef XSERVER_LIBPCIACCESS
2750    pXGI->PciInfo = xf86GetPciInfoForEntity(pXGI->pEnt->index);
2751    pXGI->PciTag = pciTag(pXGI->PciInfo->bus, pXGI->PciInfo->device,
2752                          pXGI->PciInfo->func);
2753#endif
2754
2755    pXGI->Primary = xf86IsPrimaryPci(pXGI->PciInfo);
2756    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2757               "This adapter is %s display adapter\n",
2758               (pXGI->Primary ? "primary" : "secondary"));
2759
2760    if (pXGI->Primary) {
2761#if defined(__arm__)
2762        VGAHWPTR(pScrn)->MapPhys = pXGI->PciInfo->ioBase[2] + 0xf2000000;
2763#endif
2764
2765        VGAHWPTR(pScrn)->MapSize = 0x10000;     /* Standard 64k VGA window */
2766        if (!vgaHWMapMem(pScrn)) {
2767            XGIErrorLog(pScrn, "Could not map VGA memory\n");
2768            XGIFreeRec(pScrn);
2769            return FALSE;
2770       } else {
2771#if defined(__arm__)
2772		  vgaHWSetMmioFuncs(VGAHWPTR(pScrn), VGAHWPTR(pScrn)->Base, 0);
2773#endif
2774
2775		  xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
2776				  "VGA memory map from %p to %p \n",
2777#ifdef XSERVER_LIBPCIACCESS
2778				  (void *)(intptr_t)pXGI->PciInfo->regions[2].base_addr, VGAHWPTR(pScrn)->Base);
2779#else
2780				  (void *)(intptr_t)pXGI->PciInfo->ioBase[2], VGAHWPTR(pScrn)->Base);
2781#endif
2782        }
2783    }
2784    vgaHWGetIOBase(VGAHWPTR(pScrn));
2785
2786	/* Jong@08262009; why not to modify ??? */
2787    /* We "patch" the PIOOffset inside vgaHW in order to force
2788     * the vgaHW module to use our relocated i/o ports.
2789     */
2790    VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
2791#ifdef XSERVER_LIBPCIACCESS
2792        (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
2793#else
2794        (pXGI->PciInfo->ioBase[2] & 0xFFFC)
2795#endif
2796        ;
2797
2798    pXGI->pInt = NULL;
2799    if (!pXGI->Primary) {
2800#if !defined(__alpha__)
2801#if !defined(__powerpc__)
2802        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2803                   "Initializing display adapter through int10\n");
2804
2805        if (xf86LoadSubModule(pScrn, "int10")) {
2806#if 0
2807            xf86LoaderReqSymLists(int10Symbols, NULL);
2808#endif
2809            pXGI->pInt = xf86InitInt10(pXGI->pEnt->index);
2810        }
2811        else {
2812            XGIErrorLog(pScrn, "Could not load int10 module\n");
2813        }
2814#endif /* !defined(__powerpc__) */
2815#endif /* !defined(__alpha__) */
2816    }
2817
2818#ifndef XSERVER_LIBPCIACCESS
2819    xf86SetOperatingState(resVgaMem, pXGI->pEnt->index, ResUnusedOpr);
2820
2821    /* Operations for which memory access is required */
2822    pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
2823    /* Operations for which I/O access is required */
2824    pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
2825#endif
2826
2827    /* The ramdac module should be loaded here when needed */
2828    if (!xf86LoadSubModule(pScrn, "ramdac")) {
2829        XGIErrorLog(pScrn, "Could not load ramdac module\n");
2830
2831        if (pXGIEnt)
2832            pXGIEnt->ErrorAfterFirst = TRUE;
2833
2834        if (pXGI->pInt)
2835            xf86FreeInt10(pXGI->pInt);
2836        XGIFreeRec(pScrn);
2837        return FALSE;
2838    }
2839#if 0
2840    xf86LoaderReqSymLists(ramdacSymbols, NULL);
2841#endif
2842    /* Set pScrn->monitor */
2843    pScrn->monitor = pScrn->confScreen->monitor;
2844
2845    /* Jong 09/19/2007; modify type of support modes to M_T_USERDEF */
2846    g_CountOfUserDefinedModes=ModifyTypeOfSupportMode(pScrn->monitor->Modes);
2847
2848    /*
2849     * Set the Chipset and ChipRev, allowing config file entries to
2850     * override. DANGEROUS!
2851     */
2852    if (pXGI->pEnt->device->chipset && *pXGI->pEnt->device->chipset) {
2853        PDEBUG(ErrorF(" --- Chipset 1 \n"));
2854        pScrn->chipset = pXGI->pEnt->device->chipset;
2855        pXGI->Chipset = xf86StringToToken(XGIChipsets, pScrn->chipset);
2856        from = X_CONFIG;
2857    }
2858    else if (pXGI->pEnt->device->chipID >= 0) {
2859        PDEBUG(ErrorF(" --- Chipset 2 \n"));
2860        pXGI->Chipset = pXGI->pEnt->device->chipID;
2861        pScrn->chipset =
2862            (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
2863
2864        from = X_CONFIG;
2865        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
2866                   pXGI->Chipset);
2867    }
2868    else {
2869        PDEBUG(ErrorF(" --- Chipset 3 \n"));
2870        from = X_PROBED;
2871        pXGI->Chipset = DEVICE_ID(pXGI->PciInfo);
2872        pScrn->chipset =
2873            (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
2874    }
2875    if (pXGI->pEnt->device->chipRev >= 0) {
2876        pXGI->ChipRev = pXGI->pEnt->device->chipRev;
2877        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
2878                   pXGI->ChipRev);
2879    }
2880    else {
2881        pXGI->ChipRev = CHIP_REVISION(pXGI->PciInfo);
2882    }
2883    pXGI->xgi_HwDevExt.jChipRevision = pXGI->ChipRev;
2884
2885    PDEBUG(ErrorF(" --- Chipset : %s \n", pScrn->chipset));
2886
2887
2888    /*
2889     * This shouldn't happen because such problems should be caught in
2890     * XGIProbe(), but check it just in case.
2891     */
2892    if (pScrn->chipset == NULL) {
2893        XGIErrorLog(pScrn, "ChipID 0x%04X is not recognised\n",
2894                    pXGI->Chipset);
2895
2896        if (pXGIEnt)
2897            pXGIEnt->ErrorAfterFirst = TRUE;
2898
2899        if (pXGI->pInt)
2900            xf86FreeInt10(pXGI->pInt);
2901        XGIFreeRec(pScrn);
2902        return FALSE;
2903    }
2904
2905    if (pXGI->Chipset < 0) {
2906        XGIErrorLog(pScrn, "Chipset \"%s\" is not recognised\n",
2907                    pScrn->chipset);
2908
2909        if (pXGIEnt)
2910            pXGIEnt->ErrorAfterFirst = TRUE;
2911
2912        if (pXGI->pInt)
2913            xf86FreeInt10(pXGI->pInt);
2914        XGIFreeRec(pScrn);
2915        return FALSE;
2916    }
2917
2918    /* Determine chipset and VGA engine type */
2919    pXGI->ChipFlags = 0;
2920    pXGI->XGI_SD_Flags = 0;
2921
2922    switch (pXGI->Chipset) {
2923    case PCI_CHIP_XGIXG40:
2924    case PCI_CHIP_XGIXG20:
2925    case PCI_CHIP_XGIXG21:
2926        pXGI->xgi_HwDevExt.jChipType = XG40;
2927        pXGI->myCR63 = 0x63;
2928        pXGI->mmioSize = 64;
2929        break;
2930
2931    case PCI_CHIP_XGIXG27:
2932    	pXGI->xgi_HwDevExt.jChipType = XG27;
2933    	pXGI->myCR63 = 0x63;
2934    	pXGI->mmioSize = 64;
2935        break;
2936
2937    default:
2938        /* This driver currently only supports V3XE, V3XT, V5, V8 (all of
2939         * which are XG40 chips) and Z7 (which is XG20).
2940         */
2941        if (pXGI->pInt) {
2942            xf86FreeInt10(pXGI->pInt);
2943        }
2944        XGIFreeRec(pScrn);
2945        return FALSE;
2946    }
2947
2948/* load frame_buffer */
2949
2950    FbDevExist = FALSE;
2951   if((pXGI->Chipset != PCI_CHIP_XGIXG20)&&(pXGI->Chipset != PCI_CHIP_XGIXG21)&&( pXGI->Chipset != PCI_CHIP_XGIXG27 ))
2952   {
2953        if ((fd = open("/dev/fb", 'r')) != -1) {
2954            PDEBUG(ErrorF("--- open /dev/fb....   \n"));
2955            ioctl(fd, FBIOGET_FSCREENINFO, &fix);
2956            if (fix.accel == FB_ACCEL_XGI_GLAMOUR) {
2957                PDEBUG(ErrorF("--- fix.accel....   \n"));
2958                FbDevExist = TRUE;
2959            }
2960            else
2961                PDEBUG(ErrorF("--- no fix.accel.... 0x%08lx  \n", fix.accel));
2962            close(fd);
2963        }
2964    }
2965
2966
2967    /*
2968     * The first thing we should figure out is the depth, bpp, etc.
2969     * Additionally, determine the size of the HWCursor memory area.
2970     */
2971    pXGI->CursorSize = 4096;
2972    pix24flags = Support32bppFb;
2973
2974#ifdef XGIDUALHEAD
2975    /* In case of Dual Head, we need to determine if we are the "master" head or
2976     * the "slave" head. In order to do that, we set PrimInit to DONE in the
2977     * shared entity at the end of the first initialization. The second
2978     * initialization then knows that some things have already been done. THIS
2979     * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
2980     */
2981
2982    if (xf86IsEntityShared(pScrn->entityList[0])) {
2983        if (pXGIEnt->lastInstance > 0) {
2984            if (!xf86IsPrimInitDone(pScrn->entityList[0])) {
2985                /* First Head (always CRT2) */
2986                pXGI->SecondHead = FALSE;
2987                pXGIEnt->pScrn_1 = pScrn;
2988                pXGIEnt->CRT2ModeNo = -1;
2989                pXGIEnt->CRT2ModeSet = FALSE;
2990                pXGI->DualHeadMode = TRUE;
2991                pXGIEnt->DisableDual = FALSE;
2992                pXGIEnt->BIOS = NULL;
2993                pXGIEnt->XGI_Pr = NULL;
2994                pXGIEnt->RenderAccelArray = NULL;
2995            }
2996            else {
2997                /* Second Head (always CRT1) */
2998                pXGI->SecondHead = TRUE;
2999                pXGIEnt->pScrn_2 = pScrn;
3000                pXGI->DualHeadMode = TRUE;
3001            }
3002        }
3003        else {
3004            /* Only one screen in config file - disable dual head mode */
3005            pXGI->SecondHead = FALSE;
3006            pXGI->DualHeadMode = FALSE;
3007            pXGIEnt->DisableDual = TRUE;
3008        }
3009    }
3010    else {
3011        /* Entity is not shared - disable dual head mode */
3012        pXGI->SecondHead = FALSE;
3013        pXGI->DualHeadMode = FALSE;
3014    }
3015#endif
3016
3017    /* Allocate VB_DEVICE_INFO (for mode switching code) and initialize it */
3018    pXGI->XGI_Pr = NULL;
3019    if (pXGIEnt && pXGIEnt->XGI_Pr) {
3020        pXGI->XGI_Pr = pXGIEnt->XGI_Pr;
3021    }
3022
3023    if (!pXGI->XGI_Pr) {
3024        if (!(pXGI->XGI_Pr = xnfcalloc(sizeof(VB_DEVICE_INFO), 1))) {
3025            XGIErrorLog(pScrn,
3026                        "Could not allocate memory for XGI_Pr private\n");
3027
3028            if (pXGIEnt)
3029                pXGIEnt->ErrorAfterFirst = TRUE;
3030            if (pXGI->pInt)
3031                xf86FreeInt10(pXGI->pInt);
3032            XGIFreeRec(pScrn);
3033            return FALSE;
3034        }
3035
3036        if (pXGIEnt)
3037            pXGIEnt->XGI_Pr = pXGI->XGI_Pr;
3038
3039        memset(pXGI->XGI_Pr, 0, sizeof(VB_DEVICE_INFO));
3040    }
3041
3042    /* Get our relocated IO registers */
3043#if defined(__arm__)
3044	pXGI->RelIO = (XGIIOADDRESS)(((IOADDRESS)VGAHWPTR(pScrn)->Base & 0xFFFFFFFC) + pXGI->IODBase);
3045
3046#else
3047    pXGI->RelIO = (XGIIOADDRESS) (pXGI->IODBase |
3048#ifdef XSERVER_LIBPCIACCESS
3049                                  (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
3050#else
3051                                  (pXGI->PciInfo->ioBase[2] & 0xFFFC)
3052#endif
3053                                  );
3054#endif
3055
3056    pXGI->xgi_HwDevExt.pjIOAddress = (XGIIOADDRESS) (pXGI->RelIO + 0x30);
3057    xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n",
3058               (unsigned long) pXGI->RelIO);
3059	ErrorF("xgi_driver.c-pXGI->xgi_HwDevExt.pjIOAddress=0x%lx...\n", pXGI->xgi_HwDevExt.pjIOAddress);
3060
3061    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
3062        XGIErrorLog(pScrn, "xf86SetDepthBpp() error\n");
3063
3064        if (pXGIEnt)
3065            pXGIEnt->ErrorAfterFirst = TRUE;
3066
3067        if (pXGI->pInt)
3068            xf86FreeInt10(pXGI->pInt);
3069        XGIFreeRec(pScrn);
3070        return FALSE;
3071    }
3072
3073    /* Check that the returned depth is one we support */
3074    temp = 0;
3075    switch (pScrn->depth) {
3076    case 8:
3077    case 16:
3078    case 24:
3079#if !defined(__powerpc__)
3080    case 15:
3081#endif
3082        break;
3083    default:
3084        temp = 1;
3085    }
3086
3087    if (temp) {
3088        XGIErrorLog(pScrn,
3089                    "Given color depth (%d) is not supported by this driver/chipset\n",
3090                    pScrn->depth);
3091        if (pXGI->pInt)
3092            xf86FreeInt10(pXGI->pInt);
3093        XGIFreeRec(pScrn);
3094        return FALSE;
3095    }
3096
3097    xf86PrintDepthBpp(pScrn);
3098
3099    /* Get the depth24 pixmap format */
3100    if (pScrn->depth == 24 && pix24bpp == 0) {
3101        pix24bpp = xf86GetBppFromDepth(pScrn, 24);
3102    }
3103
3104    /*
3105     * This must happen after pScrn->display has been set because
3106     * xf86SetWeight references it.
3107     */
3108    if (pScrn->depth > 8) {
3109        /* The defaults are OK for us */
3110        rgb zeros = { 0, 0, 0 };
3111
3112        if (!xf86SetWeight(pScrn, zeros, zeros)) {
3113            XGIErrorLog(pScrn, "xf86SetWeight() error\n");
3114
3115            if (pXGIEnt)
3116                pXGIEnt->ErrorAfterFirst = TRUE;
3117
3118            if (pXGI->pInt)
3119                xf86FreeInt10(pXGI->pInt);
3120            XGIFreeRec(pScrn);
3121            return FALSE;
3122        }
3123        else {
3124            Bool ret = FALSE;
3125            switch (pScrn->depth) {
3126            case 15:
3127                if ((pScrn->weight.red != 5) ||
3128                    (pScrn->weight.green != 5) || (pScrn->weight.blue != 5))
3129                    ret = TRUE;
3130                break;
3131            case 16:
3132                if ((pScrn->weight.red != 5) ||
3133                    (pScrn->weight.green != 6) || (pScrn->weight.blue != 5))
3134                    ret = TRUE;
3135                break;
3136            case 24:
3137                if ((pScrn->weight.red != 8) ||
3138                    (pScrn->weight.green != 8) || (pScrn->weight.blue != 8))
3139                    ret = TRUE;
3140                break;
3141            }
3142            if (ret) {
3143                XGIErrorLog(pScrn,
3144                            "RGB weight %d%d%d at depth %d not supported by hardware\n",
3145                            (int) pScrn->weight.red,
3146                            (int) pScrn->weight.green,
3147                            (int) pScrn->weight.blue, pScrn->depth);
3148
3149                if (pXGIEnt)
3150                    pXGIEnt->ErrorAfterFirst = TRUE;
3151
3152                if (pXGI->pInt)
3153                    xf86FreeInt10(pXGI->pInt);
3154                XGIFreeRec(pScrn);
3155                return FALSE;
3156            }
3157        }
3158    }
3159
3160    /* Set the current layout parameters */
3161    pXGI->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
3162    pXGI->CurrentLayout.depth = pScrn->depth;
3163    /* (Inside this function, we can use pScrn's contents anyway) */
3164
3165    if (!xf86SetDefaultVisual(pScrn, -1)) {
3166        XGIErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
3167
3168        if (pXGIEnt)
3169            pXGIEnt->ErrorAfterFirst = TRUE;
3170
3171        if (pXGI->pInt)
3172            xf86FreeInt10(pXGI->pInt);
3173        XGIFreeRec(pScrn);
3174        return FALSE;
3175    }
3176    else {
3177        /* We don't support DirectColor at > 8bpp */
3178        if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
3179            XGIErrorLog(pScrn,
3180                        "Given default visual (%s) is not supported at depth %d\n",
3181                        xf86GetVisualName(pScrn->defaultVisual),
3182                        pScrn->depth);
3183
3184            if (pXGIEnt)
3185                pXGIEnt->ErrorAfterFirst = TRUE;
3186
3187            if (pXGI->pInt)
3188                xf86FreeInt10(pXGI->pInt);
3189            XGIFreeRec(pScrn);
3190            return FALSE;
3191        }
3192    }
3193
3194    /* Due to palette & timing problems we don't support 8bpp in DHM */
3195    if ((IS_DUAL_HEAD(pXGI)) && (pScrn->bitsPerPixel == 8)) {
3196        XGIErrorLog(pScrn,
3197                    "Color depth 8 not supported in Dual Head mode.\n");
3198        if (pXGIEnt)
3199            pXGIEnt->ErrorAfterFirst = TRUE;
3200        if (pXGI->pInt)
3201            xf86FreeInt10(pXGI->pInt);
3202        XGIFreeRec(pScrn);
3203        return FALSE;
3204    }
3205
3206    /*
3207     * The cmap layer needs this to be initialised.
3208     */
3209    {
3210		Gamma zeros = { 0.0, 0.0, 0.0 };
3211        /* Gamma zeros = { 0.5, 0.5, 0.5 }; */
3212
3213        if (!xf86SetGamma(pScrn, zeros)) {
3214            XGIErrorLog(pScrn, "xf86SetGamma() error\n");
3215
3216            if (pXGIEnt)
3217                pXGIEnt->ErrorAfterFirst = TRUE;
3218
3219            if (pXGI->pInt)
3220                xf86FreeInt10(pXGI->pInt);
3221            XGIFreeRec(pScrn);
3222            return FALSE;
3223        }
3224    }
3225
3226    /* We use a programamble clock */
3227    pScrn->progClock = TRUE;
3228
3229    /* Set the bits per RGB for 8bpp mode */
3230    if (pScrn->depth == 8) {
3231        pScrn->rgbBits = 6;
3232    }
3233
3234    from = X_DEFAULT;
3235
3236    /* Unlock registers */
3237    xgiSaveUnlockExtRegisterLock(pXGI, &srlockReg, &crlockReg);
3238
3239    /* Read BIOS for 300 and 315/330 series customization */
3240    pXGI->xgi_HwDevExt.pjVirtualRomBase = NULL;
3241    pXGI->BIOS = NULL;
3242    pXGI->xgi_HwDevExt.UseROM = FALSE;
3243
3244    /* Evaluate options */
3245    xgiOptions(pScrn);
3246
3247#ifdef XGIMERGED
3248    /* Due to palette & timing problems we don't support 8bpp in MFBM */
3249    if ((pXGI->MergedFB) && (pScrn->bitsPerPixel == 8)) {
3250        XGIErrorLog(pScrn, "MergedFB: Color depth 8 not supported, %s\n",
3251                    mergeddisstr);
3252        pXGI->MergedFB = pXGI->MergedFBAuto = FALSE;
3253    }
3254#endif
3255
3256    /* Do basic configuration */
3257
3258    XGISetup(pScrn);
3259
3260    from = X_PROBED;
3261#ifdef XSERVER_LIBPCIACCESS
3262        pXGI->FbAddress = pXGI->PciInfo->regions[0].base_addr & 0xFFFFFFF0;
3263#else
3264    if (pXGI->pEnt->device->MemBase != 0) {
3265        /*
3266         * XXX Should check that the config file value matches one of the
3267         * PCI base address values.
3268         */
3269        pXGI->FbAddress = pXGI->pEnt->device->MemBase;
3270        from = X_CONFIG;
3271    }
3272    else {
3273        pXGI->FbAddress = pXGI->PciInfo->memBase[0] & 0xFFFFFFF0;
3274    }
3275#endif
3276
3277    pXGI->realFbAddress = pXGI->FbAddress;
3278
3279    xf86DrvMsg(pScrn->scrnIndex, from,
3280               "%sinear framebuffer at 0x%lX\n",
3281               IS_DUAL_HEAD(pXGI) ? "Global l" : "L",
3282               (unsigned long) pXGI->FbAddress);
3283
3284#ifdef XSERVER_LIBPCIACCESS
3285        pXGI->IOAddress = pXGI->PciInfo->regions[1].base_addr & 0xFFFFFFF0;
3286#else
3287    if (pXGI->pEnt->device->IOBase != 0) {
3288        /*
3289         * XXX Should check that the config file value matches one of the
3290         * PCI base address values.
3291         */
3292        pXGI->IOAddress = pXGI->pEnt->device->IOBase;
3293        from = X_CONFIG;
3294    }
3295    else {
3296        pXGI->IOAddress = pXGI->PciInfo->memBase[1] & 0xFFFFFFF0;
3297    }
3298#endif
3299
3300    xf86DrvMsg(pScrn->scrnIndex, from,
3301               "MMIO registers at 0x%lX (size %ldK)\n",
3302               (unsigned long) pXGI->IOAddress, pXGI->mmioSize);
3303    pXGI->xgi_HwDevExt.bIntegratedMMEnabled = TRUE;
3304
3305#ifndef XSERVER_LIBPCIACCESS
3306    /* Register the PCI-assigned resources. */
3307    if (xf86RegisterResources(pXGI->pEnt->index, NULL, ResExclusive)) {
3308        XGIErrorLog(pScrn,
3309                    "xf86RegisterResources() found resource conflicts\n");
3310
3311        if (pXGIEnt)
3312            pXGIEnt->ErrorAfterFirst = TRUE;
3313
3314        if (pXGI->pInt)
3315            xf86FreeInt10(pXGI->pInt);
3316        xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
3317        XGIFreeRec(pScrn);
3318        return FALSE;
3319    }
3320#endif
3321
3322    from = X_PROBED;
3323    if (pXGI->pEnt->device->videoRam != 0) {
3324
3325        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3326                   "Option \"VideoRAM\" ignored\n");
3327    }
3328
3329    xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n", pScrn->videoRam);
3330
3331    pXGI->FbMapSize = pXGI->availMem = pScrn->videoRam * 1024;
3332    pXGI->xgi_HwDevExt.ulVideoMemorySize = pScrn->videoRam * 1024;
3333    pXGI->xgi_HwDevExt.bSkipDramSizing = TRUE;
3334
3335    /* Calculate real availMem according to Accel/TurboQueue and
3336     * HWCursur setting.
3337     *
3338     * TQ is max 64KiB.  Reduce the available memory by 64KiB, and locate the
3339     * TQ at the beginning of this last 64KiB block.  This is done even when
3340     * using the HWCursor, because the cursor only takes 2KiB and the queue
3341     * does not seem to last that far anyway.
3342     *
3343     * The TQ must be located at 32KB boundaries.
3344     */
3345    if (pScrn->videoRam < 3072) {
3346        if (pXGI->TurboQueue) {
3347            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3348                       "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
3349            pXGI->TurboQueue = FALSE;
3350        }
3351    }
3352
3353    pXGI->availMem -= (pXGI->TurboQueue) ? (64 * 1024) : pXGI->CursorSize;
3354
3355
3356    /* In dual head mode, we share availMem equally - so align it
3357     * to 8KB; this way, the address of the FB of the second
3358     * head is aligned to 4KB for mapping.
3359     *
3360     * Check MaxXFBMem setting.  Since DRI is not supported in dual head
3361     * mode, we don't need the MaxXFBMem setting.
3362     */
3363    if (IS_DUAL_HEAD(pXGI)) {
3364        if (pXGI->maxxfbmem) {
3365            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3366                       "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n");
3367        }
3368
3369        pXGI->availMem &= 0xFFFFE000;
3370        pXGI->maxxfbmem = pXGI->availMem;
3371    }
3372    else if (pXGI->maxxfbmem) {
3373        if (pXGI->maxxfbmem > pXGI->availMem) {
3374            if (pXGI->xgifbMem) {
3375                pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
3376                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3377                           "Invalid MaxXFBMem setting. Using xgifb heap start information\n");
3378            }
3379            else {
3380                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3381                           "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
3382                pXGI->maxxfbmem = pXGI->availMem;
3383            }
3384        }
3385        else if (pXGI->xgifbMem) {
3386            if (pXGI->maxxfbmem > pXGI->xgifbMem * 1024) {
3387                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3388                           "MaxXFBMem beyond xgifb heap start. Using xgifb heap start\n");
3389                pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
3390            }
3391        }
3392    }
3393    else if (pXGI->xgifbMem) {
3394        pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
3395    }
3396    else
3397        pXGI->maxxfbmem = pXGI->availMem;
3398
3399    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n",
3400               pXGI->maxxfbmem / 1024);
3401
3402    pXGI->CRT1off = -1;
3403
3404    /* Detect video bridge and sense TV/VGA2 */
3405    XGIVGAPreInit(pScrn);
3406
3407    /* Detect CRT1 (via DDC1 and DDC2, hence via VGA port; regardless of LCDA) */
3408    XGICRT1PreInit(pScrn);
3409
3410    /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */
3411    XGILCDPreInit(pScrn);
3412
3413    /* LCDA only supported under these conditions: */
3414    if (pXGI->ForceCRT1Type == CRT1_LCDA) {
3415        if (!
3416            (pXGI->XGI_Pr->
3417             VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV |
3418                           VB_XGI302LV))) {
3419            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3420                       "Chipset/Video bridge does not support LCD-via-CRT1\n");
3421            pXGI->ForceCRT1Type = CRT1_VGA;
3422        }
3423        else if (!(pXGI->VBFlags & CRT2_LCD)) {
3424            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3425                       "No digitally connected LCD panel found, LCD-via-CRT1 "
3426                       "disabled\n");
3427            pXGI->ForceCRT1Type = CRT1_VGA;
3428        }
3429    }
3430
3431    /* Setup SD flags */
3432    pXGI->XGI_SD_Flags |= XGI_SD_ADDLSUPFLAG;
3433
3434    if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
3435        pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTV;
3436    }
3437
3438#ifdef ENABLE_YPBPR
3439    if (pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B)) {
3440        pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTHIVISION;
3441    }
3442#endif
3443
3444#ifdef TWDEBUG                  /* @@@ TEST @@@ */
3445    pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTYPBPRAR;
3446    xf86DrvMsg(0, X_INFO, "TEST: Support Aspect Ratio\n");
3447#endif
3448
3449    /* Detect CRT2-TV and PAL/NTSC mode */
3450    XGITVPreInit(pScrn);
3451
3452    /* Detect CRT2-VGA */
3453    XGICRT2PreInit(pScrn);
3454    PDEBUG(ErrorF("3496 pXGI->VBFlags =%x\n", pXGI->VBFlags));
3455
3456    if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR)) {
3457        if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_YPBPR)) {
3458            pXGI->ForceTVType = -1;
3459            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3460                       "YPbPr TV output not supported\n");
3461        }
3462    }
3463
3464    if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTHIVISION)) {
3465        if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_HIVISION)) {
3466            pXGI->ForceTVType = -1;
3467            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3468                       "HiVision TV output not supported\n");
3469        }
3470    }
3471
3472    if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
3473        pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
3474    }
3475    if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
3476        pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTVPOS;
3477    }
3478    if (pXGI->XGI_Pr->
3479        VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
3480        pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTSCART | XGI_SD_SUPPORTVGA2);
3481    }
3482
3483    if ((pXGI->XGI_Pr->
3484         VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV | VB_XGI302LV))
3485        && (pXGI->VBFlags & CRT2_LCD)) {
3486        pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTLCDA;
3487    }
3488
3489    pXGI->VBFlags |= pXGI->ForceCRT1Type;
3490
3491#ifdef TWDEBUG
3492    xf86DrvMsg(0, X_INFO, "SDFlags %lx\n", pXGI->XGI_SD_Flags);
3493#endif
3494
3495
3496    if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI)) {
3497        xf86DrvMsg(pScrn->scrnIndex, pXGI->CRT1gammaGiven ? X_CONFIG : X_INFO,
3498                   "CRT1 gamma correction is %s\n",
3499                   pXGI->CRT1gamma ? "enabled" : "disabled");
3500    }
3501
3502    /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART, HIVISION, YPBPR) */
3503    if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
3504        if (pXGI->ForceTVType != -1) {
3505            pXGI->VBFlags &= ~(TV_INTERFACE);
3506            pXGI->VBFlags |= pXGI->ForceTVType;
3507            if (pXGI->VBFlags & TV_YPBPR) {
3508                pXGI->VBFlags &= ~(TV_STANDARD);
3509                pXGI->VBFlags &= ~(TV_YPBPRAR);
3510                pXGI->VBFlags |= pXGI->ForceYPbPrType;
3511                pXGI->VBFlags |= pXGI->ForceYPbPrAR;
3512            }
3513        }
3514    }
3515
3516    /* Check if CRT1 used or needed.  There are three cases where this can
3517     * happen:
3518     *     - No video bridge.
3519     *     - No CRT2 output.
3520     *     - Depth = 8 and bridge=LVDS|301B-DH
3521     *     - LCDA
3522     */
3523    if (((pXGI->XGI_Pr->VBType & VB_XGIVB) == 0)
3524        || ((pXGI->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)) == 0)
3525        || ((pScrn->bitsPerPixel == 8)
3526            && (pXGI->XGI_Pr->VBType & VB_XGI301LV302LV))
3527        || (pXGI->VBFlags & CRT1_LCDA)) {
3528        pXGI->CRT1off = 0;
3529    }
3530
3531
3532    /* Handle TVStandard option */
3533    if ((pXGI->NonDefaultPAL != -1) || (pXGI->NonDefaultNTSC != -1)) {
3534        if (!(pXGI->XGI_Pr->VBType & VB_XGIVB)) {
3535            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3536                       "PALM, PALN and NTSCJ not supported on this hardware\n");
3537            pXGI->NonDefaultPAL = pXGI->NonDefaultNTSC = -1;
3538            pXGI->VBFlags &= ~(TV_PALN | TV_PALM | TV_NTSCJ);
3539            pXGI->XGI_SD_Flags &=
3540                ~(XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
3541        }
3542    }
3543
3544#ifdef XGI_CP
3545    XGI_CP_DRIVER_RECONFIGOPT
3546#endif
3547        /* Do some MergedFB mode initialisation */
3548#ifdef XGIMERGED
3549        if (pXGI->MergedFB) {
3550        pXGI->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
3551        if (!pXGI->CRT2pScrn) {
3552            XGIErrorLog(pScrn,
3553                        "Failed to allocate memory for 2nd pScrn, %s\n",
3554                        mergeddisstr);
3555            pXGI->MergedFB = FALSE;
3556        }
3557        else {
3558            memcpy(pXGI->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
3559        }
3560    }
3561#endif
3562    PDEBUG(ErrorF("3674 pXGI->VBFlags =%x\n", pXGI->VBFlags));
3563
3564    /* Determine CRT1<>CRT2 mode
3565     *     Note: When using VESA or if the bridge is in slavemode, display
3566     *           is ALWAYS in MIRROR_MODE!
3567     *           This requires extra checks in functions using this flag!
3568     *           (see xgi_video.c for example)
3569     */
3570    if (pXGI->VBFlags & DISPTYPE_DISP2) {
3571        if (pXGI->CRT1off) {    /* CRT2 only ------------------------------- */
3572            if (IS_DUAL_HEAD(pXGI)) {
3573                XGIErrorLog(pScrn,
3574                            "CRT1 not detected or forced off. Dual Head mode can't initialize.\n");
3575                if (pXGIEnt)
3576                    pXGIEnt->DisableDual = TRUE;
3577                if (pXGIEnt)
3578                    pXGIEnt->ErrorAfterFirst = TRUE;
3579                if (pXGI->pInt)
3580                    xf86FreeInt10(pXGI->pInt);
3581                pXGI->pInt = NULL;
3582                xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
3583                XGIFreeRec(pScrn);
3584                return FALSE;
3585            }
3586#ifdef XGIMERGED
3587            if (pXGI->MergedFB) {
3588                if (pXGI->MergedFBAuto) {
3589                    xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt1,
3590                               mergeddisstr);
3591                }
3592                else {
3593                    XGIErrorLog(pScrn, mergednocrt1, mergeddisstr);
3594                }
3595                if (pXGI->CRT2pScrn)
3596                    xfree(pXGI->CRT2pScrn);
3597                pXGI->CRT2pScrn = NULL;
3598                pXGI->MergedFB = FALSE;
3599            }
3600#endif
3601            pXGI->VBFlags |= VB_DISPMODE_SINGLE;
3602        }
3603        /* CRT1 and CRT2 - mirror or dual head ----- */
3604        else if (IS_DUAL_HEAD(pXGI)) {
3605            pXGI->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1);
3606            if (pXGIEnt)
3607                pXGIEnt->DisableDual = FALSE;
3608        }
3609        else
3610            pXGI->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
3611    }
3612    else {                      /* CRT1 only ------------------------------- */
3613        if (IS_DUAL_HEAD(pXGI)) {
3614            XGIErrorLog(pScrn,
3615                        "No CRT2 output selected or no bridge detected. "
3616                        "Dual Head mode can't initialize.\n");
3617            if (pXGIEnt)
3618                pXGIEnt->ErrorAfterFirst = TRUE;
3619            if (pXGI->pInt)
3620                xf86FreeInt10(pXGI->pInt);
3621            pXGI->pInt = NULL;
3622            xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
3623            XGIFreeRec(pScrn);
3624            return FALSE;
3625        }
3626
3627#ifdef XGIMERGED
3628        if (pXGI->MergedFB) {
3629            if (pXGI->MergedFBAuto) {
3630                xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt2,
3631                           mergeddisstr);
3632            }
3633            else {
3634                XGIErrorLog(pScrn, mergednocrt2, mergeddisstr);
3635            }
3636            if (pXGI->CRT2pScrn)
3637                xfree(pXGI->CRT2pScrn);
3638            pXGI->CRT2pScrn = NULL;
3639            pXGI->MergedFB = FALSE;
3640        }
3641#endif
3642        PDEBUG(ErrorF("3782 pXGI->VBFlags =%x\n", pXGI->VBFlags));
3643        pXGI->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
3644    }
3645
3646    /* Init Ptrs for Save/Restore functions and calc MaxClock */
3647    XGIDACPreInit(pScrn);
3648
3649    /* ********** end of VBFlags setup ********** */
3650
3651    /* VBFlags are initialized now. Back them up for SlaveMode modes. */
3652    pXGI->VBFlags_backup = pXGI->VBFlags;
3653
3654    /* Find out about paneldelaycompensation and evaluate option */
3655    if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
3656
3657    }
3658
3659    /* In dual head mode, both heads (currently) share the maxxfbmem equally.
3660     * If memory sharing is done differently, the following has to be changed;
3661     * the other modules (eg. accel and Xv) use dhmOffset for hardware
3662     * pointer settings relative to VideoRAM start and won't need to be changed.
3663     */
3664    if (IS_DUAL_HEAD(pXGI)) {
3665        if (!IS_SECOND_HEAD(pXGI)) {
3666            /* ===== First head (always CRT2) ===== */
3667            /* We use only half of the memory available */
3668            pXGI->maxxfbmem /= 2;
3669            /* Initialize dhmOffset */
3670            pXGI->dhmOffset = 0;
3671            /* Copy framebuffer addresses & sizes to entity */
3672            pXGIEnt->masterFbAddress = pXGI->FbAddress;
3673            pXGIEnt->masterFbSize = pXGI->maxxfbmem;
3674            pXGIEnt->slaveFbAddress = pXGI->FbAddress + pXGI->maxxfbmem;
3675            pXGIEnt->slaveFbSize = pXGI->maxxfbmem;
3676            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
3677                       "%ldKB video RAM at 0x%lx available for master head (CRT2)\n",
3678                       pXGI->maxxfbmem / 1024, pXGI->FbAddress);
3679        }
3680        else {
3681            /* ===== Second head (always CRT1) ===== */
3682            /* We use only half of the memory available */
3683            pXGI->maxxfbmem /= 2;
3684            /* Adapt FBAddress */
3685            pXGI->FbAddress += pXGI->maxxfbmem;
3686            /* Initialize dhmOffset */
3687            pXGI->dhmOffset = pXGI->availMem - pXGI->maxxfbmem;
3688            xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
3689                       "%ldKB video RAM at 0x%lx available for slave head (CRT1)\n",
3690                       pXGI->maxxfbmem / 1024, pXGI->FbAddress);
3691        }
3692    }
3693    else
3694        pXGI->dhmOffset = 0;
3695
3696    /* Note: Do not use availMem for anything from now. Use
3697     * maxxfbmem instead. (availMem does not take dual head
3698     * mode into account.)
3699     */
3700
3701#if !defined(__arm__)
3702#if !defined(__powerpc__)
3703    /* Now load and initialize VBE module. */
3704    if (xf86LoadSubModule(pScrn, "vbe")) {
3705#if 0
3706        xf86LoaderReqSymLists(vbeSymbols, NULL);
3707#endif
3708        pXGI->pVbe = VBEExtendedInit(pXGI->pInt, pXGI->pEnt->index,
3709                                     SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
3710        if (!pXGI->pVbe) {
3711            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3712                       "Could not initialize VBE module for DDC\n");
3713        }
3714    }
3715    else {
3716        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3717                   "Could not load VBE module\n");
3718    }
3719
3720#endif
3721#endif
3722
3723
3724    XGIDDCPreInit(pScrn);
3725
3726    /* Jong 07/29/2009; Proposal : use wide range for HorizSync and strict range for VertRefresh; And set 1024x768 in Modes of Screen section */
3727	/* Jong 07/17/2009; fix issue of only one mode (800x600) */
3728    /* if (no Horizsync or VertRefresh is spefified in Monitor section) and (no DDC detection) */
3729    /* then apply followings as default Hsync and VRefresh (1024x768x60HZ) */
3730    /* XGIDDCPreInit() should be called first to get EDID but need I2C programming instead of VBIOS call */
3731	if(pScrn->monitor->DDC == NULL)
3732	{
3733		ErrorF("Non-DDC minitor or NO EDID information...\n");
3734
3735		if(pScrn->monitor->nHsync == 0)
3736		{
3737			pScrn->monitor->nHsync = 1;
3738			pScrn->monitor->hsync[0].lo=30;
3739			pScrn->monitor->hsync[0].hi=50;
3740			ErrorF("No HorizSync information set in Monitor section and use default (%g, %g)...\n",
3741				pScrn->monitor->hsync[0].lo, pScrn->monitor->hsync[0].hi);
3742		}
3743
3744		if(pScrn->monitor->nVrefresh == 0)
3745		{
3746			pScrn->monitor->nVrefresh = 1;
3747			pScrn->monitor->vrefresh[0].lo=40;
3748			pScrn->monitor->vrefresh[0].hi=60;
3749			ErrorF("No VertRefresh information set in Monitor section and use default (%g, %g)...\n",
3750				pScrn->monitor->vrefresh[0].lo, pScrn->monitor->vrefresh[0].hi);
3751		}
3752	}
3753
3754    /* From here, we mainly deal with clocks and modes */
3755
3756    /* Set the min pixel clock */
3757    pXGI->MinClock = 5000;
3758
3759    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
3760               pXGI->MinClock / 1000);
3761
3762    from = X_PROBED;
3763    /*
3764     * If the user has specified ramdac speed in the XF86Config
3765     * file, we respect that setting.
3766     */
3767    if (pXGI->pEnt->device->dacSpeeds[0]) {
3768        int speed = 0;
3769        switch (pScrn->bitsPerPixel) {
3770        case 8:
3771            speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP8];
3772            break;
3773        case 16:
3774            speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP16];
3775            break;
3776        case 24:
3777            speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP24];
3778            break;
3779        case 32:
3780            speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP32];
3781            break;
3782        }
3783        if (speed == 0)
3784            pXGI->MaxClock = pXGI->pEnt->device->dacSpeeds[0];
3785        else
3786            pXGI->MaxClock = speed;
3787        from = X_CONFIG;
3788    }
3789    xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
3790               pXGI->MaxClock / 1000);
3791
3792    /*
3793     * Setup the ClockRanges, which describe what clock ranges are available,
3794     * and what sort of modes they can be used for.
3795     */
3796    clockRanges = xnfcalloc(sizeof(ClockRange), 1);
3797    clockRanges->next = NULL;
3798    clockRanges->minClock = pXGI->MinClock;
3799    clockRanges->maxClock = pXGI->MaxClock;
3800    clockRanges->clockIndex = -1;       /* programmable */
3801    clockRanges->interlaceAllowed = TRUE;
3802    clockRanges->doubleScanAllowed = TRUE;
3803
3804    /*
3805     * xf86ValidateModes will check that the mode HTotal and VTotal values
3806     * don't exceed the chipset's limit if pScrn->maxHValue and
3807     * pScrn->maxVValue are set.  Since our XGIValidMode() already takes
3808     * care of this, we don't worry about setting them here.
3809     */
3810
3811    /* Select valid modes from those available */
3812#ifdef XGIMERGED
3813    pXGI->CheckForCRT2 = FALSE;
3814#endif
3815    XGIDumpMonPtr(pScrn->monitor);
3816
3817
3818	XGIAddAvailableModes(pScrn->monitor->Modes);
3819
3820	/* XGIFilterModeByDDC(pScrn->monitor->Modes, g_pMonitorDVI); */ /* Do it in XGIValidMode() */
3821
3822	ErrorF("Call xf86ValidateModes()...Use Virtual Size-1-Virtual Size=%d\n", pScrn->display->virtualX);
3823    i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, 2048,    /* min / max pitch */
3824                          pScrn->bitsPerPixel * 8, 128, 2048,   /* min / max height */
3825                          pScrn->display->virtualX,
3826                          pScrn->display->virtualY,
3827                          pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
3828
3829    if (i == -1) {
3830        XGIErrorLog(pScrn, "xf86ValidateModes() error\n");
3831
3832        if (pXGIEnt)
3833            pXGIEnt->ErrorAfterFirst = TRUE;
3834
3835        if (pXGI->pInt)
3836            xf86FreeInt10(pXGI->pInt);
3837        xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
3838        XGIFreeRec(pScrn);
3839        return FALSE;
3840    }
3841
3842    /* Check the virtual screen against the available memory */
3843
3844    memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8))
3845	* pScrn->virtualY;
3846
3847    if (memreq > pXGI->maxxfbmem) {
3848		XGIErrorLog(pScrn,
3849				"Virtual screen too big for memory; %ldK needed, %ldK available\n",
3850				memreq / 1024, pXGI->maxxfbmem / 1024);
3851
3852		if (pXGIEnt)
3853			pXGIEnt->ErrorAfterFirst = TRUE;
3854
3855		if (pXGI->pInt)
3856			xf86FreeInt10(pXGI->pInt);
3857		pXGI->pInt = NULL;
3858		xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
3859		XGIFreeRec(pScrn);
3860		return FALSE;
3861    }
3862    else if (pXGI->loadDRI && !IS_DUAL_HEAD(pXGI))
3863	{
3864		pXGI->maxxfbmem = memreq;
3865		pXGI->DRIheapstart = pXGI->DRIheapend = 0;
3866
3867		if (pXGI->maxxfbmem == pXGI->availMem) {
3868			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3869				   "All video memory used for framebuffer.  DRI will be disabled.\n");
3870			pXGI->loadDRI = FALSE;
3871		}
3872		else {
3873			pXGI->DRIheapstart = pXGI->maxxfbmem;
3874			pXGI->DRIheapend = pXGI->availMem;
3875		}
3876    }
3877
3878
3879    /* Dual Head:
3880     * -) Go through mode list and mark all those modes as bad,
3881     *    which are unsuitable for dual head mode.
3882     * -) Find the highest used pixelclock on the master head.
3883     */
3884    if (IS_DUAL_HEAD(pXGI) && !IS_SECOND_HEAD(pXGI))
3885	{
3886        pXGIEnt->maxUsedClock = 0;
3887
3888        if ((p = first = pScrn->modes))
3889		{
3890            do {
3891                n = p->next;
3892
3893                /* Modes that require the bridge to operate in SlaveMode
3894                 * are not suitable for Dual Head mode.
3895                 */
3896
3897                /* Search for the highest clock on first head in order to calculate
3898                 * max clock for second head (CRT1)
3899                 */
3900                if ((p->status == MODE_OK)
3901                    && (p->Clock > pXGIEnt->maxUsedClock)) {
3902                    pXGIEnt->maxUsedClock = p->Clock;
3903                }
3904
3905                p = n;
3906
3907            } while (p != NULL && p != first);
3908        }
3909    }
3910
3911    /* Prune the modes marked as invalid */
3912    xf86PruneDriverModes(pScrn);
3913
3914    if (i == 0 || pScrn->modes == NULL) {
3915        XGIErrorLog(pScrn, "No valid modes found\n");
3916
3917        if (pXGIEnt)
3918            pXGIEnt->ErrorAfterFirst = TRUE;
3919
3920        if (pXGI->pInt)
3921            xf86FreeInt10(pXGI->pInt);
3922        xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
3923        XGIFreeRec(pScrn);
3924        return FALSE;
3925    }
3926
3927    xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
3928
3929    /* Set the current mode to the first in the list */
3930    pScrn->currentMode = pScrn->modes;
3931
3932    /* Copy to CurrentLayout */
3933    pXGI->CurrentLayout.mode = pScrn->currentMode;
3934    pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
3935
3936#ifdef XGIMERGED
3937    if (pXGI->MergedFB) {
3938        xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 1);
3939    }
3940#endif
3941
3942    /* Print the list of modes being used ; call xf86Mode.c-xf86PrintModeline() to print */
3943	ErrorF("Call xf86PrintModes(pScrn) to list all valid modes...\n");
3944    xf86PrintModes(pScrn);
3945
3946#ifdef XGIMERGED
3947    if (pXGI->MergedFB) {
3948        BOOLEAN acceptcustommodes = TRUE;
3949        BOOLEAN includelcdmodes = TRUE;
3950        BOOLEAN isfordvi = FALSE;
3951
3952        xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 2);
3953
3954        clockRanges->next = NULL;
3955        clockRanges->minClock = pXGI->MinClock;
3956        clockRanges->clockIndex = -1;
3957        clockRanges->interlaceAllowed = FALSE;
3958        clockRanges->doubleScanAllowed = FALSE;
3959
3960        xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
3961                   "Min pixel clock for CRT2 is %d MHz\n",
3962                   clockRanges->minClock / 1000);
3963        xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
3964                   "Max pixel clock for CRT2 is %d MHz\n",
3965                   clockRanges->maxClock / 1000);
3966
3967        if ((pXGI->XGI_Pr->
3968             VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)))
3969        {
3970            if (!(pXGI->VBFlags & (CRT2_LCD | CRT2_VGA)))
3971                includelcdmodes = FALSE;
3972            if (pXGI->VBFlags & CRT2_LCD)
3973                isfordvi = TRUE;
3974            if (pXGI->VBFlags & CRT2_TV)
3975                acceptcustommodes = FALSE;
3976        }
3977        else {
3978            includelcdmodes = FALSE;
3979            acceptcustommodes = FALSE;
3980        }
3981    }
3982
3983    if (pXGI->MergedFB) {
3984
3985        pXGI->CheckForCRT2 = TRUE;
3986        i = xf86ValidateModes(pXGI->CRT2pScrn,
3987                              pXGI->CRT2pScrn->monitor->Modes,
3988                              pXGI->CRT2pScrn->display->modes, clockRanges,
3989                              NULL, 256, 4088,
3990                              pXGI->CRT2pScrn->bitsPerPixel * 8, 128, 4096,
3991                              pScrn->display->virtualX ? pScrn->virtualX : 0,
3992                              pScrn->display->virtualY ? pScrn->virtualY : 0,
3993                              pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
3994        pXGI->CheckForCRT2 = FALSE;
3995
3996        if (i == -1) {
3997            XGIErrorLog(pScrn, "xf86ValidateModes() error, %s.\n",
3998                        mergeddisstr);
3999            XGIFreeCRT2Structs(pXGI);
4000            pXGI->MergedFB = FALSE;
4001        }
4002
4003    }
4004
4005    if (pXGI->MergedFB) {
4006
4007        if ((p = first = pXGI->CRT2pScrn->modes)) {
4008            do {
4009                n = p->next;
4010                p = n;
4011            } while (p != NULL && p != first);
4012        }
4013
4014        xf86PruneDriverModes(pXGI->CRT2pScrn);
4015
4016        if (i == 0 || pXGI->CRT2pScrn->modes == NULL) {
4017            XGIErrorLog(pScrn, "No valid modes found for CRT2; %s\n",
4018                        mergeddisstr);
4019            XGIFreeCRT2Structs(pXGI);
4020            pXGI->MergedFB = FALSE;
4021        }
4022
4023    }
4024
4025    if (pXGI->MergedFB) {
4026
4027        xf86SetCrtcForModes(pXGI->CRT2pScrn, INTERLACE_HALVE_V);
4028
4029        xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 2);
4030
4031        xf86PrintModes(pXGI->CRT2pScrn);
4032
4033        pXGI->CRT1Modes = pScrn->modes;
4034        pXGI->CRT1CurrentMode = pScrn->currentMode;
4035
4036        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4037                   "Generating MergedFB mode list\n");
4038
4039        pScrn->modes = XGIGenerateModeList(pScrn, pXGI->MetaModes,
4040                                           pXGI->CRT1Modes,
4041                                           pXGI->CRT2pScrn->modes,
4042                                           pXGI->CRT2Position);
4043
4044        if (!pScrn->modes) {
4045
4046            XGIErrorLog(pScrn,
4047                        "Failed to parse MetaModes or no modes found. %s.\n",
4048                        mergeddisstr);
4049            XGIFreeCRT2Structs(pXGI);
4050            pScrn->modes = pXGI->CRT1Modes;
4051            pXGI->CRT1Modes = NULL;
4052            pXGI->MergedFB = FALSE;
4053
4054        }
4055
4056    }
4057
4058    if (pXGI->MergedFB) {
4059
4060        /* If no virtual dimension was given by the user,
4061         * calculate a sane one now. Adapts pScrn->virtualX,
4062         * pScrn->virtualY and pScrn->displayWidth.
4063         */
4064        XGIRecalcDefaultVirtualSize(pScrn);
4065
4066        pScrn->modes = pScrn->modes->next;      /* We get the last from GenerateModeList(), skip to first */
4067        pScrn->currentMode = pScrn->modes;
4068
4069        /* Update CurrentLayout */
4070        pXGI->CurrentLayout.mode = pScrn->currentMode;
4071        pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
4072
4073    }
4074#endif
4075
4076    /* Set display resolution */
4077#ifdef XGIMERGED
4078    if (pXGI->MergedFB) {
4079        XGIMergedFBSetDpi(pScrn, pXGI->CRT2pScrn, pXGI->CRT2Position);
4080    }
4081    else
4082#endif
4083
4084
4085	/* Jong 07/30/2009; might cause small font size */
4086	xf86SetDpi(pScrn, 0, 0);
4087
4088#if 0
4089	/*yilin@20080407 fix the font too small problem at low resolution*/
4090	if((pScrn->xDpi < 65)||(pScrn->yDpi < 65))
4091	{
4092		  pScrn->xDpi = 75;
4093		  pScrn->yDpi = 75;
4094	}
4095#endif
4096
4097    /* Load fb module */
4098    switch (pScrn->bitsPerPixel) {
4099    case 8:
4100    case 16:
4101    case 24:
4102    case 32:
4103        if (!xf86LoadSubModule(pScrn, "fb")) {
4104            XGIErrorLog(pScrn, "Failed to load fb module");
4105
4106            if (pXGIEnt)
4107                pXGIEnt->ErrorAfterFirst = TRUE;
4108
4109            if (pXGI->pInt)
4110                xf86FreeInt10(pXGI->pInt);
4111            xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
4112            XGIFreeRec(pScrn);
4113            return FALSE;
4114        }
4115        break;
4116    default:
4117        XGIErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n",
4118                    pScrn->bitsPerPixel);
4119
4120        if (pXGIEnt)
4121            pXGIEnt->ErrorAfterFirst = TRUE;
4122
4123        if (pXGI->pInt)
4124            xf86FreeInt10(pXGI->pInt);
4125        xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
4126        XGIFreeRec(pScrn);
4127        return FALSE;
4128    }
4129#if 0
4130    xf86LoaderReqSymLists(fbSymbols, NULL);
4131#endif
4132    /* Load XAA if needed */
4133    if (!pXGI->NoAccel)
4134	{
4135        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n");
4136
4137#ifdef XGI_USE_XAA
4138		if(!(pXGI->useEXA))
4139		{
4140			if (!xf86LoadSubModule(pScrn, "xaa")) {
4141				XGIErrorLog(pScrn, "Could not load xaa module\n");
4142
4143				if (pXGIEnt)
4144					pXGIEnt->ErrorAfterFirst = TRUE;
4145
4146				if (pXGI->pInt)
4147					xf86FreeInt10(pXGI->pInt);
4148				xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
4149				XGIFreeRec(pScrn);
4150				return FALSE;
4151			}
4152#if 0
4153			xf86LoaderReqSymLists(xaaSymbols, NULL);
4154#endif
4155		}
4156#endif
4157
4158#ifdef XGI_USE_EXA
4159		if(pXGI->useEXA)
4160		{
4161		   if(!xf86LoadSubModule(pScrn, "exa")) {
4162			  XGIErrorLog(pScrn, "Could not load exa module\n");
4163			  return FALSE;
4164		   }
4165#if 0
4166		   xf86LoaderReqSymLists(exaSymbols, NULL);
4167#endif
4168		}
4169#endif
4170	}
4171
4172    /* Load shadowfb if needed */
4173    if (pXGI->ShadowFB) {
4174        if (!xf86LoadSubModule(pScrn, "shadowfb")) {
4175            XGIErrorLog(pScrn, "Could not load shadowfb module\n");
4176
4177            if (pXGIEnt)
4178                pXGIEnt->ErrorAfterFirst = TRUE;
4179
4180            if (pXGI->pInt)
4181                xf86FreeInt10(pXGI->pInt);
4182            xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
4183            XGIFreeRec(pScrn);
4184            return FALSE;
4185        }
4186#if 0
4187        xf86LoaderReqSymLists(shadowSymbols, NULL);
4188#endif
4189    }
4190
4191    /* Load the dri module if requested. */
4192#ifdef XF86DRI
4193    if(pXGI->loadDRI) {
4194        if (xf86LoadSubModule(pScrn, "dri")) {
4195#if 0
4196            xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL);
4197#endif
4198        }
4199        else {
4200            if (!IS_DUAL_HEAD(pXGI))
4201                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4202                           "Remove >Load \"dri\"< from the Module section of your XF86Config file\n");
4203        }
4204    }
4205#endif
4206
4207
4208    /* Now load and initialize VBE module for VESA and mode restoring. */
4209    if (pXGI->pVbe) {
4210        vbeFree(pXGI->pVbe);
4211        pXGI->pVbe = NULL;
4212    }
4213
4214#ifdef XGIDUALHEAD
4215    xf86SetPrimInitDone(pScrn->entityList[0]);
4216#endif
4217
4218    xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
4219
4220    if (pXGI->pInt)
4221        xf86FreeInt10(pXGI->pInt);
4222    pXGI->pInt = NULL;
4223
4224    if (IS_DUAL_HEAD(pXGI)) {
4225        pXGI->XGI_SD_Flags |= XGI_SD_ISDUALHEAD;
4226        if (IS_SECOND_HEAD(pXGI))
4227            pXGI->XGI_SD_Flags |= XGI_SD_ISDHSECONDHEAD;
4228        else
4229            pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
4230#ifdef PANORAMIX
4231        if (!noPanoramiXExtension) {
4232            pXGI->XGI_SD_Flags |= XGI_SD_ISDHXINERAMA;
4233            pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
4234        }
4235#endif
4236    }
4237
4238#ifdef XGIMERGED
4239    if (pXGI->MergedFB)
4240        pXGI->XGI_SD_Flags |= XGI_SD_ISMERGEDFB;
4241#endif
4242
4243    if (pXGI->enablexgictrl)
4244        pXGI->XGI_SD_Flags |= XGI_SD_ENABLED;
4245
4246    return TRUE;
4247}
4248
4249
4250/*
4251 * Map the framebuffer and MMIO memory.
4252 */
4253
4254static Bool
4255XGIMapMem(ScrnInfoPtr pScrn)
4256{
4257    XGIPtr pXGI = XGIPTR(pScrn);;
4258
4259#ifdef XSERVER_LIBPCIACCESS
4260    unsigned i;
4261
4262    for (i = 0; i < 2; i++) {
4263        int err;
4264
4265        err = pci_device_map_region(pXGI->PciInfo, i, TRUE);
4266        if (err) {
4267            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4268                       "Internal error: cound not map PCI region %u\n", i);
4269            return FALSE;
4270        }
4271    }
4272
4273    pXGI->FbBase = pXGI->PciInfo->regions[0].memory;
4274    pXGI->IOBase = pXGI->PciInfo->regions[1].memory;
4275#else
4276    int mmioFlags;
4277
4278    /*
4279     * Map IO registers to virtual address space
4280     */
4281#if !defined(__alpha__)
4282    mmioFlags = VIDMEM_MMIO;
4283#else
4284    /*
4285     * For Alpha, we need to map SPARSE memory, since we need
4286     * byte/short access.
4287     */
4288    mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
4289#endif
4290    pXGI->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
4291                                 pXGI->PciTag, pXGI->IOAddress, 0x10000);
4292    if (pXGI->IOBase == NULL)
4293        return FALSE;
4294
4295#ifdef __alpha__
4296    /*
4297     * for Alpha, we need to map DENSE memory as well, for
4298     * setting CPUToScreenColorExpandBase.
4299     */
4300    pXGI->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
4301                                      pXGI->PciTag, pXGI->IOAddress, 0x10000);
4302
4303    if (pXGI->IOBaseDense == NULL)
4304        return FALSE;
4305#endif /* __alpha__ */
4306
4307    pXGI->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
4308                                 pXGI->PciTag,
4309                                 (unsigned long) pXGI->FbAddress,
4310                                 pXGI->FbMapSize);
4311
4312    PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n", (ULONG) (pXGI->FbBase)));
4313
4314    if (pXGI->FbBase == NULL)
4315        return FALSE;
4316#endif
4317
4318    return TRUE;
4319}
4320
4321
4322/*
4323 * Unmap the framebuffer and MMIO memory.
4324 */
4325
4326static Bool
4327XGIUnmapMem(ScrnInfoPtr pScrn)
4328{
4329    XGIPtr pXGI = XGIPTR(pScrn);
4330    XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
4331
4332
4333    /* In dual head mode, we must not unmap if the other head still
4334     * assumes memory as mapped
4335     */
4336    if (IS_DUAL_HEAD(pXGI)) {
4337        if (pXGIEnt->MapCountIOBase) {
4338            pXGIEnt->MapCountIOBase--;
4339            if ((pXGIEnt->MapCountIOBase == 0) || (pXGIEnt->forceUnmapIOBase)) {
4340#ifdef XSERVER_LIBPCIACCESS
4341                pci_device_unmap_region(pXGI->PciInfo, 1);
4342#else
4343                xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->IOBase,
4344                                (pXGI->mmioSize * 1024));
4345#endif
4346                pXGIEnt->IOBase = NULL;
4347                pXGIEnt->MapCountIOBase = 0;
4348                pXGIEnt->forceUnmapIOBase = FALSE;
4349            }
4350            pXGI->IOBase = NULL;
4351        }
4352#ifdef __alpha__
4353#ifdef XSERVER_LIBPCIACCESS
4354#error "How to do dense mapping on Alpha?"
4355#else
4356        if (pXGIEnt->MapCountIOBaseDense) {
4357            pXGIEnt->MapCountIOBaseDense--;
4358            if ((pXGIEnt->MapCountIOBaseDense == 0)
4359                || (pXGIEnt->forceUnmapIOBaseDense)) {
4360                xf86UnMapVidMem(pScrn->scrnIndex,
4361                                (pointer) pXGIEnt->IOBaseDense,
4362                                (pXGI->mmioSize * 1024));
4363                pXGIEnt->IOBaseDense = NULL;
4364                pXGIEnt->MapCountIOBaseDense = 0;
4365                pXGIEnt->forceUnmapIOBaseDense = FALSE;
4366            }
4367            pXGI->IOBaseDense = NULL;
4368        }
4369#endif
4370#endif /* __alpha__ */
4371        if (pXGIEnt->MapCountFbBase) {
4372            pXGIEnt->MapCountFbBase--;
4373            if ((pXGIEnt->MapCountFbBase == 0) || (pXGIEnt->forceUnmapFbBase)) {
4374#ifdef XSERVER_LIBPCIACCESS
4375                pci_device_unmap_region(pXGI->PciInfo, 0);
4376#else
4377                xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->FbBase,
4378                                pXGI->FbMapSize);
4379#endif
4380                pXGIEnt->FbBase = NULL;
4381                pXGIEnt->MapCountFbBase = 0;
4382                pXGIEnt->forceUnmapFbBase = FALSE;
4383
4384            }
4385            pXGI->FbBase = NULL;
4386        }
4387    }
4388    else {
4389#ifdef XSERVER_LIBPCIACCESS
4390        pci_device_unmap_region(pXGI->PciInfo, 0);
4391        pci_device_unmap_region(pXGI->PciInfo, 1);
4392#else
4393        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBase,
4394                        (pXGI->mmioSize * 1024));
4395        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->FbBase,
4396                        pXGI->FbMapSize);
4397#endif
4398        pXGI->IOBase = NULL;
4399        pXGI->FbBase = NULL;
4400
4401#ifdef __alpha__
4402#ifdef XSERVER_LIBPCIACCESS
4403#error "How to do dense mapping on Alpha?"
4404#else
4405        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBaseDense,
4406                        (pXGI->mmioSize * 1024));
4407        pXGI->IOBaseDense = NULL;
4408#endif
4409#endif
4410    }
4411
4412    return TRUE;
4413}
4414
4415/*
4416 * This function saves the video state.
4417 */
4418static void
4419XGISave(ScrnInfoPtr pScrn)
4420{
4421    XGIPtr pXGI;
4422    vgaRegPtr vgaReg;
4423    XGIRegPtr xgiReg;
4424
4425    PDEBUG(ErrorF("XGISave()\n"));
4426
4427    pXGI = XGIPTR(pScrn);
4428
4429    /* We always save master & slave */
4430    if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
4431        return;
4432
4433    vgaReg = &VGAHWPTR(pScrn)->SavedReg;
4434    xgiReg = &pXGI->SavedReg;
4435
4436    vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
4437
4438    xgiSaveUnlockExtRegisterLock(pXGI, &xgiReg->xgiRegs3C4[0x05],
4439                                 &xgiReg->xgiRegs3D4[0x80]);
4440
4441    (*pXGI->XGISave) (pScrn, xgiReg);
4442
4443    /* "Save" these again as they may have been changed prior to XGISave() call */
4444}
4445
4446
4447/*
4448 * Initialise a new mode.  This is currently done using the
4449 * "initialise struct, restore/write struct to HW" model for
4450 * the old chipsets (5597/530/6326). For newer chipsets,
4451 * we use our own mode switching code (or VESA).
4452 */
4453
4454static Bool
4455XGIModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
4456{
4457    vgaHWPtr hwp = VGAHWPTR(pScrn);
4458    vgaRegPtr vgaReg;
4459    XGIPtr pXGI = XGIPTR(pScrn);
4460    XGIRegPtr xgiReg;
4461#ifdef __powerpc__
4462    unsigned char tmpval;
4463#endif
4464
4465    PDEBUG(ErrorF("XGIModeInit\n"));
4466    PDEBUG(ErrorF("mode->HDisplay = %d\n", mode->HDisplay));
4467    PDEBUG(ErrorF("mode->VDisplay = %d\n", mode->VDisplay));
4468
4469	PDEBUG(ErrorF("Before update...\n"));
4470    PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX));
4471    PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY));
4472    PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth));
4473    PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0));
4474    PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0));
4475    PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1));
4476    PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1));
4477
4478	/* pScrn->displayWidth=mode->HDisplay; */
4479
4480	if(pXGI->TargetRefreshRate)
4481			mode->VRefresh = pXGI->TargetRefreshRate;
4482
4483	if((pScrn->monitor->DDC == NULL) && (pXGI->Non_DDC_DefaultMode))
4484	{
4485		mode->HDisplay = pXGI->Non_DDC_DefaultResolutionX;
4486		mode->VDisplay = pXGI->Non_DDC_DefaultResolutionY;
4487		mode->VRefresh = pXGI->Non_DDC_DefaultRefreshRate;
4488	}
4489
4490    /* PDEBUG(ErrorF("XGIModeInit(). \n")); */
4491    PDEBUG(ErrorF
4492           ("XGIModeInit Resolution (%d, %d) \n", mode->HDisplay,
4493            mode->VDisplay));
4494    PDEBUG(ErrorF("XGIModeInit VVRefresh (%8.3f) \n", mode->VRefresh));
4495    PDEBUG(ErrorF("XGIModeInit Color Depth (%d) \n", pScrn->depth));
4496
4497    /* Jong Lin 08-26-2005; save current mode */
4498    Volari_SetDefaultIdleWait(pXGI, mode->HDisplay, pScrn->depth);
4499
4500    andXGIIDXREG(XGICR, 0x11, 0x7f);    /* Unlock CRTC registers */
4501
4502    XGIModifyModeInfo(mode);    /* Quick check of the mode parameters */
4503
4504
4505    if (IS_DUAL_HEAD(pXGI))
4506	{
4507        XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
4508
4509		if (!(*pXGI->ModeInit) (pScrn, mode)) {
4510			XGIErrorLog(pScrn, "ModeInit() failed\n");
4511			return FALSE;
4512		}
4513
4514		pScrn->vtSema = TRUE;
4515
4516		/* Head 2 (slave) is always CRT1 */
4517		XGIPreSetMode(pScrn, mode, XGI_MODE_CRT1);
4518		if (!XGIBIOSSetModeCRT1(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn,
4519					mode))
4520		{
4521			XGIErrorLog(pScrn, "XGIBIOSSetModeCRT1() failed\n");
4522			return FALSE;
4523		}
4524
4525		XGIPostSetMode(pScrn, &pXGI->ModeReg);
4526		XGIAdjustFrame(pXGIEnt->pScrn_1->scrnIndex, pXGIEnt->pScrn_1->frameX0,
4527				   pXGIEnt->pScrn_1->frameY0, 0);
4528    }
4529    else
4530    {
4531		/* For other chipsets, use the old method */
4532
4533		/* Initialise the ModeReg values */
4534		if (!vgaHWInit(pScrn, mode)) {
4535			XGIErrorLog(pScrn, "vgaHWInit() failed\n");
4536			return FALSE;
4537		}
4538
4539		/* Reset our PIOOffset as vgaHWInit might have reset it */
4540		VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
4541#ifdef XSERVER_LIBPCIACCESS
4542        (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
4543#else
4544        (pXGI->PciInfo->ioBase[2] & 0xFFFC)
4545#endif
4546        ;
4547
4548		/* Prepare the register contents */
4549		if (!(*pXGI->ModeInit) (pScrn, mode)) {
4550			XGIErrorLog(pScrn, "ModeInit() failed\n");
4551			return FALSE;
4552		}
4553
4554		pScrn->vtSema = TRUE;
4555
4556		/* Program the registers */
4557		vgaHWProtect(pScrn, TRUE);
4558		vgaReg = &hwp->ModeReg;
4559		xgiReg = &pXGI->ModeReg;
4560
4561		vgaReg->Attribute[0x10] = 0x01;
4562		if (pScrn->bitsPerPixel > 8) {
4563			vgaReg->Graphics[0x05] = 0x00;
4564		}
4565
4566		vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
4567
4568		(*pXGI->XGIRestore) (pScrn, xgiReg);
4569
4570#ifdef TWDEBUG
4571		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4572			   "REAL REGISTER CONTENTS AFTER SETMODE:\n");
4573		(*pXGI->ModeInit) (pScrn, mode);
4574#endif
4575
4576		vgaHWProtect(pScrn, FALSE);
4577    }
4578
4579
4580	if((pXGI->Chipset == PCI_CHIP_XGIXG40)||(pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27))
4581	   {
4582        /* PDEBUG(XGIDumpRegs(pScrn)) ; */
4583        PDEBUG(ErrorF(" *** PreSetMode(). \n"));
4584        XGIPreSetMode(pScrn, mode, XGI_MODE_SIMU);
4585        /* PDEBUG(XGIDumpRegs(pScrn)) ; */
4586        PDEBUG(ErrorF(" *** Start SetMode() \n"));
4587
4588        if (!XGIBIOSSetMode(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn, mode)) {
4589            XGIErrorLog(pScrn, "XGIBIOSSetModeCRT() failed\n");
4590            return FALSE;
4591        }
4592        Volari_EnableAccelerator(pScrn);
4593        /* XGIPostSetMode(pScrn, &pXGI->ModeReg); */
4594        /* outXGIIDXREG(XGISR, 0x20, 0xA1) ; */
4595        /* PDEBUG(XGIDumpRegs(pScrn)) ; */
4596    }
4597
4598    /* Update Currentlayout */
4599    pXGI->CurrentLayout.mode = mode;
4600
4601#ifdef __powerpc__
4602    inXGIIDXREG(XGICR, 0x4D, tmpval);
4603    if (pScrn->depth == 16)
4604        tmpval = (tmpval & 0xE0) | 0x0B;        //word swap
4605    else if (pScrn->depth == 24)
4606        tmpval = (tmpval & 0xE0) | 0x15;        //dword swap
4607    else
4608        tmpval = tmpval & 0xE0; // no swap
4609
4610    outXGIIDXREG(XGICR, 0x4D, tmpval);
4611#endif
4612
4613	XGISetDPMS(pScrn, pXGI->XGI_Pr, &pXGI->xgi_HwDevExt , 0x00000000 );
4614
4615    return TRUE;
4616}
4617
4618
4619/*
4620 * Restore the initial mode. To be used internally only!
4621 */
4622static void
4623XGIRestore(ScrnInfoPtr pScrn)
4624{
4625    XGIPtr pXGI = XGIPTR(pScrn);
4626    XGIRegPtr xgiReg = &pXGI->SavedReg;
4627    vgaHWPtr hwp = VGAHWPTR(pScrn);
4628    vgaRegPtr vgaReg = &hwp->SavedReg;
4629
4630
4631    PDEBUG(ErrorF("XGIRestore():\n"));
4632
4633    /* Wait for the accelerators */
4634#ifdef XGI_USE_XAA
4635    if (!(pXGI->useEXA) && pXGI->AccelInfoPtr) {
4636        (*pXGI->AccelInfoPtr->Sync) (pScrn);
4637    }
4638#endif
4639
4640    vgaHWProtect(pScrn, TRUE);
4641
4642#ifdef UNLOCK_ALWAYS
4643    xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
4644#endif
4645
4646	/* Volari_DisableCmdQueue(pScrn) ; */
4647
4648	/* Volari_Restore() */
4649    (*pXGI->XGIRestore) (pScrn, xgiReg);
4650
4651	pXGI->xgi_HwDevExt.SpecifyTiming = FALSE;
4652
4653	/* Jong 11/14/2007; resolve no display of DVI after leaving VT */
4654	/* But there's no int10 for PPC... */
4655	/* XGIRestorePrevMode(pScrn) ; */
4656	/* works but mode is not exactly right because there're more than one mode 0x03 in table XGI330_SModeIDTable[] */
4657	XGISetModeNew( &pXGI->xgi_HwDevExt, pXGI->XGI_Pr, 0x03);
4658
4659    vgaHWProtect(pScrn, TRUE);
4660    if (pXGI->Primary) {
4661        vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
4662    }
4663
4664    xgiRestoreExtRegisterLock(pXGI, xgiReg->xgiRegs3C4[5],
4665                              xgiReg->xgiRegs3D4[0x80]);
4666    vgaHWProtect(pScrn, FALSE);
4667}
4668
4669
4670/* Our generic BlockHandler for Xv */
4671static void
4672XGIBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
4673{
4674    ScreenPtr pScreen = screenInfo.screens[i];
4675    ScrnInfoPtr pScrn = xf86Screens[i];
4676    XGIPtr pXGI = XGIPTR(pScrn);
4677
4678    pScreen->BlockHandler = pXGI->BlockHandler;
4679    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
4680    pScreen->BlockHandler = XGIBlockHandler;
4681
4682    if (pXGI->VideoTimerCallback) {
4683        (*pXGI->VideoTimerCallback) (pScrn, currentTime.milliseconds);
4684    }
4685
4686    if (pXGI->RenderCallback) {
4687        (*pXGI->RenderCallback) (pScrn);
4688    }
4689}
4690
4691/* Jong@08122009 */
4692int  g_virtualX;
4693int  g_virtualY;
4694int  g_frameX0;
4695int  g_frameY0;
4696int  g_frameX1;
4697int  g_frameY1;
4698
4699void xgiRestoreVirtual(ScrnInfoPtr pScrn)
4700{
4701	pScrn->virtualX = g_virtualX;
4702	pScrn->virtualY = g_virtualY;
4703	pScrn->frameX0 = g_frameX0;
4704	pScrn->frameY0 = g_frameY0;
4705	pScrn->frameX1 = g_frameX1;
4706	pScrn->frameY1 = g_frameY1;
4707}
4708
4709/* Mandatory
4710 * This gets called at the start of each server generation
4711 *
4712 * We use pScrn and not CurrentLayout here, because the
4713 * properties we use have not changed (displayWidth,
4714 * depth, bitsPerPixel)
4715 *
4716 * pScrn->displayWidth : memory pitch
4717 */
4718static Bool
4719XGIScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
4720{
4721    ScrnInfoPtr pScrn;
4722    vgaHWPtr hwp;
4723    XGIPtr pXGI;
4724    int ret;
4725    VisualPtr visual;
4726    unsigned long OnScreenSize;
4727    int height, width, displayWidth;
4728    unsigned char *FBStart;
4729    XGIEntPtr pXGIEnt = NULL;
4730
4731    ErrorF("XGIScreenInit\n");
4732    pScrn = xf86Screens[pScreen->myNum];
4733
4734    PDEBUG(ErrorF("pScrn->currentMode->HDisplay = %d\n", pScrn->currentMode->HDisplay));
4735    PDEBUG(ErrorF("pScrn->currentMode->VDisplay = %d\n", pScrn->currentMode->VDisplay));
4736
4737	PDEBUG(ErrorF("Before update...\n"));
4738    PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX));
4739    PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY));
4740    PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth));
4741    PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0));
4742    PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0));
4743    PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1));
4744    PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1));
4745
4746/* Jong 07/29/2009; fix bug of switch mode */
4747#if 1
4748    /* Jong 08/30/2007; no virtual screen for all cases */
4749    /* Jong 08/22/2007; support modeline */
4750    /* if(g_CountOfUserDefinedModes > 0) */
4751    {
4752		/* Jong@08122009 */
4753		g_virtualX = pScrn->virtualX;
4754		g_virtualY = pScrn->virtualY;
4755		g_frameX0 = pScrn->frameX0;
4756		g_frameY0 = pScrn->frameY0;
4757		g_frameX1 = pScrn->frameX1;
4758		g_frameY1 = pScrn->frameY1;
4759
4760		/*
4761		pScrn->virtualX=pScrn->currentMode->HDisplay;
4762		pScrn->virtualY=pScrn->currentMode->VDisplay;
4763		*/
4764
4765		//pScrn->displayWidth=pScrn->currentMode->HDisplay;
4766
4767		/*
4768		pScrn->frameX0=0;
4769		pScrn->frameY0=0;
4770		pScrn->frameX1=pScrn->currentMode->HDisplay-1;
4771		pScrn->frameY1=pScrn->currentMode->VDisplay-1; */
4772    }
4773#endif
4774
4775    PDEBUG(ErrorF("After update...\n"));
4776    PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX));
4777    PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY));
4778    PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth));
4779    PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0));
4780    PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0));
4781    PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1));
4782    PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1));
4783
4784    hwp = VGAHWPTR(pScrn);
4785
4786    pXGI = XGIPTR(pScrn);
4787
4788#if !defined(__arm__)
4789#if !defined(__powerpc__)
4790    if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
4791        if (xf86LoadSubModule(pScrn, "vbe")) {
4792#if 0
4793            xf86LoaderReqSymLists(vbeSymbols, NULL);
4794#endif
4795            pXGI->pVbe = VBEExtendedInit(NULL, pXGI->pEnt->index,
4796                                         SET_BIOS_SCRATCH |
4797                                         RESTORE_BIOS_SCRATCH);
4798        }
4799        else {
4800            XGIErrorLog(pScrn, "Failed to load VBE submodule\n");
4801        }
4802    }
4803#endif /* if !defined(__powerpc__)  */
4804#endif
4805
4806    if (IS_DUAL_HEAD(pXGI)) {
4807        pXGIEnt = ENTITY_PRIVATE(pXGI);
4808        pXGIEnt->refCount++;
4809    }
4810
4811    /* Map the VGA memory and get the VGA IO base */
4812    if (pXGI->Primary) {
4813        hwp->MapSize = 0x10000; /* Standard 64k VGA window */
4814        if (!vgaHWMapMem(pScrn)) {
4815            XGIErrorLog(pScrn, "Could not map VGA memory window\n");
4816            return FALSE;
4817        }
4818    }
4819    vgaHWGetIOBase(hwp);
4820
4821    /* Patch the PIOOffset inside vgaHW to use
4822     * our relocated IO ports.
4823     */
4824    VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
4825#ifdef XSERVER_LIBPCIACCESS
4826        (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
4827#else
4828        (pXGI->PciInfo->ioBase[2] & 0xFFFC)
4829#endif
4830        ;
4831
4832    /* Map the XGI memory and MMIO areas */
4833    if (!XGIMapMem(pScrn)) {
4834        XGIErrorLog(pScrn, "XGIMapMem() failed\n");
4835        return FALSE;
4836    }
4837
4838#ifdef UNLOCK_ALWAYS
4839    xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
4840#endif
4841
4842    /* Save the current state */
4843    XGISave(pScrn);
4844
4845
4846    PDEBUG(ErrorF("--- ScreenInit ---  \n"));
4847    PDEBUG(XGIDumpRegs(pScrn));
4848
4849    /* Initialise the first mode */
4850    if (!XGIModeInit(pScrn, pScrn->currentMode)) {
4851        XGIErrorLog(pScrn, "XGIModeInit() failed\n");
4852        return FALSE;
4853    }
4854
4855	/* Jong@08122009; still at virtual */
4856	/* xgiRestoreVirtual(); */
4857
4858    PDEBUG(ErrorF("--- XGIModeInit ---  \n"));
4859    PDEBUG(XGIDumpRegs(pScrn));
4860
4861    /* Darken the screen for aesthetic reasons */
4862    /* Not using Dual Head variant on purpose; we darken
4863     * the screen for both displays, and un-darken
4864     * it when the second head is finished
4865     */
4866    XGISaveScreen(pScreen, SCREEN_SAVER_ON);
4867
4868    /* Set the viewport */
4869    XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
4870    /* XGIAdjustFrame(scrnIndex, 0, 0, 0); */
4871
4872	/* xgiRestoreVirtual(pScrn); */
4873
4874    /*
4875     * The next step is to setup the screen's visuals, and initialise the
4876     * framebuffer code.  In cases where the framebuffer's default
4877     * choices for things like visual layouts and bits per RGB are OK,
4878     * this may be as simple as calling the framebuffer's ScreenInit()
4879     * function.  If not, the visuals will need to be setup before calling
4880     * a fb ScreenInit() function and fixed up after.
4881     *
4882     * For most PC hardware at depths >= 8, the defaults that cfb uses
4883     * are not appropriate.  In this driver, we fixup the visuals after.
4884     */
4885
4886    /*
4887     * Reset visual list.
4888     */
4889    miClearVisualTypes();
4890
4891    /* Setup the visuals we support. */
4892
4893    /*
4894     * For bpp > 8, the default visuals are not acceptable because we only
4895     * support TrueColor and not DirectColor.
4896     */
4897    if (!miSetVisualTypes(pScrn->depth,
4898                          (pScrn->bitsPerPixel > 8) ?
4899                          TrueColorMask : miGetDefaultVisualMask(pScrn->
4900                                                                 depth),
4901                          pScrn->rgbBits, pScrn->defaultVisual)) {
4902        XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
4903        XGIErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n",
4904                    pScrn->bitsPerPixel);
4905        return FALSE;
4906    }
4907
4908	/*xgiRestoreVirtual(pScrn); */
4909
4910#if 0
4911	ErrorF("Use Virtual Size - *1\n");
4912    width = pScrn->virtualX;
4913    height = pScrn->virtualY;
4914    displayWidth = pScrn->displayWidth;
4915#endif
4916
4917    if (pXGI->Rotate) {
4918        height = pScrn->virtualX;
4919        width = pScrn->virtualY;
4920    }
4921
4922    if (pXGI->ShadowFB) {
4923        pXGI->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
4924        pXGI->ShadowPtr = xalloc(pXGI->ShadowPitch * height);
4925        displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3);
4926        FBStart = pXGI->ShadowPtr;
4927    }
4928    else {
4929        pXGI->ShadowPtr = NULL;
4930        FBStart = pXGI->FbBase;
4931    }
4932
4933    if (!miSetPixmapDepths()) {
4934        XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
4935        XGIErrorLog(pScrn, "miSetPixmapDepths() failed\n");
4936        return FALSE;
4937    }
4938
4939    /* Point cmdQueuePtr to pXGIEnt for shared usage
4940     * (same technique is then eventually used in DRIScreeninit).
4941     */
4942    if (IS_SECOND_HEAD(pXGI))
4943        pXGI->cmdQueueLenPtr = &(XGIPTR(pXGIEnt->pScrn_1)->cmdQueueLen);
4944    else
4945        pXGI->cmdQueueLenPtr = &(pXGI->cmdQueueLen);
4946
4947    pXGI->cmdQueueLen = 0;      /* Force an EngineIdle() at start */
4948
4949#ifdef XF86DRI
4950    if(pXGI->loadDRI) {
4951        /* No DRI in dual head mode */
4952        if (IS_DUAL_HEAD(pXGI)) {
4953            pXGI->directRenderingEnabled = FALSE;
4954            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4955                       "DRI not supported in Dual Head mode\n");
4956        }
4957        else if ((pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27)) {
4958            PDEBUG(ErrorF("--- DRI not supported   \n"));
4959            xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED,
4960                       "DRI not supported on this chipset\n");
4961            pXGI->directRenderingEnabled = FALSE;
4962        }
4963        else {
4964            pXGI->directRenderingEnabled = XGIDRIScreenInit(pScreen);
4965            PDEBUG(ErrorF("--- DRI supported   \n"));
4966        }
4967    }
4968#endif
4969
4970	/* xgiRestoreVirtual(pScrn); */
4971
4972    /*
4973     * Call the framebuffer layer's ScreenInit function, and fill in other
4974     * pScreen fields.
4975     */
4976    switch (pScrn->bitsPerPixel) {
4977    case 24:
4978    case 8:
4979    case 16:
4980    case 32:
4981
4982/* Jong 07/30/2009; fix bug of small font */
4983#if 1
4984		PDEBUG(ErrorF("Use Virtual Size - *1\n"));
4985		width = /* pScrn->virtualX; */ pScrn->currentMode->HDisplay;
4986		height = /* pScrn->virtualY;*/ pScrn->currentMode->VDisplay;
4987
4988		/* Jong@10022009 */
4989		displayWidth = pScrn->displayWidth; /* important to set pitch correctly */
4990#endif
4991		PDEBUG(ErrorF("Call fbScreenInit()...\n"));
4992		PDEBUG(ErrorF("width=%d, height=%d, pScrn->xDpi=%d, pScrn->yDpi=%d, displayWidth=%d, pScrn->bitsPerPixel=%d...\n",
4993					width, height, pScrn->xDpi, pScrn->yDpi,displayWidth, pScrn->bitsPerPixel));
4994
4995		/* in fbscreen.c */
4996		/* (xsize, ysize) : virtual size (1600, 1200)
4997		   (dpix, dpiy) : (75, 75)
4998		   (542) pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
4999		   (406) pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10); */
5000
5001        /* ret = fbScreenInit(pScreen, FBStart, width, */
5002        ret = fbScreenInit(pScreen, FBStart , width,
5003                           height, pScrn->xDpi, pScrn->yDpi,
5004                           displayWidth, pScrn->bitsPerPixel);
5005
5006		/* Jong 07/30/2009; bug fixing for small font size */
5007		pScreen->mmWidth = (pScrn->currentMode->HDisplay * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10);
5008		pScreen->mmHeight = (pScrn->currentMode->VDisplay * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10);
5009
5010	    PDEBUG(ErrorF("pScrn->xDpi = %d\n", pScrn->xDpi));
5011		PDEBUG(ErrorF("pScrn->yDpi = %d\n", pScrn->yDpi));
5012	    PDEBUG(ErrorF("pScreen->mmWidth = %d\n", pScreen->mmWidth));
5013		PDEBUG(ErrorF("pScreen->mmHeight = %d\n", pScreen->mmHeight));
5014
5015        break;
5016    default:
5017        ret = FALSE;
5018        break;
5019    }
5020
5021	xgiRestoreVirtual(pScrn);
5022
5023    if (!ret) {
5024        XGIErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n",
5025                    pScrn->bitsPerPixel);
5026        XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
5027        return FALSE;
5028    }
5029
5030    if (pScrn->bitsPerPixel > 8) {
5031        /* Fixup RGB ordering */
5032        visual = pScreen->visuals + pScreen->numVisuals;
5033        while (--visual >= pScreen->visuals) {
5034            if ((visual->class | DynamicClass) == DirectColor) {
5035                visual->offsetRed = pScrn->offset.red;
5036                visual->offsetGreen = pScrn->offset.green;
5037                visual->offsetBlue = pScrn->offset.blue;
5038                visual->redMask = pScrn->mask.red;
5039                visual->greenMask = pScrn->mask.green;
5040                visual->blueMask = pScrn->mask.blue;
5041            }
5042        }
5043    }
5044
5045	/* xgiRestoreVirtual(pScrn); */
5046
5047    /* Initialize RENDER ext; must be after RGB ordering fixed */
5048    fbPictureInit(pScreen, 0, 0);
5049
5050	/* xgiRestoreVirtual(pScrn); */
5051
5052    /* hardware cursor needs to wrap this layer    <-- TW: what does that mean? */
5053    if (!pXGI->ShadowFB)
5054        XGIDGAInit(pScreen);
5055
5056    xf86SetBlackWhitePixels(pScreen);
5057
5058    if (!pXGI->NoAccel) {
5059        /* Volari_EnableAccelerator(pScrn); */
5060        PDEBUG(ErrorF("---Volari Accel..  \n"));
5061        Volari_AccelInit(pScreen);
5062    }
5063
5064    PDEBUG(ErrorF("--- AccelInit ---  \n"));
5065    PDEBUG(XGIDumpRegs(pScrn));
5066
5067    miInitializeBackingStore(pScreen);
5068    xf86SetBackingStore(pScreen);
5069    xf86SetSilkenMouse(pScreen);
5070
5071    /* Initialise cursor functions */
5072    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
5073
5074    if (pXGI->HWCursor) {
5075        XGIHWCursorInit(pScreen);
5076    }
5077
5078    /* Initialise default colourmap */
5079    if (!miCreateDefColormap(pScreen)) {
5080        XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
5081        XGIErrorLog(pScrn, "miCreateDefColormap() failed\n");
5082        return FALSE;
5083    }
5084    if (!xf86HandleColormaps
5085        (pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
5086         XGILoadPalette, NULL,
5087         CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
5088        PDEBUG(ErrorF("XGILoadPalette() check-return.  \n"));
5089        XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
5090        XGIErrorLog(pScrn, "xf86HandleColormaps() failed\n");
5091        return FALSE;
5092    }
5093
5094/*
5095    if (!xf86HandleColormaps(pScreen, 256, 8, XGILoadPalette, NULL,
5096                             CMAP_RELOAD_ON_MODE_SWITCH))
5097    {
5098        return FALSE;
5099    }
5100*/
5101    xf86DPMSInit(pScreen, (DPMSSetProcPtr) XGIDisplayPowerManagementSet, 0);
5102
5103    /* Init memPhysBase and fbOffset in pScrn */
5104    pScrn->memPhysBase = pXGI->FbAddress;
5105    pScrn->fbOffset = 0;
5106
5107    pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
5108
5109#if defined(XvExtension)
5110    if (!pXGI->NoXvideo) {
5111        XGIInitVideo(pScreen);
5112    }
5113#endif
5114
5115#ifdef XF86DRI
5116    if (pXGI->directRenderingEnabled) {
5117	/* Now that mi, drm and others have done their thing,
5118	 * complete the DRI setup.
5119	 */
5120	pXGI->directRenderingEnabled = XGIDRIFinishScreenInit(pScreen);
5121    }
5122
5123    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering %sabled\n",
5124	       (pXGI->directRenderingEnabled) ? "en" : "dis");
5125    if (pXGI->directRenderingEnabled) {
5126	/* TODO */
5127	/* XGISetLFBConfig(pXGI); */
5128    }
5129#endif
5130
5131    /* Wrap some funcs and setup remaining SD flags */
5132
5133    pXGI->XGI_SD_Flags &= ~(XGI_SD_PSEUDOXINERAMA);
5134
5135    pXGI->CloseScreen = pScreen->CloseScreen;
5136    pScreen->CloseScreen = XGICloseScreen;
5137    if (IS_DUAL_HEAD(pXGI))
5138        pScreen->SaveScreen = XGISaveScreenDH;
5139    else
5140        pScreen->SaveScreen = XGISaveScreen;
5141
5142    /* Install BlockHandler */
5143    pXGI->BlockHandler = pScreen->BlockHandler;
5144    pScreen->BlockHandler = XGIBlockHandler;
5145
5146    /* Report any unused options (only for the first generation) */
5147    if (serverGeneration == 1) {
5148        xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
5149    }
5150
5151    /* Clear frame buffer */
5152    /* For CRT2, we don't do that at this point in dual head
5153     * mode since the mode isn't switched at this time (it will
5154     * be reset when setting the CRT1 mode). Hence, we just
5155     * save the necessary data and clear the screen when
5156     * going through this for CRT1.
5157     */
5158
5159    OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
5160        * (pScrn->bitsPerPixel >> 3);
5161
5162    /* Turn on the screen now */
5163    /* We do this in dual head mode after second head is finished */
5164    if (IS_DUAL_HEAD(pXGI)) {
5165        if (IS_SECOND_HEAD(pXGI)) {
5166            bzero(pXGI->FbBase, OnScreenSize);
5167            bzero(pXGIEnt->FbBase1, pXGIEnt->OnScreenSize1);
5168            XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
5169        }
5170        else {
5171            pXGIEnt->FbBase1 = pXGI->FbBase;
5172            pXGIEnt->OnScreenSize1 = OnScreenSize;
5173        }
5174    }
5175    else {
5176        XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
5177        bzero(pXGI->FbBase, OnScreenSize);
5178    }
5179
5180    pXGI->XGI_SD_Flags &= ~XGI_SD_ISDEPTH8;
5181    if (pXGI->CurrentLayout.bitsPerPixel == 8) {
5182        pXGI->XGI_SD_Flags |= XGI_SD_ISDEPTH8;
5183        pXGI->XGI_SD_Flags &= ~XGI_SD_SUPPORTXVGAMMA1;
5184    }
5185
5186    PDEBUG(ErrorF("XGIScreenInit() End.  \n"));
5187    PDEBUG(XGIDumpPalette(pScrn));
5188	PDEBUG(XGIDumpRegs(pScrn));
5189
5190	/* xgiRestoreVirtual(); */
5191    XGIAdjustFrame(scrnIndex, 0, 0, 0);
5192	pScrn->frameX0 = 0;
5193	pScrn->frameY0 = 0;
5194	pScrn->frameX1 = pScrn->currentMode->HDisplay - 1 ;
5195	pScrn->frameY1 = pScrn->currentMode->VDisplay - 1;
5196
5197    return TRUE;
5198}
5199
5200/* Usually mandatory */
5201Bool
5202XGISwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
5203{
5204    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
5205    XGIPtr pXGI = XGIPTR(pScrn);
5206
5207	if(pXGI->TargetRefreshRate)
5208			mode->VRefresh = pXGI->TargetRefreshRate;
5209
5210    PDEBUG(ErrorF("XGISwitchMode\n"));
5211    PDEBUG(ErrorF("mode->HDisplay = %d\n", mode->HDisplay));
5212    PDEBUG(ErrorF("mode->VDisplay = %d\n", mode->VDisplay));
5213
5214	PDEBUG(ErrorF("Before update...\n"));
5215    PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX));
5216    PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY));
5217    PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth));
5218    PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0));
5219    PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0));
5220    PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1));
5221    PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1));
5222
5223    PDEBUG(ErrorF("pScrn->xDpi = %d\n", pScrn->xDpi));
5224	PDEBUG(ErrorF("pScrn->yDpi = %d\n", pScrn->yDpi));
5225	PDEBUG(ErrorF("pScreen->mmWidth = %d\n", pScrn->pScreen->mmWidth));
5226    PDEBUG(ErrorF("pScreen->mmHeight = %d\n", pScrn->pScreen->mmHeight));
5227
5228	/* Jong@08122009 */
5229	//pScrn->frameX0 = 0;
5230	//pScrn->frameY0 = 0;
5231	//pScrn->frameX1 = mode->HDisplay;
5232	//pScrn->frameY1 = mode->VDisplay;
5233
5234    if (!pXGI->NoAccel) {
5235#ifdef XGI_USE_XAA
5236        if (!(pXGI->useEXA) && pXGI->AccelInfoPtr) {
5237            (*pXGI->AccelInfoPtr->Sync) (pScrn);
5238            PDEBUG(ErrorF("XGISwitchMode Accel Enabled. \n"));
5239        }
5240#endif
5241    }
5242
5243    PDEBUG(ErrorF
5244           ("XGISwitchMode (%d, %d) \n", mode->HDisplay, mode->VDisplay));
5245
5246#if 1
5247    /* Jong 07/29/2009; Set the viewport; still not working */
5248    XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
5249#endif
5250
5251    if (!(XGIModeInit(xf86Screens[scrnIndex], mode)))
5252        return FALSE;
5253
5254
5255#if 0
5256    int height, width, displayWidth;
5257    unsigned char *FBStart;
5258	int ret;
5259
5260    if (pXGI->ShadowFB) {
5261        displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3);
5262        FBStart = pXGI->ShadowPtr;
5263    }
5264    else {
5265        pXGI->ShadowPtr = NULL;
5266        FBStart = pXGI->FbBase;
5267    }
5268
5269	width = pScrn->virtualX; /* 1024; */ /* pScrn->currentMode->HDisplay; */
5270	height = pScrn->virtualY; /* 768; */ /* pScrn->currentMode->VDisplay; */
5271	displayWidth = pScrn->displayWidth; /* important to set pitch correctly */
5272
5273	ErrorF("Call fbScreenInit()...\n");
5274	ErrorF("width=%d, height=%d, pScrn->xDpi=%d, pScrn->yDpi=%d, displayWidth=%d, pScrn->bitsPerPixel=%d...\n",
5275				width, height, pScrn->xDpi, pScrn->yDpi,displayWidth, pScrn->bitsPerPixel);
5276
5277	/* in fbscreen.c */
5278	/* (xsize, ysize) : virtual size (1600, 1200)
5279	   (dpix, dpiy) : (75, 75)
5280	   (542) pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
5281	   (406) pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10); */
5282
5283    ret = fbScreenInit(pScrn->pScreen, FBStart, width,
5284                       height, pScrn->xDpi, pScrn->yDpi,
5285                       displayWidth, pScrn->bitsPerPixel);
5286#endif
5287
5288	/* Jong 07/30/2009; bug fixing for small font size */
5289	pScrn->pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10);
5290	pScrn->pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10);
5291
5292#if 0
5293    /* Jong 08/30/2007; no virtual screen for all cases */
5294    /* Jong 08/22/2007; support modeline */
5295    /* if(g_CountOfUserDefinedModes > 0) */
5296    {
5297
5298		pScrn->virtualX=mode->HDisplay;
5299		pScrn->virtualY=mode->VDisplay;
5300
5301		pScrn->displayWidth=mode->HDisplay;
5302		pScrn->frameX0=0;
5303		pScrn->frameY0=0;
5304		pScrn->frameX1=mode->HDisplay-1;
5305		pScrn->frameY1=mode->VDisplay-1;
5306    }
5307#endif
5308
5309	PDEBUG(ErrorF("After update...\n"));
5310    PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX));
5311    PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY));
5312    PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth));
5313    PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0));
5314    PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0));
5315    PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1));
5316    PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1));
5317
5318    PDEBUG(ErrorF("pScrn->xDpi = %d\n", pScrn->xDpi));
5319	PDEBUG(ErrorF("pScrn->yDpi = %d\n", pScrn->yDpi));
5320	PDEBUG(ErrorF("pScreen->mmWidth = %d\n", pScrn->pScreen->mmWidth));
5321    PDEBUG(ErrorF("pScreen->mmHeight = %d\n", pScrn->pScreen->mmHeight));
5322
5323    /* Since RandR (indirectly) uses SwitchMode(), we need to
5324     * update our Xinerama info here, too, in case of resizing
5325     */
5326
5327	/* sleep(3); */ /* Jong 07/30/2009; wait to be ready for drawing */;
5328
5329    return TRUE;
5330}
5331
5332/* static void
5333XGISetStartAddressCRT1(XGIPtr pXGI, unsigned long base)
5334{
5335    unsigned char cr11backup;
5336
5337    inXGIIDXREG(XGICR,  0x11, cr11backup);
5338    andXGIIDXREG(XGICR, 0x11, 0x7F);
5339    outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
5340    outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
5341    outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
5342
5343
5344    setXGIIDXREG(XGICR, 0x11, 0x7F,(cr11backup & 0x80));
5345} */
5346
5347#ifdef XGIMERGED
5348/* static Bool
5349InRegion(int x, int y, region r)
5350{
5351    return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
5352} */
5353
5354/* static void
5355XGIAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y)
5356{
5357    XGIPtr pXGI = XGIPTR(pScrn);
5358    unsigned long base;
5359
5360    base = y * pXGI->CurrentLayout.displayWidth + x;
5361    switch(pXGI->CurrentLayout.bitsPerPixel)
5362    {
5363       case 16:  base >>= 1; 	break;
5364       case 32:  		break;
5365       default:  base >>= 2;
5366    }
5367    XGISetStartAddressCRT1(pXGI, base);
5368} */
5369
5370/* static void
5371XGIMergePointerMoved(int scrnIndex, int x, int y)
5372{
5373  ScrnInfoPtr   pScrn1 = xf86Screens[scrnIndex];
5374  XGIPtr        pXGI = XGIPTR(pScrn1);
5375  ScrnInfoPtr   pScrn2 = pXGI->CRT2pScrn;
5376  region 	out, in1, in2, f2, f1;
5377  int 		deltax, deltay;
5378
5379  f1.x0 = pXGI->CRT1frameX0;
5380  f1.x1 = pXGI->CRT1frameX1;
5381  f1.y0 = pXGI->CRT1frameY0;
5382  f1.y1 = pXGI->CRT1frameY1;
5383  f2.x0 = pScrn2->frameX0;
5384  f2.x1 = pScrn2->frameX1;
5385  f2.y0 = pScrn2->frameY0;
5386  f2.y1 = pScrn2->frameY1;
5387
5388  out.x0 = pScrn1->frameX0;
5389  out.x1 = pScrn1->frameX1;
5390  out.y0 = pScrn1->frameY0;
5391  out.y1 = pScrn1->frameY1;
5392
5393  in1 = out;
5394  in2 = out;
5395  switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
5396  {
5397     case xgiLeftOf:
5398        in1.x0 = f1.x0;
5399        in2.x1 = f2.x1;
5400        break;
5401     case xgiRightOf:
5402        in1.x1 = f1.x1;
5403        in2.x0 = f2.x0;
5404        break;
5405     case xgiBelow:
5406        in1.y1 = f1.y1;
5407        in2.y0 = f2.y0;
5408        break;
5409     case xgiAbove:
5410        in1.y0 = f1.y0;
5411        in2.y1 = f2.y1;
5412        break;
5413     case xgiClone:
5414        break;
5415  }
5416
5417  deltay = 0;
5418  deltax = 0;
5419
5420  if(InRegion(x, y, out))
5421  {
5422
5423     if(InRegion(x, y, in1) && !InRegion(x, y, f1))
5424     {
5425        REBOUND(f1.x0, f1.x1, x);
5426        REBOUND(f1.y0, f1.y1, y);
5427        deltax = 1;
5428     }
5429     if(InRegion(x, y, in2) && !InRegion(x, y, f2))
5430     {
5431        REBOUND(f2.x0, f2.x1, x);
5432        REBOUND(f2.y0, f2.y1, y);
5433        deltax = 1;
5434     }
5435
5436  }
5437  else
5438  {
5439
5440     if(out.x0 > x)
5441     {
5442        deltax = x - out.x0;
5443     }
5444     if(out.x1 < x)
5445     {
5446        deltax = x - out.x1;
5447     }
5448     if(deltax)
5449     {
5450        pScrn1->frameX0 += deltax;
5451        pScrn1->frameX1 += deltax;
5452    f1.x0 += deltax;
5453        f1.x1 += deltax;
5454        f2.x0 += deltax;
5455        f2.x1 += deltax;
5456     }
5457
5458     if(out.y0 > y)
5459     {
5460        deltay = y - out.y0;
5461     }
5462     if(out.y1 < y)
5463     {
5464        deltay = y - out.y1;
5465     }
5466     if(deltay)
5467     {
5468        pScrn1->frameY0 += deltay;
5469        pScrn1->frameY1 += deltay;
5470    f1.y0 += deltay;
5471        f1.y1 += deltay;
5472        f2.y0 += deltay;
5473        f2.y1 += deltay;
5474     }
5475
5476     switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
5477     {
5478        case xgiLeftOf:
5479       if(x >= f1.x0)
5480       { REBOUND(f1.y0, f1.y1, y); }
5481       if(x <= f2.x1)
5482       { REBOUND(f2.y0, f2.y1, y); }
5483           break;
5484        case xgiRightOf:
5485       if(x <= f1.x1)
5486       { REBOUND(f1.y0, f1.y1, y); }
5487       if(x >= f2.x0)
5488       { REBOUND(f2.y0, f2.y1, y); }
5489           break;
5490        case xgiBelow:
5491       if(y <= f1.y1)
5492       { REBOUND(f1.x0, f1.x1, x); }
5493       if(y >= f2.y0)
5494       { REBOUND(f2.x0, f2.x1, x); }
5495           break;
5496        case xgiAbove:
5497       if(y >= f1.y0)
5498       { REBOUND(f1.x0, f1.x1, x); }
5499       if(y <= f2.y1)
5500       { REBOUND(f2.x0, f2.x1, x); }
5501           break;
5502        case xgiClone:
5503           break;
5504     }
5505
5506  }
5507
5508  if(deltax || deltay)
5509  {
5510     pXGI->CRT1frameX0 = f1.x0;
5511     pXGI->CRT1frameY0 = f1.y0;
5512     pScrn2->frameX0 = f2.x0;
5513     pScrn2->frameY0 = f2.y0;
5514
5515     pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
5516     pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
5517     pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR->CRT2->HDisplay - 1;
5518     pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR->CRT2->VDisplay - 1;
5519     pScrn1->frameX1   = pScrn1->frameX0   + pXGI->CurrentLayout.mode->HDisplay  - 1;
5520     pScrn1->frameY1   = pScrn1->frameY0   + pXGI->CurrentLayout.mode->VDisplay  - 1;
5521
5522     XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
5523  }
5524}  */
5525
5526
5527/* static void
5528XGIAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
5529{
5530    ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
5531    XGIPtr pXGI = XGIPTR(pScrn1);
5532    ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
5533    int VTotal = pXGI->CurrentLayout.mode->VDisplay;
5534    int HTotal = pXGI->CurrentLayout.mode->HDisplay;
5535    int VMax = VTotal;
5536    int HMax = HTotal;
5537
5538    BOUND(x, 0, pScrn1->virtualX - HTotal);
5539    BOUND(y, 0, pScrn1->virtualY - VTotal);
5540
5541    switch(SDMPTR(pScrn1)->CRT2Position)
5542    {
5543        case xgiLeftOf:
5544            pScrn2->frameX0 = x;
5545            BOUND(pScrn2->frameY0,   y, y + VMax - CDMPTR->CRT2->VDisplay);
5546            pXGI->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay;
5547            BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
5548            break;
5549        case xgiRightOf:
5550            pXGI->CRT1frameX0 = x;
5551            BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
5552            pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay;
5553            BOUND(pScrn2->frameY0,   y, y + VMax - CDMPTR->CRT2->VDisplay);
5554            break;
5555        case xgiAbove:
5556            BOUND(pScrn2->frameX0,   x, x + HMax - CDMPTR->CRT2->HDisplay);
5557            pScrn2->frameY0 = y;
5558            BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
5559            pXGI->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay;
5560            break;
5561        case xgiBelow:
5562            BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
5563            pXGI->CRT1frameY0 = y;
5564            BOUND(pScrn2->frameX0,   x, x + HMax - CDMPTR->CRT2->HDisplay);
5565            pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay;
5566            break;
5567        case xgiClone:
5568            BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
5569            BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
5570            BOUND(pScrn2->frameX0,   x, x + HMax - CDMPTR->CRT2->HDisplay);
5571            BOUND(pScrn2->frameY0,   y, y + VMax - CDMPTR->CRT2->VDisplay);
5572            break;
5573    }
5574
5575    BOUND(pXGI->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
5576    BOUND(pXGI->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
5577    BOUND(pScrn2->frameX0,   0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
5578    BOUND(pScrn2->frameY0,   0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
5579
5580    pScrn1->frameX0 = x;
5581    pScrn1->frameY0 = y;
5582
5583    pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
5584    pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
5585    pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR->CRT2->HDisplay - 1;
5586    pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR->CRT2->VDisplay - 1;
5587    pScrn1->frameX1   = pScrn1->frameX0   + pXGI->CurrentLayout.mode->HDisplay  - 1;
5588    pScrn1->frameY1   = pScrn1->frameY0   + pXGI->CurrentLayout.mode->VDisplay  - 1;
5589
5590    XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
5591} */
5592#endif
5593
5594/*
5595 * This function is used to initialize the Start Address - the first
5596 * displayed location in the video memory.
5597 *
5598 * Usually mandatory
5599 */
5600void
5601XGIAdjustFrame(int scrnIndex, int x, int y, int flags)
5602{
5603    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
5604    XGIPtr pXGI = XGIPTR(pScrn);
5605    unsigned long base;
5606    unsigned char ucSR5Stat, ucTemp;
5607
5608    ErrorF("AdjustFrame %d\n", scrnIndex);
5609    inXGIIDXREG(XGISR, 0x05, ucSR5Stat);
5610    if (ucSR5Stat == 0xA1)
5611        ucSR5Stat = 0x86;
5612    outXGIIDXREG(XGISR, 0x05, 0x86);
5613
5614    base = (pScrn->bitsPerPixel + 7) / 8;
5615    base *= x;
5616    base += pXGI->scrnOffset * y;
5617    base >>= 2;
5618
5619    switch (pXGI->Chipset) {
5620    case PCI_CHIP_XGIXG40:
5621    case PCI_CHIP_XGIXG20:
5622    case PCI_CHIP_XGIXG21:
5623    case PCI_CHIP_XGIXG27:
5624    default:
5625
5626        ucTemp = base & 0xFF;
5627        outXGIIDXREG(XGICR, 0x0D, ucTemp);
5628        ucTemp = (base >> 8) & 0xFF;
5629        outXGIIDXREG(XGICR, 0x0C, ucTemp);
5630        ucTemp = (base >> 16) & 0xFF;
5631        outXGIIDXREG(XGISR, 0x0D, ucTemp);
5632        ucTemp = (base >> 24) & 0x01;
5633        setXGIIDXREG(XGISR, 0x37, 0xFE, ucTemp);
5634
5635/*        if (pXGI->VBFlags)  {
5636            XGI_UnLockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
5637            ucTemp = base & 0xFF       ; outXGIIDXREG( XGIPART1, 6 , ucTemp ) ;
5638            ucTemp = (base>>8) & 0xFF  ; outXGIIDXREG( XGIPART1, 5 , ucTemp ) ;
5639            ucTemp = (base>>16) & 0xFF ; outXGIIDXREG( XGIPART1, 4 , ucTemp ) ;
5640            ucTemp = (base>>24) & 0x01 ; ucTemp <<= 7 ;
5641            setXGIIDXREG( XGIPART1, 0x2, 0x7F, ucTemp ) ;
5642
5643            XGI_LockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
5644        }
5645        */
5646        break;
5647
5648    }
5649
5650    outXGIIDXREG(XGISR, 0x05, ucSR5Stat);
5651
5652}
5653
5654/*
5655 * This is called when VT switching back to the X server.  Its job is
5656 * to reinitialise the video mode.
5657 * Mandatory!
5658 */
5659static Bool
5660XGIEnterVT(int scrnIndex, int flags)
5661{
5662    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
5663    XGIPtr pXGI = XGIPTR(pScrn);
5664
5665    xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
5666
5667    if (!XGIModeInit(pScrn, pScrn->currentMode)) {
5668        XGIErrorLog(pScrn, "XGIEnterVT: XGIModeInit() failed\n");
5669        return FALSE;
5670    }
5671
5672    XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
5673
5674#ifdef XF86DRI
5675    if (pXGI->directRenderingEnabled) {
5676        DRIUnlock(screenInfo.screens[scrnIndex]);
5677    }
5678#endif
5679
5680    if ((!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) && (pXGI->ResetXv)) {
5681        (pXGI->ResetXv) (pScrn);
5682    }
5683
5684    return TRUE;
5685}
5686
5687/*
5688 * This is called when VT switching away from the X server.  Its job is
5689 * to restore the previous (text) mode.
5690 * Mandatory!
5691 */
5692static void
5693XGILeaveVT(int scrnIndex, int flags)
5694{
5695    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
5696    vgaHWPtr hwp = VGAHWPTR(pScrn);
5697    XGIPtr pXGI = XGIPTR(pScrn);
5698#ifdef XF86DRI
5699    ScreenPtr pScreen;
5700
5701    PDEBUG(ErrorF("XGILeaveVT()\n"));
5702    if (pXGI->directRenderingEnabled) {
5703        pScreen = screenInfo.screens[scrnIndex];
5704        DRILock(pScreen, 0);
5705    }
5706#endif
5707
5708    if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
5709        return;
5710
5711    if (pXGI->CursorInfoPtr) {
5712        /* Because of the test and return above, we know that this is not
5713         * the second head.
5714         */
5715        pXGI->CursorInfoPtr->HideCursor(pScrn);
5716        XGI_WaitBeginRetrace(pXGI->RelIO);
5717    }
5718
5719    XGIRestore(pScrn);
5720
5721
5722    /* We use (otherwise unused) bit 7 to indicate that we are running to keep
5723     * xgifb to change the displaymode (this would result in lethal display
5724     * corruption upon quitting X or changing to a VT until a reboot).
5725     */
5726    vgaHWLock(hwp);
5727}
5728
5729
5730/*
5731 * This is called at the end of each server generation.  It restores the
5732 * original (text) mode.  It should really also unmap the video memory too.
5733 * Mandatory!
5734 */
5735static Bool
5736XGICloseScreen(int scrnIndex, ScreenPtr pScreen)
5737{
5738    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
5739    vgaHWPtr hwp = VGAHWPTR(pScrn);
5740    XGIPtr pXGI = XGIPTR(pScrn);
5741
5742
5743#ifdef XF86DRI
5744    if (pXGI->directRenderingEnabled) {
5745        XGIDRICloseScreen(pScreen);
5746        pXGI->directRenderingEnabled = FALSE;
5747    }
5748#endif
5749
5750    if (pScrn->vtSema) {
5751        if (pXGI->CursorInfoPtr
5752            && (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI))) {
5753            pXGI->CursorInfoPtr->HideCursor(pScrn);
5754            XGI_WaitBeginRetrace(pXGI->RelIO);
5755        }
5756
5757
5758        XGIRestore(pScrn);
5759        vgaHWLock(hwp);
5760    }
5761
5762    /* We should restore the mode number in case vtsema = false as well,
5763     * but since we haven't register access then we can't do it. I think
5764     * I need to rework the save/restore stuff, like saving the video
5765     * status when returning to the X server and by that save me the
5766     * trouble if xgifb was started from a textmode VT while X was on.
5767     */
5768
5769    XGIUnmapMem(pScrn);
5770    vgaHWUnmapMem(pScrn);
5771
5772    if (IS_DUAL_HEAD(pXGI)) {
5773        XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
5774        pXGIEnt->refCount--;
5775    }
5776
5777    if (pXGI->pInt) {
5778        xf86FreeInt10(pXGI->pInt);
5779        pXGI->pInt = NULL;
5780    }
5781
5782#ifdef XGI_USE_XAA
5783    if (pXGI->AccelLinearScratch) {
5784        xf86FreeOffscreenLinear(pXGI->AccelLinearScratch);
5785        pXGI->AccelLinearScratch = NULL;
5786    }
5787
5788    if (!(pXGI->useEXA) && pXGI->AccelInfoPtr) {
5789        XAADestroyInfoRec(pXGI->AccelInfoPtr);
5790        pXGI->AccelInfoPtr = NULL;
5791    }
5792#endif
5793
5794    if (pXGI->CursorInfoPtr) {
5795        xf86DestroyCursorInfoRec(pXGI->CursorInfoPtr);
5796        pXGI->CursorInfoPtr = NULL;
5797    }
5798
5799    if (pXGI->ShadowPtr) {
5800        xfree(pXGI->ShadowPtr);
5801        pXGI->ShadowPtr = NULL;
5802    }
5803
5804    if (pXGI->DGAModes) {
5805        xfree(pXGI->DGAModes);
5806        pXGI->DGAModes = NULL;
5807    }
5808
5809    if (pXGI->adaptor) {
5810        xfree(pXGI->adaptor);
5811        pXGI->adaptor = NULL;
5812        pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
5813    }
5814
5815    pScrn->vtSema = FALSE;
5816
5817    /* Restore Blockhandler */
5818    pScreen->BlockHandler = pXGI->BlockHandler;
5819
5820    pScreen->CloseScreen = pXGI->CloseScreen;
5821
5822    return (*pScreen->CloseScreen) (scrnIndex, pScreen);
5823}
5824
5825
5826/* Free up any per-generation data structures */
5827
5828/* Optional */
5829static void
5830XGIFreeScreen(int scrnIndex, int flags)
5831{
5832    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) {
5833        vgaHWFreeHWRec(xf86Screens[scrnIndex]);
5834    }
5835
5836    XGIFreeRec(xf86Screens[scrnIndex]);
5837}
5838
5839
5840/* Jong 07/02/2008; Validate user-defined mode */
5841int XGIValidateUserDefMode(XGIPtr pXGI, DisplayModePtr mode)
5842{
5843   UShort i = (pXGI->CurrentLayout.bitsPerPixel+7)/8 - 1;
5844
5845
5846#if 1
5847	if((mode->HDisplay >= 1600) && (mode->VDisplay >= 1200) && (mode->VRefresh > 60))
5848	{
5849		ErrorF("Not support over (1600,1200) 60Hz ... Reduce to (1600,1200) 60Hz\n");
5850		mode->type=48; /* not user-defined */
5851		mode->VRefresh = 60.0;
5852
5853		mode->Clock=mode->SynthClock=162000; /* from XG20_Mode[] */ /* ((float)(mode->VTotal*mode->HTotal)+0.5) * (mode->VRefresh) / 1000.0; */
5854		ErrorF("Update clock to %d...\n", mode->Clock);
5855		return(-111) ;
5856	}
5857#endif
5858
5859#if 0
5860	if(XGI_GetModeID(0, mode->HDisplay, mode->VDisplay, i, 0, 0) == 0)
5861	{
5862		/* Jong 11/10/2008; support custom mode without ModeID */
5863		if( !((pXGI->HaveCustomModes) && (!(mode->type & M_T_DEFAULT))) )
5864		{
5865			ErrorF("Can't get Mode ID...\n");
5866			return(MODE_NOMODE) ;
5867	    }
5868	}
5869#endif
5870
5871	return(MODE_OK);
5872}
5873
5874/* Checks if a mode is suitable for the selected chipset. */
5875
5876static int
5877XGIValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
5878{
5879    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
5880    XGIPtr pXGI = XGIPTR(pScrn);
5881    int HDisplay = mode->HDisplay;
5882    int VDisplay = mode->VDisplay;
5883    int Clock = mode->Clock;
5884    int i = 0;
5885    int VRefresh;
5886
5887	/* Jong 07/27/2009; support custom mode without ModeID */
5888	pXGI->HaveCustomModes = TRUE;
5889
5890    VRefresh =
5891        (int) ((float) (Clock * 1000) /
5892               (float) (mode->VTotal * mode->HTotal) + 0.5);
5893
5894	/* Jong@09252009 */
5895	if(mode->VRefresh == 0)
5896		mode->VRefresh = VRefresh;
5897
5898    if((mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C))
5899	{
5900		VRefresh = mode->VRefresh;
5901	    Clock = mode->Clock;
5902	}
5903
5904    PDEBUG5(ErrorF("\nXGIValidMode()-->"));
5905    PDEBUG5(ErrorF
5906            ("CLK=%5.3fMhz %dx%d@%d ", (float) Clock / 1000, HDisplay,
5907             VDisplay, VRefresh));
5908    PDEBUG5(ErrorF("(VT,HT)=(%d,%d)\n", mode->VTotal, mode->HTotal));
5909    PDEBUG5(ErrorF("flags = %d\n", flags));
5910	if(flags == MODECHECK_FINAL)
5911	    PDEBUG5(ErrorF("This is a final check...\n"));
5912
5913#if 1
5914    if((mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C))
5915	{
5916		if(pScrn->monitor->DDC)
5917		{
5918			if(XGICheckModeByDDC(mode, pScrn->monitor->DDC) == FALSE)
5919			{
5920				ErrorF("It's a user-defined mode...rejected by EDID (pScrn->monitor->DDC)...return MODE_NOMODE\n");
5921				return (MODE_NOMODE);
5922			}
5923		}
5924
5925		PDEBUG5(ErrorF("It's a user-defined mode...return MODE_OK (might need more checking here) \n"));
5926		return(MODE_OK);
5927	}
5928#else
5929	if((mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C))
5930	{
5931		iRet=XGIValidateUserDefMode(pXGI, mode);
5932		if(iRet != -111)
5933		{
5934			if(iRet == MODE_OK)
5935				ErrorF("User-defined mode---MODE_OK\n");
5936			else
5937				ErrorF("User-defined mode---MODE_NOMODE\n");
5938
5939			return(iRet);
5940		}
5941	}
5942#endif
5943
5944	if(mode->VRefresh == 0)
5945		mode->VRefresh = VRefresh;
5946
5947#if 0
5948    if (pXGI->VBFlags & CRT2_LCD) {
5949        if ((HDisplay > 1600 && VDisplay > 1200)
5950            || (HDisplay < 640 && VDisplay < 480)) {
5951            PDEBUG5(ErrorF("skip by LCD limit\n"));
5952            return (MODE_NOMODE);
5953        }
5954        /* if( VRefresh != 60) return(MODE_NOMODE) ; */
5955    }
5956    else if (pXGI->VBFlags & CRT2_TV) {
5957        if ((HDisplay > 1024 && VDisplay > 768) ||
5958            (HDisplay < 640 && VDisplay < 480) || (VRefresh != 60)) {
5959            PDEBUG5(ErrorF("skip by TV limit\n"));
5960            return (MODE_NOMODE);
5961        }
5962    }
5963    else if (pXGI->VBFlags & CRT2_VGA) {
5964        if ((HDisplay > 1600 && VDisplay > 1200) ||
5965            (HDisplay < 640 && VDisplay < 480)) {
5966            PDEBUG5(ErrorF("skip by CRT2 limit\n"));
5967            return (MODE_NOMODE);
5968        }
5969    }
5970#endif
5971
5972    if ((pXGI->Chipset == PCI_CHIP_XGIXG20) ||(pXGI->Chipset == PCI_CHIP_XGIXG21) ||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) {
5973        XgiMode = XG20_Mode;
5974    }
5975    else {
5976        XgiMode = XGI_Mode;
5977    }
5978
5979    while ((XgiMode[i].Clock != Clock) ||
5980           (XgiMode[i].HDisplay != HDisplay) ||
5981           (XgiMode[i].VDisplay != VDisplay)) {
5982        if (XgiMode[i].Clock == 0) {
5983            PDEBUG5(ErrorF
5984                    ("--- Mode %dx%d@%dHz is not defined in support mode table of driver\n", HDisplay,
5985                     VDisplay, VRefresh));
5986			PDEBUG5(ErrorF("Mode is invalid...return MODE_NOMODE\n"));
5987            return (MODE_NOMODE);
5988        }
5989        else
5990            i++;
5991    }
5992
5993	if(pScrn->monitor->DDC)
5994	{
5995		if(XGICheckModeByDDC(mode, pScrn->monitor->DDC) == FALSE)
5996			{
5997				ErrorF("Rejected by EDID (pScrn->monitor->DDC)...return MODE_NOMODE\n");
5998				return (MODE_NOMODE);
5999			}
6000	}
6001
6002	if (pXGI->Chipset == PCI_CHIP_XGIXG27)
6003	{
6004		if(((g_PowerSavingStatus & 0x03) < 0x03) &&
6005		   ((g_PowerSavingStatus & 0x04) == 0x00) &&
6006			g_pMonitorDVI)
6007		{
6008			if(XGICheckModeByDDC(mode, g_pMonitorDVI) == FALSE)
6009			{
6010				PDEBUG5(ErrorF("Rejected by CRT2 EDID...return MODE_NOMODE\n"));
6011				return (MODE_NOMODE);
6012			}
6013		}
6014	}
6015	else /* Jong 12/05/2007; filter mode of CRT1 with CRT2 DDC for XG21 */
6016	{
6017		if(g_pMonitorDVI)
6018		{
6019			if(XGICheckModeByDDC(mode, g_pMonitorDVI) == FALSE)
6020			{
6021				PDEBUG5(ErrorF("Rejected by DVI EDID...return MODE_NOMODE\n"));
6022				return (MODE_NOMODE);
6023			}
6024		}
6025	}
6026
6027    PDEBUG5(ErrorF("Mode is valid...return MODE_OK\n"));
6028    return (MODE_OK);
6029}
6030
6031/* Do screen blanking
6032 *
6033 * Mandatory
6034 */
6035static Bool
6036XGISaveScreen(ScreenPtr pScreen, int mode)
6037{
6038    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
6039
6040    if ((pScrn != NULL) && pScrn->vtSema) {
6041
6042        XGIPtr pXGI = XGIPTR(pScrn);
6043
6044#ifdef UNLOCK_ALWAYS
6045        xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
6046#endif
6047    }
6048
6049    return vgaHWSaveScreen(pScreen, mode);
6050}
6051
6052/* SaveScreen for dual head mode */
6053static Bool
6054XGISaveScreenDH(ScreenPtr pScreen, int mode)
6055{
6056#ifdef XGIDUALHEAD
6057    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
6058
6059    if ((pScrn != NULL) && pScrn->vtSema) {
6060        XGIPtr pXGI = XGIPTR(pScrn);
6061
6062        if (IS_SECOND_HEAD(pXGI)
6063            && ((!(pXGI->VBFlags & CRT1_LCDA))
6064                || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
6065
6066            /* Slave head is always CRT1 */
6067            if (pXGI->VBFlags & CRT1_LCDA)
6068                pXGI->Blank = xf86IsUnblank(mode) ? FALSE : TRUE;
6069
6070            return vgaHWSaveScreen(pScreen, mode);
6071        }
6072        else {
6073            /* Master head is always CRT2 */
6074            /* But we land here if CRT1 is LCDA, too */
6075
6076            /* We can only blank LCD, not other CRT2 devices */
6077            if (!(pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)))
6078                return TRUE;
6079
6080            /* enable access to extended sequencer registers */
6081#ifdef UNLOCK_ALWAYS
6082            xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
6083#endif
6084        }
6085    }
6086#endif
6087    return TRUE;
6088}
6089
6090#ifdef DEBUG
6091static void
6092XGIDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
6093{
6094    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock : %x\n", mode->Clock);
6095    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Display : %x\n",
6096               mode->CrtcHDisplay);
6097    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank Start : %x\n",
6098               mode->CrtcHBlankStart);
6099    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync Start : %x\n",
6100               mode->CrtcHSyncStart);
6101    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync End : %x\n",
6102               mode->CrtcHSyncEnd);
6103    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank End : %x\n",
6104               mode->CrtcHBlankEnd);
6105    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Total : %x\n", mode->CrtcHTotal);
6106    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew);
6107    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz HAdjusted : %x\n",
6108               mode->CrtcHAdjusted);
6109    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Display : %x\n",
6110               mode->CrtcVDisplay);
6111    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank Start : %x\n",
6112               mode->CrtcVBlankStart);
6113    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync Start : %x\n",
6114               mode->CrtcVSyncStart);
6115    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync End : %x\n",
6116               mode->CrtcVSyncEnd);
6117    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank End : %x\n",
6118               mode->CrtcVBlankEnd);
6119    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Total : %x\n", mode->CrtcVTotal);
6120    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt VAdjusted : %x\n",
6121               mode->CrtcVAdjusted);
6122}
6123#endif
6124
6125static void
6126XGIModifyModeInfo(DisplayModePtr mode)
6127{
6128    if (mode->CrtcHBlankStart == mode->CrtcHDisplay)
6129        mode->CrtcHBlankStart++;
6130    if (mode->CrtcHBlankEnd == mode->CrtcHTotal)
6131        mode->CrtcHBlankEnd--;
6132    if (mode->CrtcVBlankStart == mode->CrtcVDisplay)
6133        mode->CrtcVBlankStart++;
6134    if (mode->CrtcVBlankEnd == mode->CrtcVTotal)
6135        mode->CrtcVBlankEnd--;
6136}
6137
6138/* Things to do before a ModeSwitch. We set up the
6139 * video bridge configuration and the TurboQueue.
6140 */
6141void
6142XGIPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode)
6143{
6144    XGIPtr pXGI = XGIPTR(pScrn);
6145    unsigned char CR30, CR31, CR33;
6146    unsigned char CR3B = 0;
6147    unsigned char CR17, CR38 = 0;
6148    unsigned char CR35 = 0, CR79 = 0;
6149    unsigned long vbflag;
6150    int temp = 0;
6151    int crt1rateindex = 0;
6152    DisplayModePtr mymode;
6153#ifdef XGIMERGED
6154    DisplayModePtr mymode2 = NULL;
6155#endif
6156
6157#ifdef XGIMERGED
6158    if (pXGI->MergedFB) {
6159        mymode = ((XGIMergedDisplayModePtr) mode->Private)->CRT1;
6160        mymode2 = ((XGIMergedDisplayModePtr) mode->Private)->CRT2;
6161    }
6162    else
6163#endif
6164        mymode = mode;
6165
6166    vbflag = pXGI->VBFlags;
6167    PDEBUG(ErrorF("VBFlags=0x%lx\n", pXGI->VBFlags));
6168
6169#ifdef UNLOCK_ALWAYS
6170    xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);     /* Unlock Registers */
6171#endif
6172
6173    inXGIIDXREG(XGICR, 0x30, CR30);
6174    inXGIIDXREG(XGICR, 0x31, CR31);
6175    inXGIIDXREG(XGICR, 0x33, CR33);
6176
6177    inXGIIDXREG(XGICR, 0x3b, CR3B);
6178    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4,
6179                   "Before: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
6180                   CR30, CR31, CR33, temp, CR38);
6181
6182    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "VBFlags=0x%lx\n",
6183                   pXGI->VBFlags);
6184
6185    CR30 = 0x00;
6186    CR31 &= ~0x60;              /* Clear VB_Drivermode & VB_OutputDisable */
6187    CR31 |= 0x04;               /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */
6188    CR35 = 0x00;
6189
6190
6191    if (!pXGI->AllowHotkey) {
6192        CR31 |= 0x80;           /* Disable hotkey-switch */
6193    }
6194    CR79 &= ~0x10;              /* Enable Backlight control on 315 series */
6195
6196
6197    if ((vbflag & CRT1_LCDA) && (viewmode == XGI_MODE_CRT1)) {
6198
6199        CR38 |= 0x02;
6200
6201    }
6202    else {
6203
6204        switch (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
6205
6206        case CRT2_TV:
6207
6208            CR38 &= ~0xC0;      /* Clear Pal M/N bits */
6209
6210            if (vbflag & TV_YPBPR) {    /* Video bridge */
6211                if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR) {
6212                    CR30 |= 0x80;
6213                    CR38 |= 0x08;
6214                    if (vbflag & TV_YPBPR525P)
6215                        CR38 |= 0x10;
6216                    else if (vbflag & TV_YPBPR750P)
6217                        CR38 |= 0x20;
6218                    else if (vbflag & TV_YPBPR1080I)
6219                        CR38 |= 0x30;
6220                    CR31 &= ~0x01;
6221                    if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPRAR) {
6222                        CR3B &= ~0x03;
6223                        if ((vbflag & TV_YPBPRAR) == TV_YPBPR43LB)
6224                            CR3B |= 0x00;
6225                        else if ((vbflag & TV_YPBPRAR) == TV_YPBPR43)
6226                            CR3B |= 0x03;
6227                        else if ((vbflag & TV_YPBPRAR) == TV_YPBPR169)
6228                            CR3B |= 0x01;
6229                        else
6230                            CR3B |= 0x03;
6231                    }
6232                }
6233            }
6234            else {              /* All */
6235                if (vbflag & TV_SCART)
6236                    CR30 |= 0x10;
6237                if (vbflag & TV_SVIDEO)
6238                    CR30 |= 0x08;
6239                if (vbflag & TV_AVIDEO)
6240                    CR30 |= 0x04;
6241                if (!(CR30 & 0x1C))
6242                    CR30 |= 0x08;       /* default: SVIDEO */
6243
6244                if (vbflag & TV_PAL) {
6245                    CR31 |= 0x01;
6246                    CR35 |= 0x01;
6247                    if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
6248                        if (vbflag & TV_PALM) {
6249                            CR38 |= 0x40;
6250                            CR35 |= 0x04;
6251                        }
6252                        else if (vbflag & TV_PALN) {
6253                            CR38 |= 0x80;
6254                            CR35 |= 0x08;
6255                        }
6256                    }
6257                }
6258                else {
6259                    CR31 &= ~0x01;
6260                    CR35 &= ~0x01;
6261                    if (vbflag & TV_NTSCJ) {
6262                        CR38 |= 0x40;   /* TW, not BIOS */
6263                        CR35 |= 0x02;
6264                    }
6265                }
6266                if (vbflag & TV_SCART) {
6267                    CR31 |= 0x01;
6268                    CR35 |= 0x01;
6269                }
6270            }
6271
6272            CR31 &= ~0x04;      /* Clear NotSimuMode */
6273#ifdef XGI_CP
6274            XGI_CP_DRIVER_CONFIG
6275#endif
6276                break;
6277
6278        case CRT2_LCD:
6279            CR30 |= 0x20;
6280            break;
6281
6282        case CRT2_VGA:
6283            CR30 |= 0x40;
6284            break;
6285
6286        default:
6287            CR30 |= 0x00;
6288            CR31 |= 0x20;       /* VB_OUTPUT_DISABLE */
6289        }
6290
6291    }
6292
6293    if (vbflag & CRT1_LCDA) {
6294        switch (viewmode) {
6295        case XGI_MODE_CRT1:
6296            CR38 |= 0x01;
6297            break;
6298        case XGI_MODE_CRT2:
6299            if (vbflag & (CRT2_TV | CRT2_VGA)) {
6300                CR30 |= 0x02;
6301                CR38 |= 0x01;
6302            }
6303            else {
6304                CR38 |= 0x03;
6305            }
6306            break;
6307        case XGI_MODE_SIMU:
6308        default:
6309            if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
6310                CR30 |= 0x01;
6311            }
6312            break;
6313        }
6314    }
6315    else {
6316        if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
6317            CR30 |= 0x01;
6318        }
6319    }
6320
6321    CR31 |= 0x40;               /* Set Drivermode */
6322    CR31 &= ~0x06;              /* Disable SlaveMode, disable SimuMode in SlaveMode */
6323    crt1rateindex = XGISearchCRT1Rate(pScrn, mymode);
6324
6325    if (IS_DUAL_HEAD(pXGI)) {
6326        if (IS_SECOND_HEAD(pXGI)) {
6327            /* CRT1 */
6328            CR33 &= 0xf0;
6329            if (!(vbflag & CRT1_LCDA)) {
6330                CR33 |= (crt1rateindex & 0x0f);
6331            }
6332        }
6333        else {
6334            /* CRT2 */
6335            CR33 &= 0x0f;
6336            if (vbflag & CRT2_VGA) {
6337                CR33 |= ((crt1rateindex << 4) & 0xf0);
6338            }
6339        }
6340    }
6341    else
6342#ifdef XGIMERGED
6343    if (pXGI->MergedFB) {
6344        CR33 = 0;
6345        if (!(vbflag & CRT1_LCDA)) {
6346            CR33 |= (crt1rateindex & 0x0f);
6347        }
6348        if (vbflag & CRT2_VGA) {
6349            CR33 |= (XGISearchCRT1Rate(pScrn, mymode2) << 4);
6350        }
6351    }
6352    else
6353#endif
6354    {
6355        CR33 = 0;
6356        if (!(vbflag & CRT1_LCDA)) {
6357            CR33 |= (crt1rateindex & 0x0f);
6358        }
6359        if (vbflag & CRT2_VGA) {
6360            CR33 |= ((crt1rateindex & 0x0f) << 4);
6361        }
6362        if (vbflag & CRT2_ENABLE) {
6363            if (pXGI->CRT1off)
6364                CR33 &= 0xf0;
6365        }
6366    }
6367    outXGIIDXREG(XGICR, 0x30, CR30);
6368    outXGIIDXREG(XGICR, 0x31, CR31);
6369    outXGIIDXREG(XGICR, 0x33, CR33);
6370    if (temp) {
6371        outXGIIDXREG(XGICR, temp, CR38);
6372    }
6373    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
6374                   "After:  CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n",
6375                   CR30, CR31, CR33, temp, CR38);
6376
6377    if (pXGI->VBFlags & CRT2_ENABLE) {
6378        /* Switch on CRT1 for modes that require the bridge in SlaveMode */
6379        andXGIIDXREG(XGISR, 0x1f, 0x3f);
6380        inXGIIDXREG(XGICR, 0x17, CR17);
6381        if (!(CR17 & 0x80)) {
6382            orXGIIDXREG(XGICR, 0x17, 0x80);
6383            outXGIIDXREG(XGISR, 0x00, 0x01);
6384            usleep(10000);
6385            outXGIIDXREG(XGISR, 0x00, 0x03);
6386        }
6387    }
6388
6389    andXGIIDXREG(XGISR, 0x1f, 0xfb); /* disable DAC pedestal to reduce brightness */
6390}
6391
6392/* PostSetMode:
6393 * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA;
6394 *    VESA uses the bridge in SlaveMode and switching CRT1 off while
6395 *    the bridge is in SlaveMode not that clever...
6396 * -) Check if overlay can be used (depending on dotclock)
6397 * -) Check if Panel Scaler is active on LVDS for overlay re-scaling
6398 * -) Save TV registers for further processing
6399 * -) Apply TV settings
6400 */
6401static void
6402XGIPostSetMode(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)
6403{
6404    XGIPtr pXGI = XGIPTR(pScrn);
6405/*    unsigned char usScratchCR17;
6406    Bool flag = FALSE;
6407    Bool doit = TRUE; */
6408    int myclock;
6409    unsigned char sr2b, sr2c, tmpreg;
6410    float num, denum, postscalar, divider;
6411    PDEBUG(ErrorF(" XGIPostSetMode(). \n"));
6412#ifdef TWDEBUG
6413    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1off is %d\n", pXGI->CRT1off);
6414#endif
6415
6416#ifdef UNLOCK_ALWAYS
6417    xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
6418#endif
6419
6420    /* Determine if the video overlay can be used */
6421    if (!pXGI->NoXvideo) {
6422        inXGIIDXREG(XGISR, 0x2b, sr2b);
6423        inXGIIDXREG(XGISR, 0x2c, sr2c);
6424        divider = (sr2b & 0x80) ? 2.0 : 1.0;
6425        postscalar = (sr2c & 0x80) ?
6426            ((((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) :
6427            (((sr2c >> 5) & 0x03) + 1.0);
6428        num = (sr2b & 0x7f) + 1.0;
6429        denum = (sr2c & 0x1f) + 1.0;
6430        myclock =
6431            (int) ((14318 * (divider / postscalar) * (num / denum)) / 1000);
6432
6433        pXGI->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT1OVERLAYGAMMA);
6434/*       switch(pXGI->xgi_HwDevExt.jChipType) {
6435            break;
6436       }
6437       */
6438        if (!(pXGI->MiscFlags & MISC_CRT1OVERLAY)) {
6439            if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI))
6440                xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3,
6441                               "Current dotclock (%dMhz) too high for video overlay on CRT1\n",
6442                               myclock);
6443        }
6444    }
6445
6446    /* Determine if the Panel Link scaler is active */
6447    pXGI->MiscFlags &= ~MISC_PANELLINKSCALER;
6448    if (pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)) {
6449        if (pXGI->VBFlags & CRT1_LCDA) {
6450            inXGIIDXREG(XGIPART1, 0x35, tmpreg);
6451            tmpreg &= 0x04;
6452            if (!tmpreg)
6453                pXGI->MiscFlags |= MISC_PANELLINKSCALER;
6454        }
6455    }
6456
6457    /* Determine if our very special TV mode is active */
6458    pXGI->MiscFlags &= ~MISC_TVNTSC1024;
6459    if ((pXGI->XGI_Pr->VBType & VB_XGIVB) && (pXGI->VBFlags & CRT2_TV)
6460        && (!(pXGI->VBFlags & TV_HIVISION))) {
6461        if (((pXGI->VBFlags & TV_YPBPR) && (pXGI->VBFlags & TV_YPBPR525I))
6462            || ((!(pXGI->VBFlags & TV_YPBPR))
6463                && (pXGI->VBFlags & (TV_NTSC | TV_PALM)))) {
6464            inXGIIDXREG(XGICR, 0x34, tmpreg);
6465            tmpreg &= 0x7f;
6466            if ((tmpreg == 0x64) || (tmpreg == 0x4a) || (tmpreg == 0x38)) {
6467                pXGI->MiscFlags |= MISC_TVNTSC1024;
6468            }
6469        }
6470    }
6471
6472    /* Reset XV gamma correction */
6473    if (pXGI->ResetXvGamma) {
6474        (pXGI->ResetXvGamma) (pScrn);
6475    }
6476
6477    /*  Apply TV settings given by options
6478     * Do this even in DualHeadMode:
6479     * - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1
6480     * - if this is called by SetModeCRT2, CRT2 mode has changed (duh!)
6481     * -> Hence, in both cases, the settings must be re-applied.
6482     */
6483}
6484
6485
6486USHORT
6487XGI_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode,
6488                  unsigned long VBFlags)
6489{
6490    XGIPtr pXGI = XGIPTR(pScrn);
6491    UShort i = (pXGI->CurrentLayout.bitsPerPixel + 7) / 8 - 1;
6492
6493    if ((VBFlags & CRT1_LCDA)) {
6494        if ((mode->HDisplay > pXGI->LCDwidth) ||
6495            (mode->VDisplay > pXGI->LCDheight)) {
6496            return 0;
6497        }
6498    }
6499
6500    return XGI_GetModeID(VBFlags, mode->HDisplay, mode->VDisplay,
6501                         i, pXGI->LCDwidth, pXGI->LCDheight);
6502}
6503
6504/* Calculate the vertical refresh rate from a mode */
6505int
6506XGICalcVRate(DisplayModePtr mode)
6507{
6508    float hsync, refresh = 0;
6509
6510    if (mode->HSync > 0.0)
6511        hsync = mode->HSync;
6512    else if (mode->HTotal > 0)
6513        hsync = (float) mode->Clock / (float) mode->HTotal;
6514    else
6515        hsync = 0.0;
6516
6517    if (mode->VTotal > 0)
6518        refresh = hsync * 1000.0 / mode->VTotal;
6519
6520    if (mode->Flags & V_INTERLACE)
6521        refresh *= 2.0;
6522
6523    if (mode->Flags & V_DBLSCAN)
6524        refresh /= 2.0;
6525
6526    if (mode->VScan > 1)
6527        refresh /= mode->VScan;
6528
6529    if (mode->VRefresh > 0.0)
6530        refresh = mode->VRefresh;
6531
6532    if (hsync == 0 || refresh == 0)
6533        return (0);
6534
6535    return ((int) (refresh));
6536}
6537
6538/* Calculate CR33 (rate index) for CRT1.
6539 * Calculation is done using currentmode, therefore it is
6540 * recommended to set VertRefresh and HorizSync to correct
6541 * values in config file.
6542 */
6543unsigned char
6544XGISearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
6545{
6546    XGIPtr         pXGI = XGIPTR(pScrn);
6547    int i = 0;
6548    int irefresh;
6549    unsigned short xres = mode->HDisplay;
6550    unsigned short yres = mode->VDisplay;
6551    unsigned char index;
6552    BOOLEAN checkxgi730 = FALSE;
6553
6554    irefresh = XGICalcVRate(mode);
6555    if (!irefresh) {
6556        if (xres == 800 || xres == 1024 || xres == 1280)
6557            return 0x02;
6558        else
6559            return 0x01;
6560    }
6561
6562#ifdef TWDEBUG
6563    xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
6564#endif
6565
6566    /* We need the REAL refresh rate here */
6567    if (mode->Flags & V_INTERLACE)
6568        irefresh /= 2;
6569
6570    /* Do not multiply by 2 when DBLSCAN! */
6571
6572#ifdef TWDEBUG
6573    xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
6574#endif
6575
6576    index = 0;
6577    while ((xgix_vrate[i].idx != 0) && (xgix_vrate[i].xres <= xres)) {
6578        if ((xgix_vrate[i].xres == xres) && (xgix_vrate[i].yres == yres)) {
6579            if ((checkxgi730 == FALSE)
6580                || (xgix_vrate[i].XGI730valid32bpp == TRUE)) {
6581                if (xgix_vrate[i].refresh == irefresh) {
6582                    index = xgix_vrate[i].idx;
6583                    break;
6584                }
6585                else if (xgix_vrate[i].refresh > irefresh) {
6586                    if ((xgix_vrate[i].refresh - irefresh) <= 3) {
6587                        index = xgix_vrate[i].idx;
6588                    }
6589                    else if (((checkxgi730 == FALSE)
6590                              || (xgix_vrate[i - 1].XGI730valid32bpp == TRUE))
6591                             && ((irefresh - xgix_vrate[i - 1].refresh) <= 2)
6592                             && (xgix_vrate[i].idx != 1)) {
6593                        index = xgix_vrate[i - 1].idx;
6594                    }
6595                    break;
6596                }
6597                else if ((irefresh - xgix_vrate[i].refresh) <= 2) {
6598                    index = xgix_vrate[i].idx;
6599                    break;
6600                }
6601            }
6602        }
6603        i++;
6604    }
6605
6606	/* Jong 10/19/2007; merge code */
6607	/* Adjust to match table of VBIOS */
6608	switch(pXGI->Chipset)
6609	{
6610		case PCI_CHIP_XGIXG20:
6611		case PCI_CHIP_XGIXG21:
6612                if((xres == 640) && (yres == 480))
6613                {
6614                  if (xgix_vrate[index].refresh>85)
6615                  {
6616                    index = 4;
6617                  }
6618                }
6619
6620                if((xres == 800) && (yres == 600))
6621                {
6622                  if (xgix_vrate[index].refresh>85)
6623                  {
6624                    index = 5;
6625                  }
6626
6627                  if (index>0)
6628                  {
6629                    index --;
6630                  }
6631                }
6632
6633                if((xres == 1024) && (yres == 768))
6634                {
6635                  if (xgix_vrate[index].refresh>85)
6636                  {
6637                    index = 5;
6638                  }
6639
6640                  if (index>0)
6641                  {
6642                    index --;
6643                  }
6644                }
6645
6646                if((xres == 1280) && (yres == 1024))
6647                {
6648                  if (index>0)
6649                  {
6650                    index --;
6651                  }
6652                }
6653
6654                if((xres == 1600) && (yres == 1200))
6655                {
6656                  if (xgix_vrate[index].refresh>85)
6657                  {
6658                    index = 5;
6659                  }
6660                }
6661
6662                if((xres >= 1920) && (yres >= 1440))
6663                {
6664                  index = 0;
6665                }
6666
6667                break;
6668
6669		case PCI_CHIP_XGIXG27:
6670
6671               if((xres == 640) && (yres == 480))
6672                {
6673                  if (xgix_vrate[index].refresh>85)
6674                  {
6675                    index = 4;
6676                  }
6677                }
6678
6679                if((xres == 800) && (yres == 600))
6680                {
6681                  if (xgix_vrate[index].refresh>85)
6682                  {
6683                    index = 5;
6684                  }
6685
6686                  if (index>0)
6687                  {
6688                    index --;
6689                  }
6690                }
6691
6692                if((xres == 1024) && (yres == 768))
6693                {
6694                  if (xgix_vrate[index].refresh>85)
6695                  {
6696                    index = 5;
6697                  }
6698
6699                  if (index>0)
6700                  {
6701                    index --;
6702                  }
6703                }
6704
6705                if((xres == 1280) && (yres == 1024))
6706                {
6707                  if (index>0)
6708                  {
6709                    index --;
6710                  }
6711                }
6712
6713                if((xres == 1600) && (yres == 1200))
6714                {
6715                  if (xgix_vrate[index].refresh>85)
6716                  {
6717                    index = 5;
6718                  }
6719                }
6720
6721                break;
6722
6723		default:
6724            break;
6725	}
6726
6727    if (index > 0)
6728        return index;
6729    else {
6730        /* Default Rate index */
6731        if (xres == 800 || xres == 1024 || xres == 1280)
6732            return 0x02;
6733        else
6734            return 0x01;
6735    }
6736}
6737
6738
6739#define MODEID_OFF 0x449
6740
6741unsigned char
6742XGI_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
6743{
6744    return (XGI_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
6745}
6746
6747unsigned char
6748XGI_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
6749{
6750    unsigned char ret = 0;
6751#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
6752    unsigned char *base;
6753
6754    base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
6755    if (!base) {
6756        XGIErrorLog(pScrn, "(Could not map BIOS scratch area)\n");
6757        return 0;
6758    }
6759
6760    ret = *(base + offset);
6761
6762    /* value != 0xff means: set register */
6763    if (value != 0xff)
6764        *(base + offset) = value;
6765
6766    xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
6767#endif
6768    return ret;
6769}
6770
6771void
6772xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
6773                             unsigned char *reg2)
6774{
6775    register unsigned char val;
6776    unsigned long mylockcalls;
6777
6778    pXGI->lockcalls++;
6779    mylockcalls = pXGI->lockcalls;
6780
6781    /* check if already unlocked */
6782    inXGIIDXREG(XGISR, 0x05, val);
6783    if (val != 0xa1) {
6784        /* save State */
6785        if (reg1)
6786            *reg1 = val;
6787        /* unlock */
6788/*
6789       outb (0x3c4, 0x20);
6790       val4 = inb (0x3c5);
6791       val4 |= 0x20;
6792       outb (0x3c5, val4);
6793*/
6794        outXGIIDXREG(XGISR, 0x05, 0x86);
6795        inXGIIDXREG(XGISR, 0x05, val);
6796        if (val != 0xA1) {
6797#ifdef TWDEBUG
6798            unsigned char val1, val2;
6799            int i;
6800#endif
6801            XGIErrorLog(pXGI->pScrn,
6802                        "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
6803                        (void *) pXGI, (unsigned long) pXGI->RelIO, val,
6804                        mylockcalls);
6805#ifdef TWDEBUG
6806            for (i = 0; i <= 0x3f; i++) {
6807                inXGIIDXREG(XGISR, i, val1);
6808                /* inXGIIDXREG(0x3c4, i, val2); */
6809                inXGIIDXREG(XGISR, i, val2);
6810                xf86DrvMsg(pXGI->pScrn->scrnIndex, X_INFO,
6811                           "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n",
6812                           i, val1, val2, mylockcalls);
6813            }
6814#endif
6815        }
6816    }
6817}
6818
6819void
6820xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1, unsigned char reg2)
6821{
6822    /* restore lock */
6823#ifndef UNLOCK_ALWAYS
6824    outXGIIDXREG(XGISR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00);
6825#endif
6826}
6827
6828/* Jong 12/03/2007; */
6829/*
6830void XGICheckModeForMonitor(ScrnInfoPtr pScrn, )
6831{
6832	DisplayModePtr pCRT1Modes=pScrn->monitor->Modes;
6833
6834    if ((p = first = pScrn->monitor->Modes)) {
6835        do {
6836			xf86CheckModeForMonitor(p,
6837            n = p->next;
6838            p = n;
6839        } while (p != NULL && p != first);
6840    }
6841
6842    xf86PruneDriverModes(pXGI->CRT2pScrn);
6843}
6844*/
6845
6846/* Jong 12/05/2007; filter mode list by monitor DDC */
6847static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC)
6848{
6849    DisplayModePtr first, p;
6850
6851    if ((p = first = pModeList))
6852	{
6853        do
6854		{
6855			if(XGICheckModeByDDC(p, pMonitorDDC) == FALSE)
6856				xf86DeleteMode(&pModeList, pModeList);
6857
6858            p = p->next;
6859        } while (p != NULL && p != first);
6860    }
6861}
6862
6863/* Jong 12/05/2007; filter mode list by monitor DDC */
6864static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC)
6865{
6866    int i, j;
6867    float VF, HF;
6868    struct detailed_timings *pd_timings;
6869    struct monitor_ranges *pranges;
6870    struct std_timings *pstd_t;
6871
6872	int VRefresh=pMode->VRefresh;
6873
6874    if ((pMode == NULL) || (pMonitorDDC == NULL)) {
6875        return(FALSE);                 /* ignore */
6876    }
6877
6878	if( pMode->VRefresh == 0)
6879		VRefresh = (int)((float)(pMode->Clock*1000)/(float)(pMode->VTotal*pMode->HTotal)+0.5);
6880
6881
6882    for (i = 0, j = 0; i < 8; i++, j++)
6883	{
6884        if (establish_timing[j].width == -1)
6885		{
6886            continue;
6887        }
6888
6889        if (pMonitorDDC->timings1.t1 & (1 << i))
6890		{
6891			if( (establish_timing[j].width == pMode->HDisplay) &&
6892				(establish_timing[j].height == pMode->VDisplay) &&
6893				(establish_timing[j].VRefresh == VRefresh) )
6894				return(TRUE);
6895        }
6896    }
6897
6898    for (i = 0; i < 8; i++, j++)
6899	{
6900        if (establish_timing[j].width == -1)
6901		{
6902            continue;
6903        }
6904
6905        if (pMonitorDDC->timings1.t2 & (1 << i))
6906		{
6907			if( (establish_timing[j].width == pMode->HDisplay) &&
6908				(establish_timing[j].height == pMode->VDisplay) &&
6909				(establish_timing[j].VRefresh == VRefresh) )
6910				return(TRUE);
6911        }
6912    }
6913
6914    for (i = 0; i < 8; i++)
6915	{
6916        if ((pMode->HDisplay == pMonitorDDC->timings2[i].hsize) &&
6917            (pMode->VDisplay == pMonitorDDC->timings2[i].vsize) &&
6918            (VRefresh == pMonitorDDC->timings2[i].refresh))
6919			return(TRUE);
6920    }
6921
6922/* Jong 12/05/2007; Don't know how to do? */
6923#if 0
6924    for (i = 0; i < 4; i++)
6925	{
6926        switch (pMonitorDDC->det_mon[i].type)
6927		{
6928			case DS_RANGES:
6929				pranges = &(pMonitorDDC->det_mon[i].section.ranges);
6930				PDEBUG5(ErrorF
6931						("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
6932						 pranges->min_v, pranges->max_v, pranges->min_h,
6933						 pranges->max_h, pranges->max_clock));
6934
6935				if (range->loH > pranges->min_h)
6936					range->loH = pranges->min_h;
6937				if (range->loV > pranges->min_v)
6938					range->loV = pranges->min_v;
6939				if (range->hiH < pranges->max_h)
6940					range->hiH = pranges->max_h;
6941				if (range->hiV < pranges->max_v)
6942					range->hiV = pranges->max_v;
6943				PDEBUG5(ErrorF
6944						("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
6945						 range->loV, range->hiH, range->hiV));
6946				break;
6947
6948			case DS_STD_TIMINGS:
6949				pstd_t = pMonitorDDC->det_mon[i].section.std_t;
6950				for (j = 0; j < 5; j++) {
6951					int k;
6952					PDEBUG5(ErrorF
6953							("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
6954							 j, pstd_t[j].hsize, pstd_t[j].vsize,
6955							 pstd_t[j].refresh, pstd_t[j].id));
6956					for (k = 0; StdTiming[k].width != -1; k++) {
6957						if ((StdTiming[k].width == pstd_t[j].hsize) &&
6958							(StdTiming[k].height == pstd_t[j].vsize) &&
6959							(StdTiming[k].VRefresh == pstd_t[j].refresh)) {
6960							if (range->loH > StdTiming[k].HSync)
6961								range->loH = StdTiming[k].HSync;
6962							if (range->hiH < StdTiming[k].HSync)
6963								range->hiH = StdTiming[k].HSync;
6964							if (range->loV > StdTiming[k].VRefresh)
6965								range->loV = StdTiming[k].VRefresh;
6966							if (range->hiV < StdTiming[k].VRefresh)
6967								range->hiV = StdTiming[k].VRefresh;
6968							break;
6969						}
6970
6971					}
6972				}
6973				break;
6974
6975			case DT:
6976
6977				pd_timings = &pMonitorDDC->det_mon[i].section.d_timings;
6978
6979				HF = pd_timings->clock / (pd_timings->h_active +
6980										  pd_timings->h_blanking);
6981				VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
6982				HF /= 1000;         /* into KHz Domain */
6983				if (range->loH > HF)
6984					range->loH = HF;
6985				if (range->hiH < HF)
6986					range->hiH = HF;
6987				if (range->loV > VF)
6988					range->loV = VF;
6989				if (range->hiV < VF)
6990					range->hiV = VF;
6991				PDEBUG(ErrorF
6992					   ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
6993						HF, VF, range->loH, range->loV, range->hiH, range->hiV));
6994				break;
6995		}
6996    }
6997#endif
6998
6999	return(FALSE);
7000}
7001
7002#ifdef DEBUG
7003void
7004XGIDumpSR(ScrnInfoPtr pScrn)
7005{
7006    XGIPtr pXGI = XGIPTR(pScrn);
7007
7008    int i, j;
7009    unsigned long temp;
7010
7011    ErrorF
7012        ("----------------------------------------------------------------------\n");
7013    ErrorF("SR xx\n");
7014    ErrorF
7015        ("----------------------------------------------------------------------\n");
7016    for (i = 0; i < 0x40; i += 0x10) {
7017        ErrorF("SR[%02X]:", i);
7018        for (j = 0; j < 16; j++) {
7019            inXGIIDXREG(XGISR, (i + j), temp);
7020            ErrorF(" %02lX", temp);
7021        }
7022        ErrorF("\n");
7023    }
7024    ErrorF("\n");
7025}
7026
7027void
7028XGIDumpCR(ScrnInfoPtr pScrn)
7029{
7030    XGIPtr pXGI = XGIPTR(pScrn);
7031
7032    int i, j;
7033    unsigned long temp;
7034
7035    ErrorF
7036        ("----------------------------------------------------------------------\n");
7037    ErrorF("CR xx\n");
7038    ErrorF
7039        ("----------------------------------------------------------------------\n");
7040    for (i = 0; i < 0x100; i += 0x10) {
7041        ErrorF("CR[%02X]:", i);
7042        for (j = 0; j < 16; j++) {
7043            inXGIIDXREG(XGICR, (i + j), temp);
7044            ErrorF(" %02lX", temp);
7045        }
7046        ErrorF("\n");
7047    }
7048}
7049
7050void
7051XGIDumpGR(ScrnInfoPtr pScrn)
7052{
7053    XGIPtr pXGI = XGIPTR(pScrn);
7054
7055    int i;
7056    unsigned long temp;
7057
7058    ErrorF
7059        ("----------------------------------------------------------------------\n");
7060    ErrorF("GR xx\n");
7061    ErrorF
7062        ("----------------------------------------------------------------------\n");
7063    ErrorF("GR:");
7064    for (i = 0; i < 0x9; i += 0x10) {
7065        inXGIIDXREG(XGISR, i, temp);
7066        ErrorF(" %02lX", temp);
7067    }
7068    ErrorF("\n");
7069}
7070
7071#if 0
7072void
7073XGIDumpPart0(ScrnInfoPtr pScrn)
7074{
7075    XGIPtr pXGI = XGIPTR(pScrn);
7076    int i, j;
7077    unsigned long temp;
7078
7079    ErrorF
7080        ("----------------------------------------------------------------------\n");
7081    ErrorF("PART0 xx\n");
7082    ErrorF
7083        ("----------------------------------------------------------------------\n");
7084    for (i = 0; i < 0x50; i += 0x10) {
7085        ErrorF("PART0[%02X]:", i);
7086        for (j = 0; j < 0x10; j++) {
7087            inXGIIDXREG(XGIPART0, (i + j), temp);
7088            ErrorF(" %02lX", temp);
7089        }
7090        ErrorF("\n");
7091    }
7092}
7093
7094void
7095XGIDumpPart05(ScrnInfoPtr pScrn)
7096{
7097    XGIPtr pXGI = XGIPTR(pScrn);
7098    int i, j;
7099    unsigned long temp;
7100    ErrorF
7101        ("----------------------------------------------------------------------\n");
7102    ErrorF("PART05 xx\n");
7103    ErrorF
7104        ("----------------------------------------------------------------------\n");
7105    for (i = 0; i < 0x50; i += 0x10) {
7106        ErrorF("PART05[%02X]:", i);
7107        for (j = 0; j < 0x10; j++) {
7108            inXGIIDXREG(XGIPART05, (i + j), temp);
7109            ErrorF(" %02lX", temp);
7110        }
7111        ErrorF("\n");
7112    }
7113}
7114
7115void
7116XGIDumpPart1(ScrnInfoPtr pScrn)
7117{
7118    XGIPtr pXGI = XGIPTR(pScrn);
7119
7120    int i, j;
7121    unsigned long temp;
7122
7123    ErrorF
7124        ("----------------------------------------------------------------------\n");
7125    ErrorF("PART1 xx\n");
7126    ErrorF
7127        ("----------------------------------------------------------------------\n");
7128    for (i = 0; i < 0x100; i += 0x10) {
7129        ErrorF("PART1[%02X]:", i);
7130        for (j = 0; j < 0x10; j++) {
7131            inXGIIDXREG(XGIPART1, (i + j), temp);
7132            ErrorF(" %02lX", temp);
7133        }
7134        ErrorF("\n");
7135    }
7136}
7137
7138void
7139XGIDumpPart2(ScrnInfoPtr pScrn)
7140{
7141    XGIPtr pXGI = XGIPTR(pScrn);
7142
7143    int i, j;
7144    unsigned long temp;
7145
7146    ErrorF
7147        ("----------------------------------------------------------------------\n");
7148    ErrorF("PART2 xx\n");
7149    ErrorF
7150        ("----------------------------------------------------------------------\n");
7151    for (i = 0; i < 0x100; i += 0x10) {
7152        ErrorF("PART2[%02X]:", i);
7153        for (j = 0; j < 0x10; j++) {
7154            inXGIIDXREG(XGIPART2, (i + j), temp);
7155            ErrorF(" %02lX", temp);
7156        }
7157        ErrorF("\n");
7158    }
7159}
7160
7161void
7162XGIDumpPart3(ScrnInfoPtr pScrn)
7163{
7164    XGIPtr pXGI = XGIPTR(pScrn);
7165
7166    int i, j;
7167    unsigned long temp;
7168
7169    ErrorF
7170        ("----------------------------------------------------------------------\n");
7171    ErrorF("PART3 xx\n");
7172    ErrorF
7173        ("----------------------------------------------------------------------\n");
7174
7175    for (i = 0; i < 0x100; i += 0x10) {
7176        ErrorF("PART3[%02X]:", i);
7177        for (j = 0; j < 0x10; j++) {
7178            inXGIIDXREG(XGIPART3, (i + j), temp);
7179            ErrorF(" %02lX", temp);
7180        }
7181        ErrorF("\n");
7182    }
7183}
7184
7185void
7186XGIDumpPart4(ScrnInfoPtr pScrn)
7187{
7188    XGIPtr pXGI = XGIPTR(pScrn);
7189
7190    int i, j;
7191    unsigned long temp;
7192
7193    ErrorF
7194        ("----------------------------------------------------------------------\n");
7195    ErrorF("PART4 xx\n");
7196    ErrorF
7197        ("----------------------------------------------------------------------\n");
7198    for (i = 0; i < 0x100; i += 0x10) {
7199        ErrorF("PART4[%02X]:", i);
7200        for (j = 0; j < 0x10; j++) {
7201            inXGIIDXREG(XGIPART4, (i + j), temp);
7202            ErrorF(" %02lX", temp);
7203        }
7204        ErrorF("\n");
7205    }
7206}
7207#endif
7208
7209void
7210XGIDumpMMIO(ScrnInfoPtr pScrn)
7211{
7212    XGIPtr pXGI = XGIPTR(pScrn);
7213
7214    int i;
7215    unsigned long temp;
7216/*
7217    ErrorF("----------------------------------------------------------------------\n") ;
7218    ErrorF("MMIO 85xx\n") ;
7219    ErrorF("----------------------------------------------------------------------\n") ;
7220	for( i = 0x8500 ; i < 0x8600 ; i+=0x10 )
7221	{
7222		ErrorF("[%04X]: %08lX %08lX %08lX %08lX\n",i,
7223			XGIMMIOLONG(i),
7224			XGIMMIOLONG(i+4),
7225			XGIMMIOLONG(i+8),
7226			XGIMMIOLONG(i+12)) ;
7227	}
7228*/
7229}
7230#endif /* DEBUG */
7231
7232void
7233XGIDumpRegs(ScrnInfoPtr pScrn)
7234{
7235#ifdef DEBUG
7236
7237    XGIPtr pXGI = XGIPTR(pScrn);
7238
7239    XGIDumpSR(pScrn);
7240    XGIDumpCR(pScrn);
7241//      XGIDumpGR(pScrn);
7242//      XGIDumpPalette(pScrn);
7243    XGIDumpMMIO(pScrn);
7244
7245	/*
7246    if (pXGI->Chipset != PCI_CHIP_XGIXG20) {
7247        XGIDumpPart0(pScrn);
7248        XGIDumpPart05(pScrn);
7249        XGIDumpPart1(pScrn);
7250        XGIDumpPart2(pScrn);
7251        XGIDumpPart3(pScrn);
7252        XGIDumpPart4(pScrn);
7253    } */
7254
7255#endif /* DEBUG */
7256}
7257
7258
7259void
7260XGIDumpPalette(ScrnInfoPtr pScrn)
7261{
7262#ifdef DEBUG
7263    XGIPtr pXGI = XGIPTR(pScrn);
7264    unsigned temp[3];
7265    int i, j;
7266
7267    ErrorF
7268        ("----------------------------------------------------------------------\n");
7269    ErrorF("Palette \n");
7270    ErrorF
7271        ("----------------------------------------------------------------------\n");
7272    for (i = 0; i < 0xFF; i += 0x04) {
7273        for (j = 0; j < 16; j++) {
7274            /* outb(0x3c7, i + j); */
7275            outb(XGISR+3, i + j);
7276
7277			/*
7278            temp[0] = inb(0x3c9);
7279            temp[1] = inb(0x3c9);
7280            temp[2] = inb(0x3c9); */
7281            temp[0] = inb(XGISR+5);
7282            temp[1] = inb(XGISR+5);
7283            temp[2] = inb(XGISR+5);
7284
7285            ErrorF("PA[%02X]: %02X %02X %02X", i + j,
7286                   temp[0], temp[1], temp[2]);
7287        }
7288        ErrorF("\n");
7289    }
7290    ErrorF("\n");
7291#endif
7292}
7293
7294