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