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