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