mga_driver.c revision a31a186a
1/* $XConsortium: mga_driver.c /main/12 1996/10/28 05:13:26 kaleb $ */
2/*
3 * MGA Millennium (MGA2064W) with Ti3026 RAMDAC driver v.1.1
4 *
5 * The driver is written without any chip documentation. All extended ports
6 * and registers come from tracing the VESA-ROM functions.
7 * The BitBlt Engine comes from tracing the windows BitBlt function.
8 *
9 * Author:	Radoslaw Kapitan, Tarnow, Poland
10 *			kapitan@student.uci.agh.edu.pl
11 *		original source
12 *
13 * Now that MATROX has released documentation to the public, enhancing
14 * this driver has become much easier. Nevertheless, this work continues
15 * to be based on Radoslaw's original source
16 *
17 * Contributors:
18 *		Andrew van der Stock
19 *			ajv@greebo.net
20 *		additions, corrections, cleanups
21 *
22 *		Dirk Hohndel
23 *			hohndel@XFree86.Org
24 *		integrated into XFree86-3.1.2Gg
25 *		fixed some problems with PCI probing and mapping
26 *
27 *		David Dawes
28 *			dawes@XFree86.Org
29 *		some cleanups, and fixed some problems
30 *
31 *		Andrew E. Mileski
32 *			aem@ott.hookup.net
33 *		RAMDAC timing, and BIOS stuff
34 *
35 *		Leonard N. Zubkoff
36 *			lnz@dandelion.com
37 *		Support for 8MB boards, RGB Sync-on-Green, and DPMS.
38 *		Guy DESBIEF
39 *			g.desbief@aix.pacwan.net
40 *		RAMDAC MGA1064 timing,
41 *		Doug Merritt
42 *			doug@netcom.com
43 *		Fixed 32bpp hires 8MB horizontal line glitch at middle right
44 *		Niels Gram Jeppesen
45 *		Added digital screen option for first head
46 */
47
48#ifdef HAVE_CONFIG_H
49#include "config.h"
50#endif
51
52/* All drivers should typically include these */
53#include "xf86.h"
54#include "xf86_OSproc.h"
55
56#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
57#include "xf86Resources.h"
58#include "xf86RAC.h"
59#endif
60
61/* All drivers need this */
62
63#include "compiler.h"
64
65/* Drivers for PCI hardware need this */
66#include "xf86PciInfo.h"
67
68/* Drivers that need to access the PCI config space directly need this */
69#ifndef XSERVER_LIBPCIACCESS
70#include "xf86Pci.h"
71#endif
72
73/* All drivers initialising the SW cursor need this */
74#include "mipointer.h"
75
76/* All drivers implementing backing store need this */
77#include "mibstore.h"
78
79#include "micmap.h"
80
81#include "xf86DDC.h"
82
83#include "vbe.h"
84
85#include "fb.h"
86#include "dixstruct.h"
87
88#include "mga_reg.h"
89#include "mga.h"
90#include "mga_macros.h"
91#include "mga_maven.h"
92
93#ifdef USE_XAA
94#include "xaa.h"
95#endif
96
97#include "xf86cmap.h"
98#include "shadowfb.h"
99#include "fbdevhw.h"
100
101#ifdef XF86DRI
102#include "dri.h"
103#endif
104
105#include <unistd.h>
106
107/*
108 * Forward definitions for the functions that make up the driver.
109 */
110
111/* Mandatory functions */
112static const OptionInfoRec *	MGAAvailableOptions(int chipid, int busid);
113static void	MGAIdentify(int flags);
114#ifdef XSERVER_LIBPCIACCESS
115static Bool MGAPciProbe(DriverPtr drv, int entity_num,
116    struct pci_device * dev, intptr_t match_data);
117#else
118static Bool	MGAProbe(DriverPtr drv, int flags);
119#endif
120static Bool	MGAPreInit(ScrnInfoPtr pScrn, int flags);
121static Bool	MGAScreenInit(int Index, ScreenPtr pScreen, int argc,
122			      char **argv);
123static Bool	MGAEnterVT(int scrnIndex, int flags);
124static Bool	MGAEnterVTFBDev(int scrnIndex, int flags);
125static void	MGALeaveVT(int scrnIndex, int flags);
126static Bool	MGACloseScreen(int scrnIndex, ScreenPtr pScreen);
127static Bool	MGASaveScreen(ScreenPtr pScreen, int mode);
128static Bool	MGASaveScreenCrtc2(ScreenPtr pScreen, int mode);
129
130/* This shouldn't be needed since RAC will disable all I/O for MGA cards. */
131#ifdef DISABLE_VGA_IO
132static void     VgaIOSave(int i, void *arg);
133static void     VgaIORestore(int i, void *arg);
134#endif
135
136/* Optional functions */
137static void	MGAFreeScreen(int scrnIndex, int flags);
138static ModeStatus MGAValidMode(int scrnIndex, DisplayModePtr mode,
139			       Bool verbose, int flags);
140
141#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ >= 4)
142#define __must_check  __attribute__((warn_unused_result))
143#else
144#define __must_check  /* */
145#endif
146
147/* Internally used functions */
148static Bool __must_check MGAMapMem(ScrnInfoPtr pScrn);
149static Bool	MGAUnmapMem(ScrnInfoPtr pScrn);
150static void	MGASave(ScrnInfoPtr pScrn);
151static void	MGARestore(ScrnInfoPtr pScrn);
152static Bool	MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
153static void 	MGABlockHandler(int, pointer, pointer, pointer);
154static void	MGAG100BlackMagic(ScrnInfoPtr pScrn);
155
156static int MGAEntityIndex = -1;
157
158#include "mga_merge.h"
159
160static const struct mga_device_attributes attribs[] = {
161    /* 2064 */
162    [0] = { 1, 0, 0, 1, 0, 0, 0, 0, old_BARs,
163	    (BLK_OPAQUE_EXPANSION | FASTBLT_BUG | USE_LINEAR_EXPANSION),
164	{
165	    { 0, 0 },          /* System VCO frequencies */
166	    { 50000, 220000 }, /* Pixel VCO frequencies */
167	    { 0, 0 },          /* Video VCO frequencies */
168	    50000,             /* Memory clock */
169	    14318,             /* PLL reference frequency */
170	    0,                 /* Supports fast bitblt? */
171	    MGA_HOST_PCI       /* Host interface */
172	},
173
174	8192, 0x1000,          /* Memory probe size & offset values */
175    },
176
177    /* 1064 */
178    [1] = { 0, 1, 0, 0, 1, 0, 0, 0, probe_BARs,
179            (USE_LINEAR_EXPANSION),
180	{
181	    /* There used to be code in MGARamdacInit (mga_dacG.c) that would
182	     * set this to 170000 if the chip revision was less than 3.  Is
183	     * that needed here?
184	     */
185	    { 50000, 230000 }, /* System VCO frequencies */
186	    { 50000, 230000 }, /* Pixel VCO frequencies */
187	    { 0, 0 },          /* Video VCO frequencies */
188	    50000,             /* Memory clock */
189	    14318,             /* PLL reference frequency */
190	    0,                 /* Supports fast bitblt? */
191	    MGA_HOST_PCI       /* Host interface */
192	},
193
194	8192, 0x1000,          /* Memory probe size & offset values */
195    },
196
197    /* 2164 */
198    [2] = { 1, 0, 0, 1, 0, 0, 0, 0, new_BARs,
199            (BLK_OPAQUE_EXPANSION | TRANSC_SOLID_FILL | USE_RECTS_FOR_LINES
200	     | USE_LINEAR_EXPANSION),
201	{
202	    { 0, 0 },          /* System VCO frequencies */
203	    { 50000, 220000 }, /* Pixel VCO frequencies */
204	    { 0, 0 },          /* Video VCO frequencies */
205	    50000,             /* Memory clock */
206	    14318,             /* PLL reference frequency */
207	    0,                 /* Supports fast bitblt? */
208	    MGA_HOST_PCI       /* Host interface */
209	},
210
211	8192, 0x1000,          /* Memory probe size & offset values */
212    },
213
214    /* 2164 AGP */
215    [3] = { 1, 0, 0, 1, 0, 0, 0, 0, new_BARs,
216            (BLK_OPAQUE_EXPANSION | TRANSC_SOLID_FILL | USE_RECTS_FOR_LINES
217	     | USE_LINEAR_EXPANSION),
218	{
219	    { 0, 0 },          /* System VCO frequencies */
220	    { 50000, 220000 }, /* Pixel VCO frequencies */
221	    { 0, 0 },          /* Video VCO frequencies */
222	    50000,             /* Memory clock */
223	    14318,             /* PLL reference frequency */
224	    0,                 /* Supports fast bitblt? */
225	    MGA_HOST_AGP_1x    /* Host interface */
226	},
227
228	8192, 0x1000,          /* Memory probe size & offset values */
229    },
230
231    /* G100 PCI */
232    [4] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs,
233            (MGA_NO_PLANEMASK | USE_LINEAR_EXPANSION),
234	{
235	    { 50000, 230000 }, /* System VCO frequencies */
236	    { 50000, 230000 }, /* Pixel VCO frequencies */
237	    { 0, 0 },          /* Video VCO frequencies */
238	    50000,             /* Memory clock */
239	    27050,             /* PLL reference frequency */
240	    0,                 /* Supports fast bitblt? */
241	    MGA_HOST_PCI       /* Host interface */
242	},
243
244	8192, 0x1000,          /* Memory probe size & offset values */
245    },
246
247    /* G100 AGP */
248    [5] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs,
249            (MGA_NO_PLANEMASK | USE_LINEAR_EXPANSION),
250	{
251	    { 50000, 230000 }, /* System VCO frequencies */
252	    { 50000, 230000 }, /* Pixel VCO frequencies */
253	    { 0, 0 },          /* Video VCO frequencies */
254	    50000,             /* Memory clock */
255	    27050,             /* PLL reference frequency */
256	    0,                 /* Supports fast bitblt? */
257	    MGA_HOST_AGP_1x    /* Host interface */
258	},
259
260	8192, 0x1000,          /* Memory probe size & offset values */
261    },
262
263    /* G200 PCI */
264    [6] = { 0, 1, 0, 0, 1, 1, 1, 1, new_BARs,
265            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
266	{
267	    { 50000, 230000 }, /* System VCO frequencies */
268	    { 50000, 230000 }, /* Pixel VCO frequencies */
269	    { 0, 0 },          /* Video VCO frequencies */
270	    50000,             /* Memory clock */
271	    27050,             /* PLL reference frequency */
272	    0,                 /* Supports fast bitblt? */
273	    MGA_HOST_PCI       /* Host interface */
274	},
275
276	8192, 0x1000,          /* Memory probe size & offset values */
277    },
278
279    /* G200 AGP */
280    [7] = { 0, 1, 0, 0, 1, 1, 1, 1, new_BARs,
281            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
282	{
283	    { 50000, 230000 }, /* System VCO frequencies */
284	    { 50000, 230000 }, /* Pixel VCO frequencies */
285	    { 0, 0 },          /* Video VCO frequencies */
286	    50000,             /* Memory clock */
287	    27050,             /* PLL reference frequency */
288	    0,                 /* Supports fast bitblt? */
289	    MGA_HOST_AGP_2x    /* Host interface */
290	},
291
292	8192, 0x1000,          /* Memory probe size & offset values */
293    },
294
295    /* G400 / G450 */
296    [8] = { 0, 1, 1, 0, 1, 1, 2, 1, new_BARs,
297            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
298	{
299	    { 50000, 252000 }, /* System VCO frequencies */
300	    { 50000, 252000 }, /* Pixel VCO frequencies */
301	    { 0, 0 },          /* Video VCO frequencies */
302	    200000,            /* Memory clock */
303	    27050,             /* PLL reference frequency */
304	    0,                 /* Supports fast bitblt? */
305	    MGA_HOST_AGP_4x    /* Host interface */
306	},
307
308	32768, 0x1000,         /* Memory probe size & offset values */
309    },
310
311    /* G550 */
312    [9] = { 0, 1, 1, 0, 1, 1, 2, 1, new_BARs,
313            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
314	{
315	    { 256000, 600000 }, /* System VCO frequencies */
316	    { 256000, 600000 }, /* Pixel VCO frequencies */
317	    { 256000, 600000 }, /* Video VCO frequencies */
318	    284000,            /* Memory clock */
319	    27050,             /* PLL reference frequency */
320	    0,                 /* Supports fast bitblt? */
321	    MGA_HOST_AGP_4x    /* Host interface */
322	},
323
324	32768, 0x1000,         /* Memory probe size & offset values */
325    },
326
327    /* G200SE A PCI */
328    [10] = { 0, 1, 0, 0, 1, 0, 0, 1, new_BARs,
329            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
330	{
331	    { 50000, 230000 }, /* System VCO frequencies */
332	    { 50000, 230000 }, /* Pixel VCO frequencies */
333	    { 0, 0 },          /* Video VCO frequencies */
334	    50000,            /* Memory clock */
335	    27050,             /* PLL reference frequency */
336	    0,                 /* Supports fast bitblt? */
337	    MGA_HOST_PCI       /* Host interface */
338	},
339
340	4096, 0x800,           /* Memory probe size & offset values */
341    },
342
343    /* G200SE B PCI */
344    [11] = { 0, 1, 0, 0, 1, 0, 0, 1, new_BARs,
345            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
346	{
347	    { 50000, 114000 }, /* System VCO frequencies */
348	    { 50000, 114000 }, /* Pixel VCO frequencies */
349	    { 0, 0 },          /* Video VCO frequencies */
350	    45000,            /* Memory clock */
351	    27050,             /* PLL reference frequency */
352	    0,                 /* Supports fast bitblt? */
353	    MGA_HOST_PCI       /* Host interface */
354	},
355
356	4096, 0x800,           /* Memory probe size & offset values */
357    },
358
359    /* G200EV */
360    [12] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs,
361            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
362	{
363	    { 50000, 230000 }, /* System VCO frequencies */
364	    { 50000, 230000 }, /* Pixel VCO frequencies */
365	    { 0, 0 },          /* Video VCO frequencies */
366	    45000,            /* Memory clock */
367	    27050,             /* PLL reference frequency */
368	    0,                 /* Supports fast bitblt? */
369	    MGA_HOST_PCI       /* Host interface */
370	},
371
372	16384, 0x4000,          /* Memory probe size & offset values */
373    },
374
375    /* G200WB */
376    [13] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs,
377            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
378	{
379	    { 50000, 230000 }, /* System VCO frequencies */
380	    { 50000, 203400 }, /* Pixel VCO frequencies */
381	    { 0, 0 },          /* Video VCO frequencies */
382	    45000,            /* Memory clock */
383	    27050,             /* PLL reference frequency */
384	    0,                 /* Supports fast bitblt? */
385	    MGA_HOST_PCI       /* Host interface */
386	},
387
388	8192, 0x4000,          /* Memory probe size & offset values */
389    },
390
391    /* G200EH */
392    [14] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs,
393            (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
394	{
395	    { 50000, 230000 }, /* System VCO frequencies */
396	    { 50000, 203400 }, /* Pixel VCO frequencies */
397	    { 0, 0 },          /* Video VCO frequencies */
398	    45000,            /* Memory clock */
399	    27050,             /* PLL reference frequency */
400	    0,                 /* Supports fast bitblt? */
401	    MGA_HOST_PCI       /* Host interface */
402	},
403
404	8192, 0x4000,          /* Memory probe size & offset values */
405    },
406
407};
408
409#ifdef XSERVER_LIBPCIACCESS
410#define MGA_DEVICE_MATCH(d, i) \
411    { 0x102B, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
412#define MGA_SUBDEVICE_MATCH(d, s, i) \
413    { 0x102B, (d), 0x102B, (s), 0, 0, (i) }
414
415static const struct pci_id_match mga_device_match[] = {
416    MGA_DEVICE_MATCH(PCI_CHIP_MGA2064,     0),
417    MGA_DEVICE_MATCH(PCI_CHIP_MGA1064,     1),
418    MGA_DEVICE_MATCH(PCI_CHIP_MGA2164,     2),
419    MGA_DEVICE_MATCH(PCI_CHIP_MGA2164_AGP, 3),
420    MGA_DEVICE_MATCH(PCI_CHIP_MGAG100,     4),
421    MGA_DEVICE_MATCH(PCI_CHIP_MGAG100_PCI, 5),
422    MGA_DEVICE_MATCH(PCI_CHIP_MGAG200,     6),
423    MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_PCI, 7),
424    MGA_DEVICE_MATCH(PCI_CHIP_MGAG400,     8),
425    MGA_DEVICE_MATCH(PCI_CHIP_MGAG550,     9),
426
427    MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_SE_A_PCI, 10),
428    MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_SE_B_PCI, 11),
429
430    MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_EV_PCI, 12),
431
432    MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_WINBOND_PCI, 13 ),
433
434    MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_EH_PCI, 14 ),
435
436    { 0, 0, 0 },
437};
438#endif
439
440/* Supported chipsets */
441static SymTabRec MGAChipsets[] = {
442    { PCI_CHIP_MGA2064,		"mga2064w" },
443    { PCI_CHIP_MGA1064,		"mga1064sg" },
444    { PCI_CHIP_MGA2164,		"mga2164w" },
445    { PCI_CHIP_MGA2164_AGP,	"mga2164w AGP" },
446    { PCI_CHIP_MGAG100,		"mgag100" },
447    { PCI_CHIP_MGAG100_PCI,	"mgag100 PCI" },
448    { PCI_CHIP_MGAG200,		"mgag200" },
449    { PCI_CHIP_MGAG200_PCI,	"mgag200 PCI" },
450    { PCI_CHIP_MGAG200_SE_A_PCI,	"mgag200 SE A PCI" },
451    { PCI_CHIP_MGAG200_SE_B_PCI,	"mgag200 SE B PCI" },
452    { PCI_CHIP_MGAG200_EV_PCI,	"mgag200 EV Maxim" },
453    { PCI_CHIP_MGAG200_WINBOND_PCI,	"mgag200 eW Nuvoton" },
454    { PCI_CHIP_MGAG200_EH_PCI,	"mgag200eH" },
455    { PCI_CHIP_MGAG400,		"mgag400" },
456    { PCI_CHIP_MGAG550,		"mgag550" },
457    {-1,			NULL }
458};
459
460static PciChipsets MGAPciChipsets[] = {
461    { PCI_CHIP_MGA2064,	    PCI_CHIP_MGA2064,	RES_SHARED_VGA },
462    { PCI_CHIP_MGA1064,	    PCI_CHIP_MGA1064,	RES_SHARED_VGA },
463    { PCI_CHIP_MGA2164,	    PCI_CHIP_MGA2164,	RES_SHARED_VGA },
464    { PCI_CHIP_MGA2164_AGP, PCI_CHIP_MGA2164_AGP,RES_SHARED_VGA },
465    { PCI_CHIP_MGAG100,	    PCI_CHIP_MGAG100,	RES_SHARED_VGA },
466    { PCI_CHIP_MGAG100_PCI, PCI_CHIP_MGAG100_PCI,RES_SHARED_VGA },
467    { PCI_CHIP_MGAG200,	    PCI_CHIP_MGAG200,	RES_SHARED_VGA },
468    { PCI_CHIP_MGAG200_PCI, PCI_CHIP_MGAG200_PCI,RES_SHARED_VGA },
469    { PCI_CHIP_MGAG200_SE_B_PCI, PCI_CHIP_MGAG200_SE_B_PCI,
470	RES_SHARED_VGA },
471    { PCI_CHIP_MGAG200_SE_A_PCI, PCI_CHIP_MGAG200_SE_A_PCI,
472	RES_SHARED_VGA },
473    { PCI_CHIP_MGAG200_EV_PCI, PCI_CHIP_MGAG200_EV_PCI,
474	RES_SHARED_VGA },
475    { PCI_CHIP_MGAG200_WINBOND_PCI, PCI_CHIP_MGAG200_WINBOND_PCI,
476	RES_SHARED_VGA },
477    { PCI_CHIP_MGAG200_EH_PCI, PCI_CHIP_MGAG200_EH_PCI,
478	RES_SHARED_VGA },
479    { PCI_CHIP_MGAG400,	    PCI_CHIP_MGAG400,	RES_SHARED_VGA },
480    { PCI_CHIP_MGAG550,	    PCI_CHIP_MGAG550,	RES_SHARED_VGA },
481    { -1,			-1,		RES_UNDEFINED }
482};
483
484/*
485 * This contains the functions needed by the server after loading the
486 * driver module.  It must be supplied, and gets added the driver list by
487 * the Module Setup funtion in the dynamic case.  In the static case a
488 * reference to this is compiled in, and this requires that the name of
489 * this DriverRec be an upper-case version of the driver name.
490 */
491
492_X_EXPORT DriverRec MGA_C_NAME = {
493    MGA_VERSION,
494    MGA_DRIVER_NAME,
495    MGAIdentify,
496#ifdef XSERVER_LIBPCIACCESS
497    NULL,
498#else
499    MGAProbe,
500#endif
501    MGAAvailableOptions,
502    NULL,
503    0,
504    NULL,
505
506#ifdef XSERVER_LIBPCIACCESS
507    mga_device_match,
508    MGAPciProbe
509#endif
510};
511
512
513static const OptionInfoRec MGAOptions[] = {
514    { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
515    { OPTION_HW_CURSOR,		"HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
516    { OPTION_PCI_RETRY,		"PciRetry",	OPTV_BOOLEAN,	{0}, FALSE },
517    { OPTION_SYNC_ON_GREEN,	"SyncOnGreen",	OPTV_BOOLEAN,	{0}, FALSE },
518    { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
519    { OPTION_SHOWCACHE,		"ShowCache",	OPTV_BOOLEAN,	{0}, FALSE },
520    { OPTION_MGA_SDRAM,		"MGASDRAM",	OPTV_BOOLEAN,	{0}, FALSE },
521    { OPTION_SHADOW_FB,		"ShadowFB",	OPTV_BOOLEAN,	{0}, FALSE },
522    { OPTION_FBDEV,		"UseFBDev",	OPTV_BOOLEAN,	{0}, FALSE },
523    { OPTION_COLOR_KEY,		"ColorKey",	OPTV_INTEGER,	{0}, FALSE },
524    { OPTION_SET_MCLK,		"SetMclk",	OPTV_FREQ,	{0}, FALSE },
525    { OPTION_OVERCLOCK_MEM,	"OverclockMem",	OPTV_BOOLEAN,	{0}, FALSE },
526    { OPTION_VIDEO_KEY,		"VideoKey",	OPTV_INTEGER,	{0}, FALSE },
527    { OPTION_ROTATE,		"Rotate",	OPTV_ANYSTR,	{0}, FALSE },
528    { OPTION_TEXTURED_VIDEO,	"TexturedVideo",OPTV_BOOLEAN,	{0}, FALSE },
529    { OPTION_CRTC2HALF,		"Crtc2Half",	OPTV_BOOLEAN,	{0}, FALSE },
530    { OPTION_CRTC2RAM,		"Crtc2Ram",	OPTV_INTEGER,	{0}, FALSE },
531    { OPTION_INT10,		"Int10",	OPTV_BOOLEAN,	{0}, FALSE },
532    { OPTION_AGP_MODE,		"AGPMode",	OPTV_INTEGER,	{0}, FALSE },
533    { OPTION_AGP_SIZE,		"AGPSize",      OPTV_INTEGER,   {0}, FALSE },
534    { OPTION_DIGITAL1,		"DigitalScreen1",OPTV_BOOLEAN,	{0}, FALSE },
535    { OPTION_DIGITAL2,		"DigitalScreen2",OPTV_BOOLEAN,	{0}, FALSE },
536    { OPTION_TV,		"TV",		OPTV_BOOLEAN,	{0}, FALSE },
537    { OPTION_TVSTANDARD,	"TVStandard",	OPTV_ANYSTR,	{0}, FALSE },
538    { OPTION_CABLETYPE,		"CableType",	OPTV_ANYSTR,	{0}, FALSE },
539    { OPTION_NOHAL,		"NoHal",	OPTV_BOOLEAN,	{0}, FALSE },
540    { OPTION_SWAPPED_HEAD,	"SwappedHead",	OPTV_BOOLEAN,	{0}, FALSE },
541    { OPTION_DRI,		"DRI",		OPTV_BOOLEAN,	{0}, FALSE },
542    { OPTION_MERGEDFB,		"MergedFB",	OPTV_BOOLEAN,	{0}, FALSE },
543    { OPTION_HSYNC2,	"Monitor2HSync",	OPTV_ANYSTR,	{0}, FALSE },
544    { OPTION_VREFRESH2,	"Monitor2VRefresh",	OPTV_ANYSTR,	{0}, FALSE },
545    { OPTION_MONITOR2POS,   "Monitor2Position",	OPTV_ANYSTR,	{0}, FALSE },
546    { OPTION_METAMODES,   "MetaModes",  	OPTV_ANYSTR,	{0}, FALSE },
547    { OPTION_OLDDMA,		"OldDmaInit",	OPTV_BOOLEAN,	{0}, FALSE },
548    { OPTION_PCIDMA,		"ForcePciDma",	OPTV_BOOLEAN,	{0}, FALSE },
549    { OPTION_ACCELMETHOD,	"AccelMethod",	OPTV_ANYSTR,	{0}, FALSE },
550    { OPTION_KVM,		"KVM",		OPTV_BOOLEAN,	{0}, FALSE },
551    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
552};
553
554#ifdef XFree86LOADER
555
556static MODULESETUPPROTO(mgaSetup);
557
558static XF86ModuleVersionInfo mgaVersRec =
559{
560	MGA_DRIVER_NAME,
561	MODULEVENDORSTRING,
562	MODINFOSTRING1,
563	MODINFOSTRING2,
564	XORG_VERSION_CURRENT,
565    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
566	ABI_CLASS_VIDEODRV,			/* This is a video driver */
567	ABI_VIDEODRV_VERSION,
568	MOD_CLASS_VIDEODRV,
569	{0,0,0,0}
570};
571
572_X_EXPORT XF86ModuleData MGA_MODULE_DATA = { &mgaVersRec, mgaSetup, NULL };
573
574static pointer
575mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
576{
577    static Bool setupDone = FALSE;
578
579    /* This module should be loaded only once, but check to be sure. */
580
581    if (!setupDone) {
582	setupDone = TRUE;
583	xf86AddDriver(&MGA_C_NAME, module, 1);
584	/*
585	 * The return value must be non-NULL on success even though there
586	 * is no TearDownProc.
587	 */
588	return (pointer)1;
589    } else {
590	if (errmaj) *errmaj = LDR_ONCEONLY;
591	return NULL;
592    }
593}
594
595
596#endif /* XFree86LOADER */
597
598/*
599 * ramdac info structure initialization
600 */
601static MGARamdacRec DacInit = {
602	FALSE, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
603	90000, /* maxPixelClock */
604	0, X_DEFAULT, X_DEFAULT, FALSE
605};
606
607Bool
608MGAGetRec(ScrnInfoPtr pScrn)
609{
610    /*
611     * Allocate an MGARec, and hook it into pScrn->driverPrivate.
612     * pScrn->driverPrivate is initialised to NULL, so we can check if
613     * the allocation has already been done.
614     */
615    if (pScrn->driverPrivate != NULL)
616	return TRUE;
617
618    pScrn->driverPrivate = xnfcalloc(sizeof(MGARec), 1);
619    /* Initialise it */
620
621    MGAPTR(pScrn)->Dac = DacInit;
622    return TRUE;
623}
624
625void
626MGAFreeRec(ScrnInfoPtr pScrn)
627{
628    if (pScrn->driverPrivate == NULL)
629	return;
630    xfree(pScrn->driverPrivate);
631    pScrn->driverPrivate = NULL;
632}
633
634static const OptionInfoRec *
635MGAAvailableOptions(int chipid, int busid)
636{
637    return MGAOptions;
638}
639
640/* Mandatory */
641static void
642MGAIdentify(int flags)
643{
644    xf86PrintChipsets(MGA_NAME, "driver for Matrox chipsets", MGAChipsets);
645}
646
647
648#ifdef XSERVER_LIBPCIACCESS
649Bool
650MGAPciProbe(DriverPtr drv, int entity_num, struct pci_device * dev,
651	    intptr_t match_data)
652{
653    ScrnInfoPtr pScrn = NULL;
654    EntityInfoPtr pEnt;
655    MGAPtr pMga;
656#ifdef DISABLE_VGA_IO
657    MgaSavePtr smga;
658
659
660    smga = xnfalloc(sizeof(MgaSave));
661    smga->pvp = dev;
662#endif
663
664    /* Allocate a ScrnInfoRec and claim the slot */
665    pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, MGAPciChipsets,
666				NULL,
667#ifndef DISABLE_VGA_IO
668				NULL, NULL, NULL, NULL
669#else
670				VgaIOSave, VgaIOSave, VgaIORestore, smga
671#endif
672				);
673    if (pScrn != NULL) {
674	/* Fill in what we can of the ScrnInfoRec */
675	pScrn->driverVersion	= MGA_VERSION;
676	pScrn->driverName	= MGA_DRIVER_NAME;
677	pScrn->name		= MGA_NAME;
678	pScrn->Probe		= NULL;
679	pScrn->PreInit		= MGAPreInit;
680	pScrn->ScreenInit	= MGAScreenInit;
681	pScrn->SwitchMode	= MGASwitchMode;
682	pScrn->AdjustFrame	= MGAAdjustFrame;
683	pScrn->EnterVT		= MGAEnterVT;
684	pScrn->LeaveVT		= MGALeaveVT;
685	pScrn->FreeScreen	= MGAFreeScreen;
686	pScrn->ValidMode	= MGAValidMode;
687
688
689	/* Allocate the MGARec driverPrivate */
690	if (!MGAGetRec(pScrn)) {
691	    return FALSE;
692	}
693
694	pMga = MGAPTR(pScrn);
695	pMga->chip_attribs = & attribs[ match_data ];
696	pMga->PciInfo = dev;
697
698
699	/*
700	 * For cards that can do dual head per entity, mark the entity
701	 * as sharable.
702	 */
703	pEnt = xf86GetEntityInfo(entity_num);
704	if (pMga->chip_attribs->dual_head_possible) {
705	    MGAEntPtr pMgaEnt = NULL;
706	    DevUnion *pPriv;
707
708	    xf86SetEntitySharable(entity_num);
709	    /* Allocate an entity private if necessary */
710	    if (MGAEntityIndex < 0)
711	      MGAEntityIndex = xf86AllocateEntityPrivateIndex();
712	    pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
713	    if (!pPriv->ptr) {
714		pPriv->ptr = xnfcalloc(sizeof(MGAEntRec), 1);
715		pMgaEnt = pPriv->ptr;
716		pMgaEnt->lastInstance = -1;
717	    } else {
718		pMgaEnt = pPriv->ptr;
719	    }
720	    /*
721	     * Set the entity instance for this instance of the driver.  For
722	     * dual head per card, instance 0 is the "master" instance, driving
723	     * the primary head, and instance 1 is the "slave".
724	     */
725	    pMgaEnt->lastInstance++;
726	    xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0],
727					   pMgaEnt->lastInstance);
728	}
729    }
730
731    return (pScrn != NULL);
732}
733
734#else
735
736/* Mandatory */
737static Bool
738MGAProbe(DriverPtr drv, int flags)
739{
740    int i;
741    GDevPtr *devSections;
742    int *usedChips = NULL;
743    int numDevSections;
744    int numUsed;
745    Bool foundScreen = FALSE;
746
747    /*
748     * The aim here is to find all cards that this driver can handle,
749     * and for the ones not already claimed by another driver, claim the
750     * slot, and allocate a ScrnInfoRec.
751     *
752     * This should be a minimal probe, and it should under no circumstances
753     * change the state of the hardware.  Because a device is found, don't
754     * assume that it will be used.  Don't do any initialisations other than
755     * the required ScrnInfoRec initialisations.  Don't allocate any new
756     * data structures.
757     */
758
759    /*
760     * Check if there has been a chipset override in the config file.
761     * For this we must find out if there is an active device section which
762     * is relevant, i.e., which has no driver specified or has THIS driver
763     * specified.
764     */
765
766    if ((numDevSections = xf86MatchDevice(MGA_DRIVER_NAME,
767					  &devSections)) <= 0) {
768	/*
769	 * There's no matching device section in the config file, so quit
770	 * now.
771	 */
772	return FALSE;
773    }
774
775    /*
776     * We need to probe the hardware first.  We then need to see how this
777     * fits in with what is given in the config file, and allow the config
778     * file info to override any contradictions.
779     */
780
781    /*
782     * All of the cards this driver supports are PCI, so the "probing" just
783     * amounts to checking the PCI data that the server has already collected.
784     */
785    if (xf86GetPciVideoInfo() == NULL) {
786	/*
787	 * We won't let anything in the config file override finding no
788	 * PCI video cards at all.  This seems reasonable now, but we'll see.
789	 */
790	return FALSE;
791    }
792
793    numUsed = xf86MatchPciInstances(MGA_NAME, PCI_VENDOR_MATROX,
794			            MGAChipsets, MGAPciChipsets, devSections,
795			            numDevSections, drv, &usedChips);
796    /* Free it since we don't need that list after this */
797    xfree(devSections);
798    if (numUsed <= 0)
799	return FALSE;
800
801
802    if (flags & PROBE_DETECT)
803	foundScreen = TRUE;
804    else for (i = 0; i < numUsed; i++) {
805	ScrnInfoPtr pScrn = NULL;
806	EntityInfoPtr pEnt;
807	int attrib_no;
808#ifdef DISABLE_VGA_IO
809	MgaSavePtr smga;
810#endif
811
812	/* Allocate a ScrnInfoRec and claim the slot */
813#ifndef DISABLE_VGA_IO
814	pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
815				    MGAPciChipsets, NULL, NULL,
816				    NULL, NULL, NULL);
817#else
818	smga = xnfalloc(sizeof(MgaSave));
819	smga->pvp = xf86GetPciInfoForEntity(usedChips[i]);
820	pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
821				    MGAPciChipsets, NULL,VgaIOSave,
822				    VgaIOSave, VgaIORestore,smga);
823#endif
824        if (pScrn != NULL) {
825	    MGAPtr pMga;
826
827	    /* Fill in what we can of the ScrnInfoRec */
828	    pScrn->driverVersion = MGA_VERSION;
829	    pScrn->driverName	= MGA_DRIVER_NAME;
830	    pScrn->name		= MGA_NAME;
831	    pScrn->Probe	= MGAProbe;
832	    pScrn->PreInit	= MGAPreInit;
833	    pScrn->ScreenInit	= MGAScreenInit;
834	    pScrn->SwitchMode	= MGASwitchMode;
835	    pScrn->AdjustFrame	= MGAAdjustFrame;
836	    pScrn->EnterVT	= MGAEnterVT;
837	    pScrn->LeaveVT	= MGALeaveVT;
838	    pScrn->FreeScreen	= MGAFreeScreen;
839	    pScrn->ValidMode	= MGAValidMode;
840
841	    foundScreen = TRUE;
842
843	    /* Allocate the MGARec driverPrivate */
844	    if (!MGAGetRec(pScrn)) {
845		return FALSE;
846	    }
847
848	    pMga = MGAPTR(pScrn);
849
850	    /*
851	     * For cards that can do dual head per entity, mark the entity
852	     * as sharable.
853	     */
854	    pEnt = xf86GetEntityInfo(usedChips[i]);
855
856            switch (pEnt->chipset) {
857            case PCI_CHIP_MGA2064:
858                attrib_no = 0;
859                break;
860
861            case PCI_CHIP_MGA1064:
862                attrib_no = 1;
863                break;
864
865            case PCI_CHIP_MGA2164:
866                attrib_no = 2;
867                break;
868
869            case PCI_CHIP_MGA2164_AGP:
870                attrib_no = 3;
871                break;
872
873            case PCI_CHIP_MGAG100:
874                attrib_no = 4;
875                break;
876
877            case PCI_CHIP_MGAG100_PCI:
878                attrib_no = 5;
879                break;
880
881            case PCI_CHIP_MGAG200:
882                attrib_no = 6;
883                break;
884
885            case PCI_CHIP_MGAG200_PCI:
886                attrib_no = 7;
887                break;
888
889            case PCI_CHIP_MGAG400:
890                attrib_no = 8;
891                break;
892
893            case PCI_CHIP_MGAG550:
894                attrib_no = 9;
895                break;
896
897            case PCI_CHIP_MGAG200_SE_A_PCI:
898                attrib_no = 10;
899                break;
900
901            case PCI_CHIP_MGAG200_SE_B_PCI:
902                attrib_no = 11;
903                break;
904
905            case PCI_CHIP_MGAG200_EV_PCI:
906                attrib_no = 12;
907                break;
908
909            case PCI_CHIP_MGAG200_WINBOND_PCI:
910                attrib_no = 13;
911                break;
912
913            case PCI_CHIP_MGAG200_EH_PCI:
914                attrib_no = 14;
915                break;
916
917	    default:
918		return FALSE;
919            }
920
921	    pMga->chip_attribs = & attribs[attrib_no];
922
923	    if (pMga->chip_attribs->dual_head_possible) {
924		MGAEntPtr pMgaEnt = NULL;
925		DevUnion *pPriv;
926
927		xf86SetEntitySharable(usedChips[i]);
928		/* Allocate an entity private if necessary */
929		if (MGAEntityIndex < 0)
930		    MGAEntityIndex = xf86AllocateEntityPrivateIndex();
931		pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
932		if (!pPriv->ptr) {
933		    pPriv->ptr = xnfcalloc(sizeof(MGAEntRec), 1);
934		    pMgaEnt = pPriv->ptr;
935		    pMgaEnt->lastInstance = -1;
936		} else {
937		    pMgaEnt = pPriv->ptr;
938		}
939		/*
940		 * Set the entity instance for this instance of the driver.  For
941		 * dual head per card, instance 0 is the "master" instance, driving
942		 * the primary head, and instance 1 is the "slave".
943		 */
944		pMgaEnt->lastInstance++;
945		xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0],
946					       pMgaEnt->lastInstance);
947	    }
948        }
949    }
950    xfree(usedChips);
951
952    return foundScreen;
953}
954#endif
955
956
957/*
958 * MGASoftReset --
959 *
960 * Resets drawing engine
961 */
962void
963MGASoftReset(ScrnInfoPtr pScrn)
964{
965	MGAPtr pMga = MGAPTR(pScrn);
966
967	pMga->FbMapSize = 8192 * 1024;
968	MGAMapMem(pScrn);
969
970	/* set soft reset bit */
971	OUTREG(MGAREG_Reset, 1);
972	usleep(200);
973	OUTREG(MGAREG_Reset, 0);
974
975	/* reset memory */
976	OUTREG(MGAREG_MACCESS, 1<<15);
977	usleep(10);
978
979#if 0
980	/* This will hang if the PLLs aren't on */
981
982	/* wait until drawing engine is ready */
983	while ( MGAISBUSY() )
984	    usleep(1000);
985
986	/* flush FIFO */
987	i = 32;
988	WAITFIFO(i);
989	while ( i-- )
990	    OUTREG(MGAREG_SHIFT, 0);
991#endif
992
993	MGAUnmapMem(pScrn);
994}
995
996/*
997 * MGACountRAM --
998 *
999 * Counts amount of installed RAM
1000 */
1001static int
1002MGACountRam(ScrnInfoPtr pScrn)
1003{
1004    MGAPtr pMga = MGAPTR(pScrn);
1005    int ProbeSize = pMga->chip_attribs->probe_size;
1006    int ProbeSizeOffset = pMga->chip_attribs->probe_offset;
1007    int SizeFound = 2048;
1008    CARD32 biosInfo = 0;
1009    CARD8 seq1;
1010
1011#if 0
1012    /* This isn't correct. It looks like this can have arbitrary
1013	data for the memconfig even when the bios has initialized
1014	it.  At least, my cards don't advertise the documented
1015	values (my 8 and 16 Meg G200s have the same values) */
1016    if (pMga->Primary) { /* can only trust this for primary cards */
1017#ifdef XSERVER_LIBPCIACCESS
1018	pci_device_cfg_read_u32(pMga->PciInfo, & biosInfo,
1019				PCI_OPTION_REG);
1020#else
1021	biosInfo = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
1022#endif
1023    }
1024#endif
1025
1026    switch(pMga->Chipset) {
1027    case PCI_CHIP_MGA2164:
1028    case PCI_CHIP_MGA2164_AGP:
1029	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1030		"Unable to probe memory amount due to hardware bug.  "
1031		"Assuming 4096 KB\n");
1032	return 4096;
1033    case PCI_CHIP_MGAG400:
1034    case PCI_CHIP_MGAG550:
1035	if(biosInfo) {
1036	    switch((biosInfo >> 10) & 0x07) {
1037	    case 0:
1038		return (biosInfo & (1 << 14)) ? 32768 : 16384;
1039	    case 1:
1040	    case 2:
1041		return 16384;
1042	    case 3:
1043	    case 5:
1044		return 65536;
1045	    case 4:
1046		return 32768;
1047	    }
1048	}
1049	break;
1050    case PCI_CHIP_MGAG200:
1051    case PCI_CHIP_MGAG200_PCI:
1052	if(biosInfo) {
1053	    switch((biosInfo >> 11) & 0x03) {
1054	    case 0:
1055		return 8192;
1056	    default:
1057		return 16384;
1058	    }
1059	}
1060	break;
1061    case PCI_CHIP_MGAG100:
1062    case PCI_CHIP_MGAG100_PCI:
1063	if(biosInfo) /* I'm not sure if the docs are correct */
1064	    return (biosInfo & (1 << 12)) ? 16384 : 8192;
1065        break;
1066    default:
1067        break;
1068    }
1069
1070    if (pMga->FbAddress) {
1071	volatile unsigned char* base;
1072	unsigned char tmp;
1073	int i;
1074
1075	pMga->FbMapSize = ProbeSize * 1024;
1076	if (!MGAMapMem(pScrn)) {
1077	    return 0;
1078	}
1079
1080	base = pMga->FbBase;
1081
1082	if (pMga->is_G200SE)
1083	    pMga->reg_1e24 = INREG(0x1e24); /* stash the model for later */
1084	if (pMga->reg_1e24 == 0x01) {
1085	    MGAUnmapMem(pScrn);
1086	    ProbeSize = 16384;
1087	    ProbeSizeOffset = 0x10000;
1088	    pMga->FbMapSize = ProbeSize * 1024;
1089	    MGAMapMem(pScrn);
1090	    base = pMga->FbBase;
1091	}
1092
1093	if (pMga->is_G200SE) {
1094	    OUTREG8(MGAREG_SEQ_INDEX, 0x01);
1095	    seq1 = INREG8(MGAREG_SEQ_DATA);
1096	    seq1 |= 0x20;
1097	    MGAWAITVSYNC();
1098	    MGAWAITBUSY();
1099	    OUTREG8(MGAREG_SEQ_DATA, seq1);
1100	    usleep(20000);
1101	}
1102
1103        if (pMga->is_G200WB) {
1104            CARD32 Option, MaxMapSize;
1105
1106#ifdef XSERVER_LIBPCIACCESS
1107            pci_device_cfg_read_u32(pMga->PciInfo, &Option,
1108                                    PCI_OPTION_REG);
1109            MaxMapSize = pMga->PciInfo->regions[0].size;
1110#else
1111            Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
1112            MaxMapSize = 1UL << pMga->PciInfo->size[0];
1113#endif
1114            Option = (Option & 0x3000000) >> 24 ;
1115
1116            if (Option == 2)
1117                ProbeSize = 4*1024;
1118            else if(Option == 1)
1119                ProbeSize = 8*1024;
1120            else if(Option == 0)
1121                ProbeSize = 16*1024;
1122
1123            if (ProbeSize * 1024 > MaxMapSize)
1124                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1125                        "Fb size from config space doesn't fit option register\n");
1126            else {
1127                MGAUnmapMem(pScrn);
1128                pMga->FbMapSize = ProbeSize * 1024;
1129                MGAMapMem(pScrn);
1130                base = pMga->FbBase;
1131            }
1132        }
1133
1134	/* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */
1135	OUTREG8(MGAREG_CRTCEXT_INDEX, 3);
1136	tmp = INREG8(MGAREG_CRTCEXT_DATA);
1137	OUTREG8(MGAREG_CRTCEXT_DATA, tmp | 0x80);
1138
1139	/* apparently the G200 IP don't have a BIOS to read */
1140	if (pMga->is_G200SE || pMga->is_G200EV || pMga->is_G200WB || pMga->is_G200EH) {
1141	    CARD32 MemoryAt0, MemoryAt1, Offset;
1142	    CARD32 FirstMemoryVal1, FirstMemoryVal2;
1143	    CARD32 SecondMemoryVal1, SecondMemoryVal2;
1144	    CARD32 TestMemoryLocA, TestMemoryLocB;
1145	    CARD32 TestMemoryLoc0, TestMemoryLoc1;
1146	    CARD32 TestA, TestB;
1147
1148	    MemoryAt0 = base[0];
1149	    MemoryAt1 = base[1];
1150	    base[0] = 0;
1151	    base[1] = 0;
1152
1153	    for (Offset = 0x100000; Offset < (ProbeSize * 1024);
1154		    Offset += ProbeSizeOffset) {
1155		FirstMemoryVal1 = base[Offset];
1156		FirstMemoryVal2 = base[Offset+1];
1157		SecondMemoryVal1 = base[Offset+0x100];
1158		SecondMemoryVal2 = base[Offset+0x101];
1159
1160		base[Offset] = 0x55;
1161		base[Offset+1] = 0xaa;
1162		base[Offset+0x100] = 0x55;
1163		base[Offset+0x101] = 0xaa;
1164
1165		OUTREG8(MGAREG_CRTC_INDEX, 0);
1166		usleep(8);
1167
1168		TestMemoryLocA = base[Offset];
1169		TestMemoryLocB = base[Offset+1];
1170		TestMemoryLoc0 = base[0];
1171		TestMemoryLoc1 = base[1];
1172
1173		base[Offset] = FirstMemoryVal1;
1174		base[Offset+1] = FirstMemoryVal2;
1175		base[Offset+0x100] = SecondMemoryVal1;
1176		base[Offset+0x101] = SecondMemoryVal2;
1177
1178		TestA = ((TestMemoryLocB << 8) + TestMemoryLocA);
1179		TestB = ((TestMemoryLoc1 << 8) + TestMemoryLoc0);
1180		if ((TestA != 0xAA55) || (TestB)) {
1181		    break;
1182		}
1183	    }
1184
1185	    base[0] = MemoryAt0;
1186	    base[1] = MemoryAt1;
1187
1188	    SizeFound = (Offset / 1024) - 64;
1189	} else {
1190	    /* write, read and compare method
1191	       split into two loops to make it more reliable on RS/6k -ReneR */
1192	    for(i = ProbeSize; i > 2048; i -= 2048) {
1193		base[(i * 1024) - 1] = 0xAA;
1194	    }
1195	    OUTREG8(MGAREG_CRTC_INDEX, 0);  /* flush the cache */
1196	    usleep(4);  /* twart write combination */
1197	    for(i = ProbeSize; i > 2048; i -= 2048) {
1198		if(base[(i * 1024) - 1] == 0xAA) {
1199		    SizeFound = i;
1200		    break;
1201		}
1202	    }
1203	}
1204
1205	/* restore CRTCEXT3 state */
1206	OUTREG8(MGAREG_CRTCEXT_INDEX, 3);
1207	OUTREG8(MGAREG_CRTCEXT_DATA, tmp);
1208
1209	if (pMga->is_G200SE) {
1210	    OUTREG8(MGAREG_SEQ_INDEX, 0x01);
1211	    seq1 = INREG8(MGAREG_SEQ_DATA);
1212	    seq1 &= ~0x20;
1213	    MGAWAITVSYNC();
1214	    MGAWAITBUSY();
1215	    OUTREG8(MGAREG_SEQ_DATA, seq1);
1216	    usleep(20000);
1217	}
1218	MGAUnmapMem(pScrn);
1219    }
1220   return SizeFound;
1221}
1222
1223#ifdef  EDID_COMPLETE_RAWDATA
1224#undef  xf86DoEDID_DDC2
1225#define xf86DoEDID_DDC2(a, b) xf86DoEEDID(a, b, TRUE)
1226#endif
1227
1228static xf86MonPtr
1229MGAdoDDC(ScrnInfoPtr pScrn)
1230{
1231    vgaHWPtr hwp;
1232    MGAPtr pMga;
1233    xf86MonPtr MonInfo = NULL;
1234    char *from = NULL;
1235
1236    hwp = VGAHWPTR(pScrn);
1237    pMga = MGAPTR(pScrn);
1238
1239    /* Load DDC if we have the code to use it */
1240    /* This gives us DDC1 */
1241    if (pMga->ddc1Read || pMga->i2cInit) {
1242	if (!xf86LoadSubModule(pScrn, "ddc")) {
1243	    /* ddc module not found, we can do without it */
1244	    pMga->ddc1Read = NULL;
1245	    pMga->DDC_Bus1 = NULL;
1246	    pMga->DDC_Bus2 = NULL;
1247	    return NULL;
1248	}
1249    } else
1250	return NULL;
1251
1252    /* - DDC can use I2C bus */
1253    /* Load I2C if we have the code to use it */
1254    if (pMga->i2cInit) {
1255	if (!xf86LoadSubModule(pScrn, "i2c")) {
1256	    /* i2c module not found, we can do without it */
1257	    pMga->i2cInit = NULL;
1258	    pMga->DDC_Bus1 = NULL;
1259	    pMga->DDC_Bus2 = NULL;
1260	}
1261    }
1262
1263    /* Map the MGA memory and MMIO areas */
1264    if (!MGAMapMem(pScrn))
1265	return NULL;
1266
1267    /* Initialise the MMIO vgahw functions */
1268    vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET);
1269    vgaHWGetIOBase(hwp);
1270
1271    /* Map the VGA memory when the primary video */
1272    if (pMga->Primary) {
1273	hwp->MapSize = 0x10000;
1274	if (!vgaHWMapMem(pScrn))
1275	    return NULL;
1276    } else {
1277	/* XXX Need to write an MGA mode ddc1SetSpeed */
1278	if (pMga->DDC1SetSpeed == vgaHWddc1SetSpeedWeak()) {
1279	    pMga->DDC1SetSpeed = NULL;
1280	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
1281			   "DDC1 disabled - chip not in VGA mode\n");
1282	}
1283    }
1284
1285    /* Save the current state */
1286    MGASave(pScrn);
1287
1288    /* It is now safe to talk to the card */
1289
1290    /* Initialize I2C buses - used by DDC if available */
1291    if (pMga->i2cInit) {
1292	pMga->i2cInit(pScrn);
1293    }
1294
1295    /* DDC for second head... */
1296    if (pMga->SecondCrtc && pMga->DDC_Bus2) {
1297	MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pMga->DDC_Bus2);
1298	from = "I2C";
1299    } else {
1300	/* Its the first head... */
1301	if (pMga->DDC_Bus1) {
1302	    MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pMga->DDC_Bus1);
1303	    from = "I2C";
1304	}
1305	if (!MonInfo)
1306	    /* Read and output monitor info using DDC1 */
1307	    if (pMga->ddc1Read && pMga->DDC1SetSpeed) {
1308		MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex,
1309					  pMga->DDC1SetSpeed,
1310					  pMga->ddc1Read ) ;
1311		from = "DDC1";
1312	    }
1313	if (!MonInfo){
1314	    vbeInfoPtr pVbe;
1315	    if (xf86LoadSubModule(pScrn, "vbe")) {
1316		pVbe = VBEInit(NULL, pMga->pEnt->index);
1317		MonInfo = vbeDoEDID(pVbe, NULL);
1318		vbeFree(pVbe);
1319		from = "VBE";
1320	    }
1321	}
1322    }
1323
1324    if (MonInfo) {
1325	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s monitor info\n", from);
1326	xf86PrintEDID(MonInfo);
1327	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of monitor info\n");
1328    }
1329
1330    /* Restore previous state and unmap MGA memory and MMIO areas */
1331    MGARestore(pScrn);
1332    MGAUnmapMem(pScrn);
1333    /* Unmap vga memory if we mapped it */
1334    if (xf86IsPrimaryPci(pMga->PciInfo) && !pMga->FBDev) {
1335	vgaHWUnmapMem(pScrn);
1336    }
1337
1338    xf86SetDDCproperties(pScrn, MonInfo);
1339
1340    return MonInfo;
1341}
1342
1343#ifdef DISABLE_VGA_IO
1344static void
1345VgaIOSave(int i, void *arg)
1346{
1347    MgaSavePtr sMga = arg;
1348#ifndef XSERVER_LIBPCIACCESS
1349    PCITAG tag = pciTag(sMga->pvp->bus,sMga->pvp->device,sMga->pvp->func);
1350#endif
1351    uint32_t temp;
1352
1353#ifdef DEBUG
1354    ErrorF("mga: VgaIOSave: %d:%d:%d\n", sMga->pvp->bus, sMga->pvp->device,
1355	   sMga->pvp->func);
1356#endif
1357#ifdef XSERVER_LIBPCIACCESS
1358    pci_device_cfg_read_u32(pMga->PciInfo, & temp, PCI_OPTION_REG);
1359#else
1360    temp = pciReadLong(tag, PCI_OPTION_REG);
1361#endif
1362    sMga->enable = (temp & 0x100) != 0;
1363}
1364
1365static void
1366VgaIORestore(int i, void *arg)
1367{
1368    MgaSavePtr sMga = arg;
1369#ifndef XSERVER_LIBPCIACCESS
1370    PCITAG tag = pciTag(sMga->pvp->bus,sMga->pvp->device,sMga->pvp->func);
1371#endif
1372
1373#ifdef DEBUG
1374    ErrorF("mga: VgaIORestore: %d:%d:%d\n", sMga->pvp->bus, sMga->pvp->device,
1375	   sMga->pvp->func);
1376#endif
1377#ifdef XSERVER_LIBPCIACCESS
1378    pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, sMga->enable,
1379			      PCI_OPTION_REG);
1380#else
1381    pciSetBitsLong(tag, PCI_OPTION_REG, 0x100, sMga->enable ? 0x100 : 0x000);
1382#endif
1383}
1384
1385static void
1386VgaIODisable(void *arg)
1387{
1388    MGAPtr pMga = arg;
1389
1390#ifdef DEBUG
1391    ErrorF("mga: VgaIODisable: %d:%d:%d, %s, xf86ResAccessEnter is %s\n",
1392	   pMga->PciInfo->bus, pMga->PciInfo->device, pMga->PciInfo->func,
1393	   pMga->Primary ? "primary" : "secondary",
1394	   BOOLTOSTRING(xf86ResAccessEnter));
1395#endif
1396    /* Turn off the vgaioen bit. */
1397#ifdef XSERVER_LIBPCIACCESS
1398    pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000000,
1399			      PCI_OPTION_REG);
1400#else
1401    pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000);
1402#endif
1403}
1404
1405static void
1406VgaIOEnable(void *arg)
1407{
1408    MGAPtr pMga = arg;
1409
1410#ifdef DEBUG
1411    ErrorF("mga: VgaIOEnable: %d:%d:%d, %s, xf86ResAccessEnter is %s\n",
1412	   pMga->PciInfo->bus, pMga->PciInfo->device, pMga->PciInfo->func,
1413	   pMga->Primary ? "primary" : "secondary",
1414	   BOOLTOSTRING(xf86ResAccessEnter));
1415#endif
1416    /* Turn on the vgaioen bit. */
1417    if (pMga->Primary) {
1418#ifdef XSERVER_LIBPCIACCESS
1419	pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000100,
1420				  PCI_OPTION_REG);
1421#else
1422	pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x100);
1423#endif
1424    }
1425}
1426#endif /* DISABLE_VGA_IO */
1427
1428void
1429MGAProbeDDC(ScrnInfoPtr pScrn, int index)
1430{
1431    vbeInfoPtr pVbe;
1432    if (xf86LoadSubModule(pScrn, "vbe")) {
1433	pVbe = VBEInit(NULL,index);
1434	ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1435	vbeFree(pVbe);
1436    }
1437}
1438
1439Bool
1440MGAMavenRead(ScrnInfoPtr pScrn, I2CByte reg, I2CByte *val)
1441{
1442	MGAPtr pMga = MGAPTR(pScrn);
1443
1444	if (!pMga->Maven) return FALSE;
1445
1446	/* FIXME: Using private interfaces for the moment until a more
1447	 * flexible xf86I2CWriteRead() variant shows up for us
1448	 *
1449	 * MAVEN does _not_ like a start bit in the middle of its transaction
1450	 * MAVEN does _not_ like ACK at the end of the transaction
1451	 */
1452
1453	if (!pMga->Maven_Bus->I2CStart(pMga->Maven_Bus, pMga->Maven->ByteTimeout)) return FALSE;
1454	if (!pMga->Maven_Bus->I2CPutByte(pMga->Maven, MAVEN_READ)) return FALSE;
1455	if (!pMga->Maven_Bus->I2CPutByte(pMga->Maven, reg)) return FALSE;
1456	pMga->Maven_Bus->I2CStop(pMga->Maven);
1457	if (!pMga->Maven_Bus->I2CGetByte(pMga->Maven, val, 0)) return FALSE;
1458	pMga->Maven_Bus->I2CStop(pMga->Maven);
1459
1460	return TRUE;
1461}
1462
1463/* Mandatory */
1464static Bool
1465MGAPreInit(ScrnInfoPtr pScrn, int flags)
1466{
1467    MGAPtr pMga;
1468    MessageType from;
1469    int i;
1470    double real;
1471    int bytesPerPixel;
1472    ClockRangePtr clockRanges;
1473    const char *s;
1474    int flags24;
1475    MGAEntPtr pMgaEnt = NULL;
1476    Bool Default;
1477#ifdef USEMGAHAL
1478    ULONG status;
1479    CARD8 MiscCtlReg;
1480#endif
1481
1482    /*
1483     * Note: This function is only called once at server startup, and
1484     * not at the start of each server generation.  This means that
1485     * only things that are persistent across server generations can
1486     * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
1487     * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()
1488     * are too, and should be used for data that must persist across
1489     * server generations.
1490     *
1491     * Per-generation data should be allocated with
1492     * AllocateScreenPrivateIndex() from the ScreenInit() function.
1493     */
1494
1495    /* Check the number of entities, and fail if it isn't one. */
1496    if (pScrn->numEntities != 1)
1497	return FALSE;
1498
1499
1500    pMga = MGAPTR(pScrn);
1501    /* Set here until dri is enabled */
1502#ifdef XF86DRI
1503    pMga->haveQuiescense = 1;
1504#endif
1505    /* Get the entity, and make sure it is PCI. */
1506    pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1507    if (pMga->pEnt->location.type != BUS_PCI)
1508	return FALSE;
1509
1510    /* Allocate an entity private if necessary */
1511    if (xf86IsEntityShared(pScrn->entityList[0])) {
1512	pMgaEnt = xf86GetEntityPrivate(pScrn->entityList[0],
1513					MGAEntityIndex)->ptr;
1514        pMga->entityPrivate = pMgaEnt;
1515    }
1516
1517    /* Set pMga->device to the relevant Device section */
1518    pMga->device = xf86GetDevFromEntity(pScrn->entityList[0],
1519					pScrn->entityInstanceList[0]);
1520
1521    if (flags & PROBE_DETECT) {
1522	MGAProbeDDC(pScrn, pMga->pEnt->index);
1523	return TRUE;
1524    }
1525
1526    /* The vgahw module should be loaded here when needed */
1527    if (!xf86LoadSubModule(pScrn, "vgahw"))
1528	return FALSE;
1529
1530    /*
1531     * Allocate a vgaHWRec
1532     */
1533    if (!vgaHWGetHWRec(pScrn))
1534	return FALSE;
1535
1536#ifndef XSERVER_LIBPCIACCESS
1537    /* Find the PCI info for this screen */
1538    pMga->PciInfo = xf86GetPciInfoForEntity(pMga->pEnt->index);
1539    pMga->PciTag = pciTag(pMga->PciInfo->bus, pMga->PciInfo->device,
1540			  pMga->PciInfo->func);
1541#endif
1542
1543    pMga->Primary = xf86IsPrimaryPci(pMga->PciInfo);
1544
1545#ifndef DISABLE_VGA_IO
1546#ifndef XSERVER_LIBPCIACCESS
1547    xf86SetOperatingState(resVgaIo, pMga->pEnt->index, ResUnusedOpr);
1548    xf86SetOperatingState(resVgaMem, pMga->pEnt->index, ResDisableOpr);
1549#endif
1550#else
1551    /*
1552     * Set our own access functions, which control the vgaioen bit.
1553     */
1554    pMga->Access.AccessDisable = VgaIODisable;
1555    pMga->Access.AccessEnable = VgaIOEnable;
1556    pMga->Access.arg = pMga;
1557    xf86SetAccessFuncs(pMga->pEnt, &pMga->Access, &pMga->Access);
1558#endif
1559
1560    /* Set pScrn->monitor */
1561    pScrn->monitor = pScrn->confScreen->monitor;
1562
1563    /*
1564     * Set the Chipset and ChipRev, allowing config file entries to
1565     * override.
1566     */
1567    if (pMga->device->chipset && *pMga->device->chipset) {
1568	pScrn->chipset = pMga->device->chipset;
1569        pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset);
1570        from = X_CONFIG;
1571    } else if (pMga->device->chipID >= 0) {
1572	pMga->Chipset = pMga->device->chipID;
1573	pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
1574	from = X_CONFIG;
1575	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
1576		   pMga->Chipset);
1577    } else {
1578	from = X_PROBED;
1579	pMga->Chipset = DEVICE_ID(pMga->PciInfo);
1580	pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
1581    }
1582
1583    if (pMga->device->chipRev >= 0) {
1584	pMga->ChipRev = pMga->device->chipRev;
1585	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
1586		   pMga->ChipRev);
1587    } else {
1588	pMga->ChipRev = CHIP_REVISION(pMga->PciInfo);
1589    }
1590
1591    /*
1592     * This shouldn't happen because such problems should be caught in
1593     * MGAProbe(), but check it just in case.
1594     */
1595    if (pScrn->chipset == NULL) {
1596	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1597		   "ChipID 0x%04X is not recognised\n", pMga->Chipset);
1598	return FALSE;
1599    }
1600    if (pMga->Chipset < 0) {
1601	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1602		   "Chipset \"%s\" is not recognised\n", pScrn->chipset);
1603	return FALSE;
1604    }
1605
1606    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"", pScrn->chipset);
1607    if (pMga->Chipset == PCI_CHIP_MGAG400) {
1608	if (pMga->ChipRev >= 0x80)
1609	    xf86ErrorF(" (G450)\n");
1610	else
1611	    xf86ErrorF(" (G400)\n");
1612    } else {
1613	xf86ErrorF("\n");
1614    }
1615
1616    pMga->is_Gx50 = ((pMga->Chipset == PCI_CHIP_MGAG400) && (pMga->ChipRev >= 0x80))
1617	|| (pMga->Chipset == PCI_CHIP_MGAG550);
1618    pMga->is_G200SE = (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI)
1619	|| (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI);
1620    pMga->is_G200EV = (pMga->Chipset == PCI_CHIP_MGAG200_EV_PCI);
1621    pMga->is_G200WB = (pMga->Chipset == PCI_CHIP_MGAG200_WINBOND_PCI);
1622    pMga->is_G200EH = (pMga->Chipset == PCI_CHIP_MGAG200_EH_PCI);
1623
1624#ifdef USEMGAHAL
1625    if (pMga->chip_attribs->HAL_chipset) {
1626	Bool loadHal = TRUE;
1627
1628	from = X_DEFAULT;
1629	if (xf86FindOption(pMga->device->options, "NoHal")) {
1630	    loadHal = !xf86SetBoolOption(pMga->device->options,
1631					 "NoHal", !loadHal);
1632	    from = X_CONFIG;
1633	} else if (xf86FindOption(pMga->device->options, "Hal")) {
1634	    loadHal = xf86SetBoolOption(pMga->device->options,
1635					"Hal", loadHal);
1636	    from = X_CONFIG;
1637	}
1638        if (loadHal && xf86LoadSubModule(pScrn, "mga_hal")) {
1639	  xf86DrvMsg(pScrn->scrnIndex, from,"Matrox HAL module used\n");
1640	  pMga->HALLoaded = TRUE;
1641	} else {
1642	  xf86DrvMsg(pScrn->scrnIndex, from, "Matrox HAL module not loaded "
1643		     "- using builtin mode setup instead\n");
1644	  pMga->HALLoaded = FALSE;
1645	}
1646    }
1647#endif
1648
1649    pMga->DualHeadEnabled = FALSE;
1650    if (xf86IsEntityShared(pScrn->entityList[0])) {/* dual-head mode requested*/
1651	if (
1652#ifdef USEMGAHAL
1653	    pMga->HALLoaded ||
1654#endif
1655	    !MGA_DH_NEEDS_HAL(pMga)) {
1656	    pMga->DualHeadEnabled = TRUE;
1657	} else if (xf86IsPrimInitDone(pScrn->entityList[0])) {
1658	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1659	 "This card requires the \"mga_hal\" module for dual-head operation\n"
1660	 "\tIt can be found at the Matrox web site <http://www.matrox.com>\n");
1661	}
1662    }
1663
1664    /*
1665     * In case of DualHead, we need to determine if we are the 'master' head
1666     * or the 'slave' head. In order to do that, at the end of the first
1667     * initialisation, PrimInit is set as DONE to the shared entity. So that
1668     * the second initialisation knows that something has been done before it.
1669     * This always assume that the first device initialised is the master
1670     * head, and the second the slave.
1671     *
1672     */
1673    if (xf86IsEntityShared(pScrn->entityList[0])) {      /* dual-head mode */
1674        if (!xf86IsPrimInitDone(pScrn->entityList[0])) { /* Is it the first initialisation? */
1675            /* First CRTC  */
1676            pMga->SecondCrtc = FALSE;
1677            pMga->HWCursor = TRUE;
1678            pMgaEnt->pScrn_1 = pScrn;
1679        } else if (pMga->DualHeadEnabled) {
1680            /* Second CRTC */
1681            pMga->SecondCrtc = TRUE;
1682            pMga->HWCursor = FALSE;
1683            pMgaEnt->pScrn_2 = pScrn;
1684            pScrn->AdjustFrame = MGAAdjustFrameCrtc2;
1685	    /*
1686	     * Fail initialization of second head if we are in MergeFB mode,
1687	     * since we do it ourselfs.
1688             */
1689            if(pMgaEnt->pScrn_1 && MGAPTR(pMgaEnt->pScrn_1)->MergedFB) {
1690		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1691			   "Primary head in Merged framebuffer mode. \n"
1692			   "Don't let Xfree try to manage the second head.\n"
1693			   "Remove the second screen in the \"ServerLayout\"\n"
1694			   "Section of the config file.");
1695		return FALSE;
1696	    }
1697        } else {
1698	    return FALSE;
1699	}
1700    }
1701
1702    if (pMga->DualHeadEnabled) {
1703#ifdef XF86DRI
1704        pMga->GetQuiescence = MGAGetQuiescenceShared;
1705#endif
1706    } else {                                              /* single-head mode */
1707        pMga->SecondCrtc = FALSE;
1708        pMga->HWCursor = TRUE;
1709#ifdef XF86DRI
1710        pMga->GetQuiescence = MGAGetQuiescence;
1711#endif
1712    }
1713
1714    if (!(pMga->Options = xalloc(sizeof(MGAOptions))))
1715	return FALSE;
1716    memcpy(pMga->Options, MGAOptions, sizeof(MGAOptions));
1717
1718    /* ajv changes to reflect actual values. see sdk pp 3-2. */
1719    /* these masks just get rid of the crap in the lower bits */
1720
1721    /* For the 2064 and older rev 1064, base0 is the MMIO and base1 is
1722     * the framebuffer.
1723     */
1724
1725    switch (pMga->chip_attribs->BARs) {
1726    case old_BARs:
1727	pMga->framebuffer_bar = 1;
1728	pMga->io_bar = 0;
1729	pMga->iload_bar = -1;
1730	break;
1731    case probe_BARs:
1732	if (pMga->ChipRev < 3) {
1733	    pMga->framebuffer_bar = 1;
1734	    pMga->io_bar = 0;
1735	    pMga->iload_bar = 2;
1736	    break;
1737	}
1738	/* FALLTHROUGH */
1739    case new_BARs:
1740	pMga->framebuffer_bar = 0;
1741	pMga->io_bar = 1;
1742	pMga->iload_bar = 2;
1743	break;
1744    }
1745
1746#ifdef XSERVER_LIBPCIACCESS
1747    pMga->FbAddress = pMga->PciInfo->regions[pMga->framebuffer_bar].base_addr;
1748#else
1749    pMga->FbAddress = pMga->PciInfo->memBase[pMga->framebuffer_bar] & 0xff800000;
1750#endif
1751
1752    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Linear framebuffer at 0x%lX\n",
1753	       (unsigned long)pMga->FbAddress);
1754
1755#ifdef XSERVER_LIBPCIACCESS
1756    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO registers at 0x%lX\n",
1757	       (unsigned long) pMga->PciInfo->regions[pMga->io_bar].base_addr);
1758#else
1759    pMga->IOAddress = pMga->PciInfo->memBase[pMga->io_bar] & 0xffffc000;
1760
1761    xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
1762	       (unsigned long)pMga->IOAddress);
1763#endif
1764
1765    if (pMga->iload_bar != -1) {
1766#ifdef XSERVER_LIBPCIACCESS
1767	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1768		   "Pseudo-DMA transfer window at 0x%lX\n",
1769		   (unsigned long) pMga->PciInfo->regions[pMga->iload_bar].base_addr);
1770#else
1771	if (pMga->PciInfo->memBase[2] != 0) {
1772	    pMga->ILOADAddress = pMga->PciInfo->memBase[2] & 0xffffc000;
1773	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1774		       "Pseudo-DMA transfer window at 0x%lX\n",
1775		       (unsigned long)pMga->ILOADAddress);
1776	}
1777#endif
1778    }
1779
1780#ifndef XSERVER_LIBPCIACCESS
1781    /*
1782     * Find the BIOS base.  Get it from the PCI config if possible.  Otherwise
1783     * use the VGA default.  Allow the config file to override this.
1784     */
1785
1786    pMga->BiosFrom = X_NONE;
1787    if (pMga->device->BiosBase != 0) {
1788	/* XXX This isn't used */
1789	pMga->BiosAddress = pMga->device->BiosBase;
1790	pMga->BiosFrom = X_CONFIG;
1791    } else {
1792	/* details: rombase sdk pp 4-15 */
1793	if (pMga->PciInfo->biosBase != 0) {
1794	    pMga->BiosAddress = pMga->PciInfo->biosBase & 0xffff0000;
1795	    pMga->BiosFrom = X_PROBED;
1796	} else if (pMga->Primary) {
1797	    pMga->BiosAddress = 0xc0000;
1798	    pMga->BiosFrom = X_DEFAULT;
1799	}
1800    }
1801    if (pMga->BiosAddress) {
1802	xf86DrvMsg(pScrn->scrnIndex, pMga->BiosFrom, "BIOS at 0x%lX\n",
1803		   (unsigned long)pMga->BiosAddress);
1804    }
1805#endif
1806
1807#ifndef XSERVER_LIBPCIACCESS
1808    if (xf86RegisterResources(pMga->pEnt->index, NULL, ResExclusive)) {
1809	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1810		"xf86RegisterResources() found resource conflicts\n");
1811	MGAFreeRec(pScrn);
1812	return FALSE;
1813    }
1814#endif
1815
1816    /*
1817     * The first thing we should figure out is the depth, bpp, etc.
1818     * Our default depth is 8, so pass it to the helper function.
1819     * We support both 24bpp and 32bpp layouts, so indicate that.
1820     */
1821
1822    /* Prefer 32bpp */
1823    flags24 = Support24bppFb | Support32bppFb | PreferConvert24to32;
1824
1825    if (pMga->SecondCrtc)
1826	flags24 = Support32bppFb;
1827
1828    if (xf86ReturnOptValBool(pMga->Options, OPTION_FBDEV, FALSE)) {
1829	pMga->FBDev = TRUE;
1830	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1831		"Using framebuffer device\n");
1832	/* check for linux framebuffer device */
1833	if (!xf86LoadSubModule(pScrn, "fbdevhw"))
1834	    return FALSE;
1835	if (!fbdevHWInit(pScrn, pMga->PciInfo, NULL))
1836	    return FALSE;
1837    }
1838
1839    /*
1840     * If the user has specified the amount of memory in the XF86Config
1841     * file, we respect that setting.
1842     */
1843    from = X_PROBED;
1844    if (pMga->device->videoRam != 0) {
1845	pScrn->videoRam = pMga->device->videoRam;
1846	from = X_CONFIG;
1847    } else if (pMga->FBDev) {
1848	pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
1849    } else {
1850	pScrn->videoRam = MGACountRam(pScrn);
1851    }
1852
1853    if (pMga->is_G200SE && pScrn->videoRam < 2048)
1854	pScrn->confScreen->defaultdepth = 16;
1855
1856    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) {
1857	return FALSE;
1858    } else {
1859	/* Check that the returned depth is one we support */
1860	switch (pScrn->depth) {
1861	case 8:
1862	case 16:
1863	case 24:
1864	    /* OK */
1865	    break;
1866	case 15:
1867	    if (pMga->Chipset != PCI_CHIP_MGAG200_SE_A_PCI)
1868		break;
1869	default:
1870	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1871		       "Given depth (%d) is not supported by this driver\n",
1872		       pScrn->depth);
1873	    return FALSE;
1874	}
1875    }
1876    xf86PrintDepthBpp(pScrn);
1877
1878    /*
1879     * This must happen after pScrn->display has been set because
1880     * xf86SetWeight references it.
1881     */
1882    if (pScrn->depth > 8) {
1883	/* The defaults are OK for us */
1884	rgb zeros = {0, 0, 0};
1885
1886	if (!xf86SetWeight(pScrn, zeros, zeros)) {
1887	    return FALSE;
1888	} else {
1889	    /* XXX check that weight returned is supported */
1890            ;
1891        }
1892    }
1893
1894    bytesPerPixel = pScrn->bitsPerPixel / 8;
1895
1896    /* We use a programmable clock */
1897    pScrn->progClock = TRUE;
1898
1899    /* Collect all of the relevant option flags (fill in pScrn->options) */
1900    xf86CollectOptions(pScrn, NULL);
1901
1902    /* Process the options */
1903    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pMga->Options);
1904
1905    if (pMga->is_G200SE) {
1906        /* Disable MTRR support on PCIe systems */
1907#ifdef XSERVER_LIBPCIACCESS
1908	uint32_t temp;
1909
1910	pci_device_cfg_read_u32(pMga->PciInfo, & temp, 0xDC);
1911#else
1912        CARD32 temp = pciReadLong(pMga->PciTag, 0xDC);
1913#endif
1914
1915        if ((temp & 0x0000FF00) != 0x0) {
1916            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling MTRR support.\n");
1917            pScrn->options = xf86ReplaceBoolOption(pScrn->options, "MTRR", FALSE);
1918        }
1919    }
1920
1921    if (pMga->is_G200WB && xf86ReturnOptValBool(pMga->Options, OPTION_KVM, TRUE)) {
1922        pMga->KVM = TRUE;
1923        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling KVM\n");
1924    }
1925
1926#if !defined(__powerpc__)
1927    pMga->softbooted = FALSE;
1928    Default = (pMga->chip_attribs->dual_head_possible
1929	       && !pMga->Primary && !pMga->SecondCrtc);
1930
1931    if (xf86ReturnOptValBool(pMga->Options, OPTION_INT10, Default) &&
1932        xf86LoadSubModule(pScrn, "int10")) {
1933        xf86Int10InfoPtr pInt;
1934
1935        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
1936        pInt = xf86InitInt10(pMga->pEnt->index);
1937	if (pInt) pMga->softbooted = TRUE;
1938        xf86FreeInt10(pInt);
1939    }
1940#endif
1941
1942    /* Set the bits per RGB for 8bpp mode */
1943    if (pScrn->depth == 8)
1944	pScrn->rgbBits = 8;
1945
1946#ifdef XF86DRI
1947    from = X_DEFAULT;
1948    pMga->agpMode = MGA_DEFAULT_AGP_MODE;
1949
1950    if (xf86GetOptValInteger(pMga->Options,
1951			     OPTION_AGP_MODE, &(pMga->agpMode))) {
1952       if (pMga->agpMode < 1) {
1953	  pMga->agpMode = 1;
1954       }
1955       if (pMga->agpMode > MGA_MAX_AGP_MODE) {
1956	  pMga->agpMode = MGA_MAX_AGP_MODE;
1957       }
1958       from = X_CONFIG;
1959    }
1960    if (xf86GetOptValInteger(pMga->Options,
1961                             OPTION_AGP_SIZE, &(pMga->agpSize))) {
1962                             /* check later */
1963       xf86DrvMsg(pScrn->scrnIndex, from, "Using %d MB of AGP memory\n",
1964	          pMga->agpSize);
1965    }
1966
1967    xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n",
1968	       pMga->agpMode);
1969
1970    if (xf86ReturnOptValBool(pMga->Options, OPTION_OLDDMA, FALSE)) {
1971	pMga->useOldDmaInit = TRUE;
1972    }
1973
1974    if (xf86ReturnOptValBool(pMga->Options, OPTION_PCIDMA, FALSE)) {
1975	pMga->forcePciDma = TRUE;
1976    }
1977#endif
1978
1979    from = X_DEFAULT;
1980
1981    /*
1982     * The preferred method is to use the "hw cursor" option as a tri-state
1983     * option, with the default set above.
1984     */
1985    if (xf86GetOptValBool(pMga->Options, OPTION_HW_CURSOR, &pMga->HWCursor)) {
1986	from = X_CONFIG;
1987    }
1988
1989    /* For compatibility, accept this too (as an override) */
1990    if (xf86ReturnOptValBool(pMga->Options, OPTION_SW_CURSOR, FALSE)) {
1991    from = X_CONFIG;
1992    pMga->HWCursor = FALSE;
1993    }
1994    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1995        pMga->HWCursor ? "HW" : "SW");
1996
1997    if (xf86ReturnOptValBool(pMga->Options, OPTION_NOACCEL, FALSE)) {
1998	pMga->NoAccel = TRUE;
1999	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
2000    } else {
2001	int from = X_DEFAULT;
2002#ifdef USE_EXA
2003	char *s = xf86GetOptValString(pMga->Options, OPTION_ACCELMETHOD);
2004#endif
2005	pMga->NoAccel = FALSE;
2006	pMga->Exa = FALSE;
2007#ifdef USE_EXA
2008	if (!xf86NameCmp(s, "EXA")) {
2009	    pMga->Exa = TRUE;
2010	    from = X_CONFIG;
2011	}
2012#endif
2013	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n",
2014		   pMga->Exa ? "EXA" : "XAA");
2015    }
2016    if (xf86ReturnOptValBool(pMga->Options, OPTION_PCI_RETRY, FALSE)) {
2017	pMga->UsePCIRetry = TRUE;
2018	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
2019    }
2020    if (xf86ReturnOptValBool(pMga->Options, OPTION_SYNC_ON_GREEN, FALSE)) {
2021	pMga->SyncOnGreen = TRUE;
2022	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");
2023    }
2024    if (xf86ReturnOptValBool(pMga->Options, OPTION_SHOWCACHE, FALSE)) {
2025	pMga->ShowCache = TRUE;
2026	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
2027    }
2028    if (xf86ReturnOptValBool(pMga->Options, OPTION_MGA_SDRAM, FALSE)) {
2029	pMga->HasSDRAM = TRUE;
2030	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Has SDRAM\n");
2031    }
2032    if (xf86GetOptValFreq(pMga->Options, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) {
2033	pMga->MemClk = (int)(real * 1000.0);
2034    }
2035
2036    if(xf86GetOptValInteger(pMga->Options, OPTION_VIDEO_KEY, &(pMga->videoKey))) {
2037	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
2038				pMga->videoKey);
2039    } else {
2040	pMga->videoKey =  (1 << pScrn->offset.red) |
2041			  (1 << pScrn->offset.green) |
2042        (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);
2043    }
2044    if (xf86ReturnOptValBool(pMga->Options, OPTION_SHADOW_FB, FALSE)) {
2045	pMga->ShadowFB = TRUE;
2046	pMga->NoAccel = TRUE;
2047	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2048		"Using \"Shadow Framebuffer\" - acceleration disabled\n");
2049    }
2050    if (xf86ReturnOptValBool(pMga->Options, OPTION_OVERCLOCK_MEM, FALSE)) {
2051	pMga->OverclockMem = TRUE;
2052	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overclocking memory\n");
2053    }
2054    if (xf86ReturnOptValBool(pMga->Options, OPTION_TEXTURED_VIDEO, FALSE)) {
2055	pMga->TexturedVideo = TRUE;
2056    }
2057    if (xf86ReturnOptValBool(pMga->Options, OPTION_MERGEDFB, FALSE)) {
2058        if(!MGAISGx50(pMga)) {
2059            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2060                "\"Merged Framebuffer\" mode only supported on G450 and G550 boards.\n");
2061        } else {
2062#ifdef USEMGAHAL
2063            if(pMga->HALLoaded)
2064            {
2065                pMga->MergedFB = TRUE;
2066                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2067                        "Using \"Merged Framebuffer\" mode.\n");
2068                /*
2069                * a few options that won't work well together
2070                */
2071                if(pMga->HWCursor) /*Should we give the choice? */
2072                    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2073                        " -- Hardware Cursor disabled.\n");
2074                pMga->HWCursor = FALSE;
2075                if(pMga->ShadowFB)
2076                    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2077                        " -- Shadow Framebuffer disabled.\n");
2078                pMga->ShadowFB = FALSE;
2079                if(pMga->FBDev)
2080                    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2081                        " -- Framebuffer device disabled.\n");
2082                pMga->FBDev = FALSE;
2083            } /* MGA_HAL */
2084            else
2085#endif
2086            {
2087                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2088                    "HALLib not loaded! NOT using \"Merged Framebuffer\" mode.\n");
2089            } /* MGA_NOT_HAL */
2090        } /* ISMGAGx50() */
2091    }
2092    if (pMga->FBDev) {
2093	pScrn->SwitchMode    = fbdevHWSwitchModeWeak();
2094	pScrn->AdjustFrame   = fbdevHWAdjustFrameWeak();
2095	pScrn->EnterVT       = MGAEnterVTFBDev;
2096	pScrn->LeaveVT       = fbdevHWLeaveVTWeak();
2097	pScrn->ValidMode     = fbdevHWValidModeWeak();
2098    }
2099    pMga->Rotate = 0;
2100    if ((s = xf86GetOptValString(pMga->Options, OPTION_ROTATE))) {
2101        if(!pMga->MergedFB) {
2102            if(!xf86NameCmp(s, "CW")) {
2103                pMga->ShadowFB = TRUE;
2104                pMga->NoAccel = TRUE;
2105                pMga->HWCursor = FALSE;
2106                pMga->Rotate = 1;
2107                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2108                        "Rotating screen clockwise - acceleration disabled\n");
2109            } else
2110            if(!xf86NameCmp(s, "CCW")) {
2111                pMga->ShadowFB = TRUE;
2112                pMga->NoAccel = TRUE;
2113                pMga->HWCursor = FALSE;
2114                pMga->Rotate = -1;
2115                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2116                        "Rotating screen counter clockwise - acceleration disabled\n");
2117            } else {
2118                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2119                        "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
2120                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2121                        "Valid options are \"CW\" or \"CCW\"\n");
2122            }
2123        } else {
2124            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2125                " -- Rotation disabled.\n");
2126        }
2127    }
2128
2129    switch (pMga->Chipset) {
2130    case PCI_CHIP_MGA2064:
2131    case PCI_CHIP_MGA2164:
2132    case PCI_CHIP_MGA2164_AGP:
2133	MGA2064SetupFuncs(pScrn);
2134	break;
2135    case PCI_CHIP_MGA1064:
2136    case PCI_CHIP_MGAG100:
2137    case PCI_CHIP_MGAG100_PCI:
2138    case PCI_CHIP_MGAG200:
2139    case PCI_CHIP_MGAG200_PCI:
2140    case PCI_CHIP_MGAG200_SE_A_PCI:
2141    case PCI_CHIP_MGAG200_SE_B_PCI:
2142    case PCI_CHIP_MGAG200_WINBOND_PCI:
2143    case PCI_CHIP_MGAG200_EV_PCI:
2144    case PCI_CHIP_MGAG200_EH_PCI:
2145    case PCI_CHIP_MGAG400:
2146    case PCI_CHIP_MGAG550:
2147	MGAGSetupFuncs(pScrn);
2148	break;
2149    }
2150
2151    /*
2152     * Read the BIOS data struct
2153     */
2154
2155#if defined(__alpha__) && !defined(XSERVER_LIBPCIACCESS)
2156    /*
2157     * Some old Digital-OEMed Matrox Millennium I cards have a VGA
2158     * disable switch.  If the disable is on, we can't read the BIOS,
2159     * and pMga->BiosAddress = 0x0. The disable switch is needed to
2160     * allow multi-head operation with brain-dead console code... ;-}
2161     */
2162
2163    if ((pMga->BiosAddress == 0) && !xf86IsPrimaryPci(pMga->PciInfo))
2164        xf86DrvMsg(pScrn->scrnIndex, pMga->BiosFrom,
2165                   "BIOS not found, skipping read\n");
2166    else
2167#endif
2168    mga_read_and_process_bios( pScrn );
2169
2170
2171    /* Since the BIOS can swap DACs during the initialisation of G550, we need to
2172     * store which DAC this instance of the driver is taking care of. This is done
2173     * by checking a flag stored in the ROM by the BIOS at a fixed address. */
2174
2175    if (!pMga->SecondCrtc)
2176        pMga->SecondOutput = FALSE;
2177    else
2178        pMga->SecondOutput = TRUE;
2179
2180    if (pMga->Chipset == PCI_CHIP_MGAG550) {
2181        if (!pMga->SecondCrtc) {
2182            pMga->SecondOutput = (pMga->BiosOutputMode & 0x1) ? TRUE : FALSE;
2183        } else {
2184            pMga->SecondOutput = (pMga->BiosOutputMode & 0x1) ? FALSE : TRUE;
2185        }
2186    }
2187
2188
2189    /* HW bpp matches reported bpp */
2190    pMga->HwBpp = pScrn->bitsPerPixel;
2191
2192    /*
2193     * Reset card if it isn't primary one
2194     */
2195    if ( (!pMga->Primary && !pMga->FBDev) || xf86IsPc98() )
2196        MGASoftReset(pScrn);
2197
2198    if (pScrn->videoRam == 0) {
2199	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2200		   "Unable to detect video RAM.\n");
2201	return FALSE;
2202    }
2203
2204    if (pMga->DualHeadEnabled) {
2205       /* This takes gives either half or 8 meg to the second head
2206	* whichever is less. */
2207        if(pMga->SecondCrtc == FALSE) {
2208	    Bool UseHalf = FALSE;
2209	    int adjust;
2210
2211	    xf86GetOptValBool(pMga->Options, OPTION_CRTC2HALF, &UseHalf);
2212	    adjust = pScrn->videoRam / 2;
2213
2214	    if (UseHalf == TRUE ||
2215		  xf86GetOptValInteger(pMga->Options, OPTION_CRTC2RAM, &adjust)) {
2216	        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2217			   "Crtc2 will use %dK of VideoRam\n",
2218			   adjust);
2219	    } else {
2220	        adjust = min(adjust, 8192);
2221	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2222			   "Crtc2 will use %dK of VideoRam\n",
2223			   adjust);
2224	    }
2225	    pMgaEnt->mastervideoRam = pScrn->videoRam - adjust;
2226	    pScrn->videoRam = pMgaEnt->mastervideoRam;
2227	    pMgaEnt->slavevideoRam = adjust;
2228	    pMgaEnt->masterFbAddress = pMga->FbAddress;
2229	    pMga->FbMapSize =
2230	       pMgaEnt->masterFbMapSize = pScrn->videoRam * 1024;
2231	    pMgaEnt->slaveFbAddress = pMga->FbAddress +
2232	       pMgaEnt->masterFbMapSize;
2233	    pMgaEnt->slaveFbMapSize = pMgaEnt->slavevideoRam * 1024;
2234	    pMga->realSrcOrg = pMga->SrcOrg = 0;
2235	    pMga->DstOrg = 0;
2236	} else {
2237	    pMga->FbAddress = pMgaEnt->slaveFbAddress;
2238	    pMga->FbMapSize = pMgaEnt->slaveFbMapSize;
2239	    pScrn->videoRam = pMgaEnt->slavevideoRam;
2240	    pMga->DstOrg = pMga->realSrcOrg =
2241	      pMgaEnt->slaveFbAddress - pMgaEnt->masterFbAddress;
2242	    pMga->SrcOrg = 0; /* This is not stored in hw format!! */
2243	}
2244        pMgaEnt->refCount++;
2245    } else {
2246        /* Normal Handling of video ram etc */
2247        pMga->FbMapSize = pScrn->videoRam * 1024;
2248        switch(pMga->Chipset) {
2249	  case PCI_CHIP_MGAG550:
2250	  case PCI_CHIP_MGAG400:
2251	  case PCI_CHIP_MGAG200:
2252	  case PCI_CHIP_MGAG200_PCI:
2253	  case PCI_CHIP_MGAG200_SE_A_PCI:
2254	  case PCI_CHIP_MGAG200_SE_B_PCI:
2255          case PCI_CHIP_MGAG200_WINBOND_PCI:
2256	  case PCI_CHIP_MGAG200_EV_PCI:
2257      case PCI_CHIP_MGAG200_EH_PCI:
2258	    pMga->SrcOrg = 0;
2259	    pMga->DstOrg = 0;
2260	    break;
2261	  default:
2262	    break;
2263	}
2264    }
2265    xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
2266               pScrn->videoRam);
2267
2268   /* Set the bpp shift value */
2269    pMga->BppShifts[0] = 0;
2270    pMga->BppShifts[1] = 1;
2271    pMga->BppShifts[2] = 0;
2272    pMga->BppShifts[3] = 2;
2273
2274    /*
2275     * fill MGAdac struct
2276     * Warning: currently, it should be after RAM counting
2277     */
2278    (*pMga->PreInit)(pScrn);
2279
2280#if !defined(__powerpc__)
2281
2282    /* Read and print the Monitor DDC info */
2283    pScrn->monitor->DDC = MGAdoDDC(pScrn);
2284#endif /* !__powerpc__ */
2285
2286    if (!pScrn->monitor->DDC && pMga->is_G200SE) {
2287	/* Jam in ranges big enough for 1024x768 */
2288	if (!pScrn->monitor->nHsync) {
2289	    pScrn->monitor->nHsync = 1;
2290	    pScrn->monitor->hsync[0].lo = 31.5;
2291	    pScrn->monitor->hsync[0].hi = 48.0;
2292	}
2293	if (!pScrn->monitor->nVrefresh) {
2294	    pScrn->monitor->nVrefresh = 1;
2295	    pScrn->monitor->vrefresh[0].lo = 56.0;
2296	    pScrn->monitor->vrefresh[0].hi = 75.0;
2297	}
2298    }
2299
2300
2301    /*
2302     * If the driver can do gamma correction, it should call xf86SetGamma()
2303     * here.
2304     */
2305
2306    {
2307	Gamma zeros = {0.0, 0.0, 0.0};
2308
2309	if (!xf86SetGamma(pScrn, zeros)) {
2310	    return FALSE;
2311	}
2312    }
2313
2314
2315    /* XXX Set HW cursor use */
2316
2317    /* Set the min pixel clock */
2318    pMga->MinClock = 17750;
2319    if (pMga->is_G200WB){
2320	pMga->MinClock = 18750;
2321    }
2322    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
2323	       pMga->MinClock / 1000);
2324    /*
2325     * If the user has specified ramdac speed in the XF86Config
2326     * file, we respect that setting.
2327     */
2328    if (pMga->device->dacSpeeds[0]) {
2329	int speed = 0;
2330
2331	switch (pScrn->bitsPerPixel) {
2332	case 8:
2333	   speed = pMga->device->dacSpeeds[DAC_BPP8];
2334	   break;
2335	case 16:
2336	   speed = pMga->device->dacSpeeds[DAC_BPP16];
2337	   break;
2338	case 24:
2339	   speed = pMga->device->dacSpeeds[DAC_BPP24];
2340	   break;
2341	case 32:
2342	   speed = pMga->device->dacSpeeds[DAC_BPP32];
2343	   break;
2344	}
2345	if (speed == 0)
2346	    pMga->MaxClock = pMga->device->dacSpeeds[0];
2347	else
2348	    pMga->MaxClock = speed;
2349	from = X_CONFIG;
2350    } else {
2351	pMga->MaxClock = pMga->Dac.maxPixelClock;
2352	from = pMga->Dac.ClockFrom;
2353    }
2354    if(pMga->SecondCrtc == TRUE) {
2355        /* Override on 2nd crtc */
2356	if ((pMga->ChipRev >= 0x80) || (pMga->Chipset == PCI_CHIP_MGAG550)) {
2357	    /* G450, G550 */
2358	    pMga->MaxClock = 234000;
2359	} else {
2360	    pMga->MaxClock = 135000;
2361	}
2362    }
2363    xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
2364	       pMga->MaxClock / 1000);
2365    /*
2366     * Setup the ClockRanges, which describe what clock ranges are available,
2367     * and what sort of modes they can be used for.
2368     */
2369    clockRanges = xnfcalloc(sizeof(ClockRange), 1);
2370    clockRanges->next = NULL;
2371    clockRanges->minClock = pMga->MinClock;
2372    clockRanges->maxClock = pMga->MaxClock;
2373    clockRanges->clockIndex = -1;		/* programmable */
2374    clockRanges->interlaceAllowed = TRUE;
2375    clockRanges->doubleScanAllowed = TRUE;
2376#ifdef USEMGAHAL
2377    MGA_HAL(clockRanges->interlaceAllowed = FALSE);
2378    MGA_HAL(clockRanges->doubleScanAllowed = FALSE);
2379#endif
2380    if (pMga->SecondCrtc == TRUE)
2381	clockRanges->interlaceAllowed = FALSE;
2382
2383    clockRanges->ClockMulFactor = 1;
2384    clockRanges->ClockDivFactor = 1;
2385
2386    /* Only set MemClk if appropriate for the ramdac */
2387    if (pMga->Dac.SetMemClk) {
2388	if (pMga->MemClk == 0) {
2389	    pMga->MemClk = pMga->Dac.MemoryClock;
2390	    from = pMga->Dac.MemClkFrom;
2391	} else
2392	    from = X_CONFIG;
2393	xf86DrvMsg(pScrn->scrnIndex, from, "MCLK used is %.1f MHz\n",
2394		   pMga->MemClk / 1000.0);
2395    }
2396
2397    /*
2398     * xf86ValidateModes will check that the mode HTotal and VTotal values
2399     * don't exceed the chipset's limit if pScrn->maxHValue and
2400     * pScrn->maxVValue are set.  Since our MGAValidMode() already takes
2401     * care of this, we don't worry about setting them here.
2402     */
2403    {
2404	int Pitches1[] =
2405	  {640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0};
2406	int Pitches2[] =
2407	  {512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664,
2408		1920, 2048, 0};
2409	int *linePitches = NULL;
2410	int minPitch = 256;
2411	int maxPitch = 2048;
2412
2413        switch(pMga->Chipset) {
2414	case PCI_CHIP_MGA2064:
2415	   if (!pMga->NoAccel) {
2416		linePitches = xalloc(sizeof(Pitches1));
2417		memcpy(linePitches, Pitches1, sizeof(Pitches1));
2418		minPitch = maxPitch = 0;
2419	   }
2420	   break;
2421	case PCI_CHIP_MGA2164:
2422	case PCI_CHIP_MGA2164_AGP:
2423	case PCI_CHIP_MGA1064:
2424	   if (!pMga->NoAccel) {
2425		linePitches = xalloc(sizeof(Pitches2));
2426		memcpy(linePitches, Pitches2, sizeof(Pitches2));
2427		minPitch = maxPitch = 0;
2428	   }
2429	   break;
2430	case PCI_CHIP_MGAG100:
2431	case PCI_CHIP_MGAG100_PCI:
2432	   maxPitch = 2048;
2433	   break;
2434	case PCI_CHIP_MGAG200_SE_A_PCI:
2435	   if (pScrn->videoRam < 2048){
2436	       maxPitch = 1024;
2437	   }
2438	   break;
2439	case PCI_CHIP_MGAG200:
2440	case PCI_CHIP_MGAG200_PCI:
2441	case PCI_CHIP_MGAG200_SE_B_PCI:
2442        case PCI_CHIP_MGAG200_WINBOND_PCI:
2443	case PCI_CHIP_MGAG200_EV_PCI:
2444    case PCI_CHIP_MGAG200_EH_PCI:
2445	case PCI_CHIP_MGAG400:
2446	case PCI_CHIP_MGAG550:
2447	   maxPitch = 4096;
2448	   break;
2449	}
2450
2451	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
2452			      pScrn->display->modes, clockRanges,
2453			      linePitches, minPitch, maxPitch,
2454			      pMga->Roundings[(pScrn->bitsPerPixel >> 3) - 1] *
2455					pScrn->bitsPerPixel, 128, 2048,
2456			      pScrn->display->virtualX,
2457			      pScrn->display->virtualY,
2458			      pMga->FbMapSize,
2459			      LOOKUP_BEST_REFRESH);
2460
2461	if (linePitches)
2462	   xfree(linePitches);
2463    }
2464
2465    /* Some X compute displayWidth from inferred virtual without
2466       checking pitch limit. */
2467    if(pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI && pScrn->videoRam < 2048)
2468        pScrn->displayWidth = 1024;
2469
2470    if (i < 1 && pMga->FBDev) {
2471	fbdevHWUseBuildinMode(pScrn);
2472	pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
2473	i = 1;
2474    }
2475    if (i == -1) {
2476	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Validate Modes Failed\n");
2477	MGAFreeRec(pScrn);
2478	return FALSE;
2479    }
2480
2481    /* Prune the modes marked as invalid */
2482    xf86PruneDriverModes(pScrn);
2483
2484    if (i == 0 || pScrn->modes == NULL) {
2485	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
2486	MGAFreeRec(pScrn);
2487	return FALSE;
2488    }
2489#ifdef USEMGAHAL
2490    MGA_HAL(
2491
2492    if(pMga->SecondCrtc == FALSE) {
2493
2494        pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());
2495        pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));
2496        pMga->pClientStruct->pMga = (MGAPtr) pMga;
2497
2498        MGAMapMem(pScrn);
2499	/*
2500	 * For some reason the MGAOPM_DMA_BLIT bit needs to be set
2501	 * on G200 before opening the HALlib. I don't know why.
2502	 * MATROX: hint, hint.
2503	 */
2504	/*if (pMga->Chipset == PCI_CHIP_MGAG200 ||
2505	  pMga->Chipset == PCI_CHIP_MGAG200_PCI) */{
2506	    CARD32 opmode;
2507	    opmode = INREG(MGAREG_OPMODE);
2508	    OUTREG(MGAREG_OPMODE,  MGAOPM_DMA_BLIT | opmode);
2509	}
2510	/* wrapping OpenLibrary to fix broken registers. MATROX: hint, hint. */
2511	MiscCtlReg = inMGAdac(MGA1064_MISC_CTL);
2512        MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
2513	outMGAdac(MGA1064_MISC_CTL,MiscCtlReg);
2514        MGAUnmapMem(pScrn);
2515        pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO));
2516        MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
2517
2518        /* copy the board handles */
2519        if (pMga->DualHeadEnabled) {
2520            pMgaEnt->pClientStruct = pMga->pClientStruct;
2521            pMgaEnt->pBoard = pMga->pBoard;
2522            pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo;
2523        }
2524
2525    } else { /* Second CRTC && entity is shared */
2526        pMga->pBoard = pMgaEnt->pBoard;
2527        pMga->pClientStruct = pMgaEnt->pClientStruct;
2528        pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo;
2529
2530    }
2531
2532    MGAFillModeInfoStruct(pScrn,NULL);
2533    /* Fields usually handled by MGAFillModeInfoStruct, but are unavailable
2534     * because no mode is given
2535     */
2536    pMga->pMgaModeInfo->ulDispWidth = pScrn->virtualX;
2537    pMga->pMgaModeInfo->ulDispHeight = pScrn->virtualY;
2538
2539
2540    if (ISDIGITAL1(pMga))
2541        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2542                    "Digital screen detected on first head.\n");
2543    if (ISTV1(pMga))
2544        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2545                    "TV detected on first head.\n");
2546    if (ISDIGITAL2(pMga))
2547        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2548                    "Digital screen detected on second head.\n");
2549    if (ISTV2(pMga))
2550        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2551                    "TV detected on second head.\n");
2552
2553
2554    if((status = MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo)) != 0) {
2555	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2556		   "MGAValidateMode from HALlib found the mode to be invalid.\n"
2557		   "\tError: 0x%lx\n", status);
2558        return FALSE;
2559    }
2560    pScrn->displayWidth = pMga->pMgaModeInfo->ulFBPitch;
2561    );	/* MGA_HAL */
2562#endif
2563
2564    /* If the Device section explicitly set HasSDRAM, don't bother checking.
2565     */
2566    if (!pMga->HasSDRAM) {
2567	if ((pMga->softbooted || pMga->Primary)
2568	     && pMga->chip_attribs->probe_for_sdram) {
2569	    uint32_t option_reg;
2570
2571#ifdef XSERVER_LIBPCIACCESS
2572	    pci_device_cfg_read_u32(pMga->PciInfo, & option_reg,
2573				    PCI_OPTION_REG);
2574#else
2575	    option_reg = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
2576#endif
2577	    pMga->HasSDRAM = ((option_reg & (1 << 14)) == 0);
2578	}
2579	else {
2580	    pMga->HasSDRAM = pMga->chip_attribs->has_sdram;
2581	}
2582
2583	if (pMga->HasSDRAM) {
2584	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n");
2585	}
2586    }
2587
2588    /*
2589     * Set the CRTC parameters for all of the modes based on the type
2590     * of mode, and the chipset's interlace requirements.
2591     *
2592     * Calling this is required if the mode->Crtc* values are used by the
2593     * driver and if the driver doesn't provide code to set them.  They
2594     * are not pre-initialised at all.
2595     */
2596#ifdef USEMGAHAL
2597    MGA_HAL(xf86SetCrtcForModes(pScrn, 0));
2598#endif
2599    MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V));
2600
2601    /* Set the current mode to the first in the list */
2602    pScrn->currentMode = pScrn->modes;
2603
2604    /* Print the list of modes being used */
2605    xf86PrintModes(pScrn);
2606
2607    /* Set display resolution */
2608    xf86SetDpi(pScrn, 0, 0);
2609
2610    /*
2611     * Compute the byte offset into the linear frame buffer where the
2612     * frame buffer data should actually begin.  According to DDK misc.c
2613     * line 1023, if more than 4MB is to be displayed, YDSTORG must be set
2614     * appropriately to align memory bank switching, and this requires a
2615     * corresponding offset on linear frame buffer access.
2616     * This is only needed for WRAM.
2617     */
2618
2619    pMga->YDstOrg = 0;
2620    if (pMga->chip_attribs->fb_4mb_quirk &&
2621	(pScrn->virtualX * pScrn->virtualY * bytesPerPixel > 4*1024*1024)) {
2622	int offset;
2623	int offset_modulo = (pScrn->bitsPerPixel == 24) ? 12 : 4;
2624	int ydstorg_modulo = 64;
2625
2626
2627	if (pMga->Interleave) {
2628	    offset_modulo <<= 1;
2629	    ydstorg_modulo <<= 1;
2630	}
2631
2632	offset = (4*1024*1024) % (pScrn->displayWidth * bytesPerPixel);
2633	pMga->YDstOrg = offset / bytesPerPixel;
2634
2635	/*
2636	 * When this was unconditional, it caused a line of horizontal garbage
2637	 * at the middle right of the screen at the 4Meg boundary in 32bpp
2638	 * (and presumably any other modes that use more than 4M). But it's
2639	 * essential for 24bpp (it may not matter either way for 8bpp & 16bpp,
2640	 * I'm not sure; I didn't notice problems when I checked with and
2641	 * without.)
2642	 * DRM Doug Merritt 12/97, submitted to XFree86 6/98 (oops)
2643	 */
2644	if (bytesPerPixel < 4) {
2645	    while ((offset % offset_modulo) != 0 ||
2646		   (pMga->YDstOrg % ydstorg_modulo) != 0) {
2647		offset++;
2648		pMga->YDstOrg = offset / bytesPerPixel;
2649	    }
2650	}
2651    }
2652
2653    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n",
2654		   pMga->YDstOrg);
2655    if(pMga->DualHeadEnabled) {
2656        if(pMga->SecondCrtc == FALSE) {
2657	    pMga->FbUsableSize = pMgaEnt->masterFbMapSize;
2658            /* Allocate HW cursor buffer at the end of video ram */
2659	    if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
2660	        if( pScrn->virtualY * pScrn->displayWidth *
2661		    pScrn->bitsPerPixel / 8 <=
2662		    pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
2663		    pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
2664		    pMga->FbCursorOffset =
2665		      pMgaEnt->masterFbMapSize -
2666		      pMga->Dac.CursorOffscreenMemSize;
2667		} else {
2668		    pMga->HWCursor = FALSE;
2669		    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2670			       "Too little offscreen memory for HW cursor; "
2671			       "using SW cursor\n");
2672		}
2673	    }
2674	} else { /* Second CRTC */
2675	    pMga->FbUsableSize = pMgaEnt->slaveFbMapSize;
2676	    pMga->HWCursor = FALSE;
2677	}
2678    } else {
2679        pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel;
2680           /* Allocate HW cursor buffer at the end of video ram */
2681        if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
2682	    if( pScrn->virtualY * pScrn->displayWidth *
2683	        pScrn->bitsPerPixel / 8 <=
2684        	pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
2685	        pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
2686	        pMga->FbCursorOffset =
2687		  pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize;
2688	    } else {
2689	        pMga->HWCursor = FALSE;
2690	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2691			   "Too little offscreen memory for HW cursor; "
2692			   "using SW cursor\n");
2693	    }
2694	}
2695    }
2696    /*
2697     * XXX This should be taken into account in some way in the mode valdation
2698     * section.
2699     */
2700
2701
2702    /* Load the required framebuffer */
2703    if (!xf86LoadSubModule(pScrn, "fb")) {
2704	MGAFreeRec(pScrn);
2705	return FALSE;
2706    }
2707
2708    /* Load XAA if needed */
2709    if (!pMga->NoAccel) {
2710#ifdef USE_EXA
2711	if (pMga->Exa) {
2712	    if (!xf86LoadSubModule(pScrn, "exa")) {
2713		MGAFreeRec(pScrn);
2714		return FALSE;
2715	    }
2716	} else {
2717#endif
2718#ifdef USE_XAA
2719	    if (!xf86LoadSubModule(pScrn, "xaa")) {
2720		MGAFreeRec(pScrn);
2721		return FALSE;
2722	    }
2723#endif
2724#ifdef USE_EXA
2725	}
2726#endif
2727    }
2728
2729    /* Load ramdac if needed */
2730    if (pMga->HWCursor) {
2731	if (!xf86LoadSubModule(pScrn, "ramdac")) {
2732	    MGAFreeRec(pScrn);
2733	    return FALSE;
2734	}
2735    }
2736
2737    /* Load shadowfb if needed */
2738    if (pMga->ShadowFB) {
2739	if (!xf86LoadSubModule(pScrn, "shadowfb")) {
2740	    MGAFreeRec(pScrn);
2741	    return FALSE;
2742	}
2743    }
2744
2745#ifdef XF86DRI
2746    /* Load the dri module if requested. */
2747    if (xf86ReturnOptValBool(pMga->Options, OPTION_DRI, FALSE)) {
2748       xf86LoadSubModule(pScrn, "dri");
2749    }
2750#endif
2751    pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
2752    pMga->CurrentLayout.depth = pScrn->depth;
2753    pMga->CurrentLayout.displayWidth = pScrn->displayWidth;
2754    pMga->CurrentLayout.weight.red = pScrn->weight.red;
2755    pMga->CurrentLayout.weight.green = pScrn->weight.green;
2756    pMga->CurrentLayout.weight.blue = pScrn->weight.blue;
2757    pMga->CurrentLayout.mode = pScrn->currentMode;
2758
2759
2760
2761    if(pMga->MergedFB) {
2762        MGAPreInitMergedFB(pScrn,flags);
2763    };
2764
2765
2766#ifdef USEMGAHAL
2767    MGA_HAL(
2768    /* Close the library after preinit */
2769    /* This needs to only happen after this board has completed preinit
2770     * both times
2771     */
2772
2773      if(pMga->DualHeadEnabled) {
2774	  /* Entity is shared make sure refcount == 2 */
2775	  /* If ref count is 2 then reset it to 0 */
2776	  if(pMgaEnt->refCount == 2) {
2777	      /* Both boards have done there initialization */
2778	      MGACloseLibrary(pMga->pBoard);
2779
2780	      if (pMga->pBoard)
2781	        xfree(pMga->pBoard);
2782	      if (pMga->pClientStruct)
2783	        xfree(pMga->pClientStruct);
2784	      if (pMga->pMgaModeInfo)
2785	        xfree(pMga->pMgaModeInfo);
2786	      if (pMga->pMgaHwInfo)
2787	        xfree(pMga->pMgaHwInfo);
2788	      pMgaEnt->refCount = 0;
2789	  }
2790      } else {
2791	  MGACloseLibrary(pMga->pBoard);
2792
2793	  if (pMga->pBoard)
2794	    xfree(pMga->pBoard);
2795	  if (pMga->pClientStruct)
2796	    xfree(pMga->pClientStruct);
2797	  if (pMga->pMgaModeInfo)
2798	    xfree(pMga->pMgaModeInfo);
2799	  if (pMga->pMgaHwInfo)
2800	    xfree(pMga->pMgaHwInfo);
2801      }
2802
2803    );	/* MGA_HAL */
2804#endif
2805
2806    xf86SetPrimInitDone(pScrn->entityList[0]);
2807
2808    return TRUE;
2809}
2810
2811
2812/*
2813 * Map the framebuffer and MMIO memory.
2814 */
2815
2816static Bool
2817MGAMapMem(ScrnInfoPtr pScrn)
2818{
2819    MGAPtr pMga = MGAPTR(pScrn);
2820#ifdef XSERVER_LIBPCIACCESS
2821    struct pci_device *const dev = pMga->PciInfo;
2822    struct pci_mem_region *region;
2823    void **memory[2];
2824    int i, err;
2825#endif
2826
2827
2828    if (!pMga->FBDev) {
2829#ifdef XSERVER_LIBPCIACCESS
2830        memory[pMga->io_bar] = &pMga->IOBase;
2831        memory[pMga->framebuffer_bar] = &pMga->FbBase;
2832
2833        for (i = 0; i < 2; i++) {
2834            region = &dev->regions[i];
2835            err = pci_device_map_range(dev,
2836                                       region->base_addr, region->size,
2837                                       PCI_DEV_MAP_FLAG_WRITABLE,
2838                                       memory[i]);
2839
2840            if (err) {
2841                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2842                           "Unable to map BAR %i.  %s (%d)\n",
2843                           i, strerror(err), err);
2844                return FALSE;
2845            }
2846        }
2847#else
2848	/*
2849	 * For Alpha, we need to map SPARSE memory, since we need
2850	 * byte/short access.  This is taken care of automatically by the
2851	 * os-support layer.
2852	 */
2853	pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex,
2854				     VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
2855				     pMga->PciTag, pMga->IOAddress, 0x4000);
2856	if (pMga->IOBase == NULL)
2857	    return FALSE;
2858
2859	pMga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
2860				     pMga->PciTag, pMga->FbAddress,
2861				     pMga->FbMapSize);
2862	if (pMga->FbBase == NULL)
2863	    return FALSE;
2864#endif
2865    }
2866    else {
2867	pMga->FbBase = fbdevHWMapVidmem(pScrn);
2868	if (pMga->FbBase == NULL) {
2869	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2870		       "Unable to map framebuffer.\n");
2871	    return FALSE;
2872	}
2873
2874	pMga->IOBase = fbdevHWMapMMIO(pScrn);
2875	if (pMga->IOBase == NULL) {
2876	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to map MMIO.\n");
2877	    return FALSE;
2878	}
2879    }
2880
2881
2882    pMga->FbStart = pMga->FbBase + pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
2883
2884    pMga->ILOADBase = NULL;
2885    if (pMga->iload_bar != -1) {
2886#ifdef XSERVER_LIBPCIACCESS
2887        region = &dev->regions[pMga->iload_bar];
2888        err = pci_device_map_range(dev,
2889                                   region->base_addr, region->size,
2890                                   PCI_DEV_MAP_FLAG_WRITABLE,
2891                                   (void *) &pMga->ILOADBase);
2892	if (err) {
2893	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2894		       "Unable to map BAR 2 (ILOAD region).  %s (%d)\n",
2895		       strerror(err), err);
2896	    return FALSE;
2897	}
2898#else
2899	pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex,
2900					VIDMEM_MMIO | VIDMEM_MMIO_32BIT |
2901					VIDMEM_READSIDEEFFECT,
2902					pMga->PciTag, pMga->ILOADAddress,
2903					0x800000);
2904#endif
2905    }
2906
2907
2908    return TRUE;
2909}
2910
2911
2912/*
2913 * Unmap the framebuffer and MMIO memory.
2914 */
2915
2916static Bool
2917MGAUnmapMem(ScrnInfoPtr pScrn)
2918{
2919    MGAPtr pMga = MGAPTR(pScrn);
2920#ifdef XSERVER_LIBPCIACCESS
2921    struct pci_device * const dev = pMga->PciInfo;
2922#endif
2923
2924
2925    if (!pMga->FBDev) {
2926#ifdef XSERVER_LIBPCIACCESS
2927        pci_device_unmap_range(dev, pMga->IOBase,
2928			       dev->regions[pMga->io_bar].size);
2929        pci_device_unmap_range(dev, pMga->FbBase,
2930			       dev->regions[pMga->framebuffer_bar].size);
2931#else
2932	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000);
2933	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize);
2934#endif
2935    }
2936    else {
2937	fbdevHWUnmapVidmem(pScrn);
2938	fbdevHWUnmapMMIO(pScrn);
2939    }
2940
2941    if ((pMga->iload_bar != -1) && (pMga->ILOADBase != NULL)) {
2942#ifdef XSERVER_LIBPCIACCESS
2943        pci_device_unmap_range(dev, pMga->ILOADBase,
2944			       dev->regions[pMga->iload_bar].size);
2945#else
2946	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->ILOADBase, 0x800000);
2947#endif
2948    }
2949
2950    pMga->IOBase = NULL;
2951    pMga->FbBase = NULL;
2952    pMga->FbStart = NULL;
2953    pMga->ILOADBase = NULL;
2954
2955    return TRUE;
2956}
2957
2958
2959/*
2960 * This function saves the video state.
2961 */
2962static void
2963MGASave(ScrnInfoPtr pScrn)
2964{
2965    vgaHWPtr hwp = VGAHWPTR(pScrn);
2966    vgaRegPtr vgaReg = &hwp->SavedReg;
2967    MGAPtr pMga = MGAPTR(pScrn);
2968    MGARegPtr mgaReg = &pMga->SavedReg;
2969
2970    if(pMga->SecondCrtc == TRUE) return;
2971#ifdef USEMGAHAL
2972    MGA_HAL(if (pMga->pBoard != NULL) MGASaveVgaState(pMga->pBoard));
2973#endif
2974
2975    /* I need to save the registers for the second head also */
2976    /* Save the register for 0x80 to 0xa0 */
2977    /* Could call it dac2Saved */
2978
2979    /* Only save text mode fonts/text for the primary card */
2980    (*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary);
2981}
2982
2983#ifdef USEMGAHAL
2984/* Convert DisplayModeRec parameters in MGAMODEINFO parameters.
2985*  mode parameter optionnal. */
2986void
2987MGAFillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode)
2988{
2989     const char *s;
2990    MGAPtr pMga = MGAPTR(pScrn);
2991
2992    Bool digital1 = FALSE;
2993    Bool digital2 = FALSE;
2994    Bool tv1 = FALSE;
2995    Bool tv2 = FALSE;
2996    Bool swap_head
2997      = xf86ReturnOptValBool(pMga->Options, OPTION_SWAPPED_HEAD, FALSE);
2998
2999    if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) {
3000        mode = pMga->SecondCrtc ?
3001             ((MergedDisplayModePtr)mode->Private)->Monitor2
3002            : ((MergedDisplayModePtr)mode->Private)->Monitor1;
3003    }
3004
3005
3006    if (pMga->pMgaHwInfo)
3007    {
3008	digital1 = ISDIGITAL1(pMga);
3009	digital2 = ISDIGITAL2(pMga);
3010	tv1 = ISTV1(pMga);
3011	tv2 = ISTV2(pMga);
3012    }
3013
3014    /*FIXME: causes segfault elsewhere if not commented*/
3015    /*if(!pMga->pMgaModeInfo)*/ pMga->pMgaModeInfo = xalloc(sizeof(MGAMODEINFO));
3016    pMga->pMgaModeInfo->flOutput = 0;
3017    pMga->pMgaModeInfo->ulDeskWidth = pScrn->virtualX;
3018    pMga->pMgaModeInfo->ulDeskHeight = pScrn->virtualY;
3019    pMga->pMgaModeInfo->ulFBPitch = 0;
3020    pMga->pMgaModeInfo->ulBpp = pScrn->bitsPerPixel;
3021    pMga->pMgaModeInfo->ulZoom = 1;
3022    pMga->pMgaModeInfo->flSignalMode = 0x10;
3023
3024    /* Set TV standard */
3025    if ((s = xf86GetOptValString(pMga->Options, OPTION_TVSTANDARD))) {
3026    	if (!xf86NameCmp(s, "PAL")) {
3027    		pMga->pMgaModeInfo->flSignalMode = 0x00;
3028    		pMga->pMgaModeInfo->ulRefreshRate = 50;
3029    		pMga->pMgaModeInfo->ulTVStandard = TV_PAL;
3030    	} else {
3031    		pMga->pMgaModeInfo->ulRefreshRate = 60;
3032    		pMga->pMgaModeInfo->ulTVStandard = TV_NTSC;
3033    	}
3034    } else {
3035    	pMga->pMgaModeInfo->ulRefreshRate = 0;
3036    	pMga->pMgaModeInfo->ulTVStandard = TV_NTSC;
3037    }
3038
3039    /* Set Cable Type */
3040    if ((s = xf86GetOptValString(pMga->Options, OPTION_CABLETYPE))) {
3041    	if (!xf86NameCmp(s, "SCART_RGB")) {
3042    		pMga->pMgaModeInfo->ulCableType = TV_SCART_RGB;
3043    	} else if (!xf86NameCmp(s, "SCART_COMPOSITE")) {
3044    		pMga->pMgaModeInfo->ulCableType = TV_SCART_COMPOSITE;
3045    	} else if (!xf86NameCmp(s, "SCART_TYPE2")) {
3046    		pMga->pMgaModeInfo->ulCableType = TV_SCART_TYPE2;
3047    	} else {
3048    		pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE;
3049    	}
3050    } else {
3051    	pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE;
3052    }
3053
3054    if(mode) {
3055        pMga->pMgaModeInfo->ulHorizRate = 0;
3056        pMga->pMgaModeInfo->ulDispWidth = mode->HDisplay;
3057        pMga->pMgaModeInfo->ulDispHeight = mode->VDisplay;
3058        pMga->pMgaModeInfo->ulPixClock = mode->Clock;
3059        pMga->pMgaModeInfo->ulHFPorch = mode->HSyncStart - mode->HDisplay;
3060        pMga->pMgaModeInfo->ulHSync = mode->HSyncEnd - mode->HSyncStart;
3061        pMga->pMgaModeInfo->ulHBPorch = mode->HTotal - mode->HSyncEnd;
3062        pMga->pMgaModeInfo->ulVFPorch = mode->VSyncStart - mode->VDisplay;
3063        pMga->pMgaModeInfo->ulVSync = mode->VSyncEnd - mode->VSyncStart;
3064        pMga->pMgaModeInfo->ulVBPorch = mode->VTotal - mode->VSyncEnd;
3065    }
3066    /* Use DstOrg directly */
3067    /* This is an offset in pixels not memory */
3068    pMga->pMgaModeInfo->ulDstOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8);
3069    pMga->pMgaModeInfo->ulDisplayOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8);
3070    pMga->pMgaModeInfo->ulPanXGran = 0;
3071    pMga->pMgaModeInfo->ulPanYGran = 0;
3072
3073    if(pMga->SecondCrtc == TRUE) {
3074	pMga->pMgaModeInfo->flOutput = MGAMODEINFO_SECOND_CRTC |
3075				       MGAMODEINFO_FORCE_PITCH |
3076				       MGAMODEINFO_FORCE_DISPLAYORG;
3077	if (digital2) {
3078	    pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2;
3079	} else if (tv2) {
3080	    pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV;
3081	} else {
3082            if (!swap_head) {
3083	      pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2;
3084            } else {
3085              pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1;
3086            }
3087	}
3088    } else {
3089	pMga->pMgaModeInfo->flOutput = MGAMODEINFO_FORCE_PITCH;
3090        if (digital1) {
3091	    if ((pMga->Chipset == PCI_CHIP_MGAG200) ||
3092		(pMga->Chipset == PCI_CHIP_MGAG200_PCI)) {
3093		pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_FLATPANEL1;
3094		pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2;
3095	    } else {
3096		pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL1;
3097	    }
3098        } else if (tv1) {
3099	    pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV;
3100       	} else {
3101            if (!swap_head) {
3102	        pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1;
3103            } else {
3104                pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2;
3105            }
3106        }
3107    }
3108    pMga->pMgaModeInfo->ulFBPitch = pScrn->displayWidth;
3109}
3110#endif
3111
3112/*
3113 * Initialise a new mode.  This is currently still using the old
3114 * "initialise struct, restore/write struct to HW" model.  That could
3115 * be changed.
3116 */
3117
3118static Bool
3119MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
3120{
3121    vgaHWPtr hwp = VGAHWPTR(pScrn);
3122    vgaRegPtr vgaReg;
3123    MGAPtr pMga = MGAPTR(pScrn);
3124    MGARegPtr mgaReg;
3125
3126#ifdef USEMGAHAL
3127   ULONG status;
3128#endif
3129    vgaHWUnlock(hwp);
3130
3131/*    if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) {
3132        mode = (DisplayModePtr)mode->Private;
3133    }*/
3134
3135    /* Initialise the ModeReg values */
3136    if (!vgaHWInit(pScrn, mode))
3137	return FALSE;
3138    pScrn->vtSema = TRUE;
3139
3140    if (!(*pMga->ModeInit)(pScrn, mode))
3141	return FALSE;
3142
3143    /* Program the registers */
3144    if (pMga->is_G200SE) {
3145	MGAG200SEHWProtect(pScrn, TRUE);
3146    } else {
3147	vgaHWProtect(pScrn, TRUE);
3148    }
3149    vgaReg = &hwp->ModeReg;
3150    mgaReg = &pMga->ModeReg;
3151#ifdef USEMGAHAL
3152    MGA_HAL(
3153        MGAFillModeInfoStruct(pScrn,mode);
3154
3155        /* Validate the parameters */
3156        if ((status = MGAValidateMode(pMga->pBoard, pMga->pMgaModeInfo)) != 0) {
3157            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3158                    "MGAValidateMode from HALlib found the mode to be invalid.\n"
3159                    "\tError: %lx\n", status);
3160            return FALSE;
3161        }
3162
3163        /*
3164         * Find mode for second head.
3165         */
3166        if(pMga->MergedFB) {
3167
3168            MGAFillModeInfoStruct(pMga->pScrn2,mode);
3169            /* Validates the Video parameters */
3170            if ((status = MGAValidateVideoParameters(pMga->pBoard, MGAPTR(pMga->pScrn2)->pMgaModeInfo))
3171                != 0) {
3172                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3173                        "MGAValidateVideoParameters from HALlib found the mode to be invalid.\n\tError: %lx\n", status);
3174                return FALSE;
3175            }
3176        }
3177    );	 /*MGA_HAL */
3178
3179#endif
3180
3181#ifdef USEMGAHAL
3182MGA_HAL(
3183
3184    /*************************** ESC *****************************/
3185    TmpMgaModeInfo[0] =  *pMga->pMgaModeInfo;
3186
3187    if(pMga->SecondCrtc == TRUE)
3188        pMgaModeInfo[1] = pMga->pMgaModeInfo;
3189    else
3190        pMgaModeInfo[0] = pMga->pMgaModeInfo;
3191
3192	TmpMgaModeInfo[0].ulDispWidth = 0;
3193
3194    if(!pMga->MergedFB) /* FIXME: Must deal with this once PowerDesk & MergedFB
3195                           compatibility will exist */
3196        MGAFillDisplayModeStruct(mode, pMga->pMgaModeInfo);
3197    /*************************************************************/
3198
3199);	/* MGA_HAL */
3200#endif
3201
3202#ifdef XF86DRI
3203   if (pMga->directRenderingEnabled) {
3204       DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
3205   }
3206#endif
3207
3208#ifdef USEMGAHAL
3209    MGA_HAL(
3210    /* Initialize the board */
3211    if(MGASetMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) {
3212	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3213		"MGASetMode returned an error."
3214		"  Make sure to validate the mode before.\n");
3215	return FALSE;
3216    }
3217    if(pMga->MergedFB
3218       && MGASetMode(pMga->pBoard,MGAPTR(pMga->pScrn2)->pMgaModeInfo) != 0) {
3219  	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3220		   "MGASetMode returned an error."
3221		   "  Make sure to validate the mode before.\n");
3222    }
3223
3224    );	/* MGA_HAL */
3225
3226    /* getting around bugs in the HAL lib. MATROX: hint, hint. */
3227    MGA_HAL(
3228	    if (pMga->chip_attribs->hwcursor_1064) {
3229		if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) {
3230		outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW,
3231			  pMga->FbCursorOffset >> 10);
3232		outMGAdac(MGA1064_CURSOR_BASE_ADR_HI,
3233			  pMga->FbCursorOffset >> 18);
3234		outMGAdac(MGA1064_CURSOR_CTL, 0x00);
3235	      }
3236	    }
3237    );	/* MGA_HAL */
3238#endif
3239
3240    MGA_NOT_HAL((*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE));
3241
3242    MGAStormSync(pScrn);
3243    MGAStormEngineInit(pScrn);
3244
3245    if (pMga->is_G200SE) {
3246	MGAG200SEHWProtect(pScrn,FALSE);
3247    } else {
3248	vgaHWProtect(pScrn, FALSE);
3249    }
3250
3251    if (xf86IsPc98()) {
3252	if (pMga->Chipset == PCI_CHIP_MGA2064)
3253	    outb(0xfac, 0x01);
3254	else
3255	    outb(0xfac, 0x02);
3256    }
3257
3258    MGA_NOT_HAL(
3259	if (pMga->is_G200SE) {
3260            OUTREG8(0x1FDE, 0x06);
3261	    if (pMga->reg_1e24 == 0x01)
3262		OUTREG8(0x1FDF, 0x03);
3263	    else
3264		OUTREG8(0x1FDF, 0x14);
3265        }
3266    );
3267
3268    pMga->CurrentLayout.mode = mode;
3269
3270    if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) {
3271	pMga->M1currentMode = (DisplayModePtr)mode->Private;
3272    }
3273
3274#ifdef XF86DRI
3275   if (pMga->directRenderingEnabled)
3276     DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
3277#endif
3278#ifdef DEBUG
3279   MGAG450PrintPLL(pScrn);
3280#endif
3281    return TRUE;
3282}
3283
3284static
3285void MGARestoreSecondCrtc(ScrnInfoPtr pScrn)
3286{
3287    MGAPtr pMga = MGAPTR(pScrn);
3288
3289    if (MGAISGx50(pMga)) {
3290        /* Force to return in clone mode */
3291        if (pMga->SecondOutput
3292                && (xf86IsEntityShared(pScrn->entityList[0]) || pMga->SecondCrtc)
3293                && !pMga->MergedFB) {
3294            /* Do this branch if
3295             * SecondOutput
3296             * and not Unshared Primary
3297             * and not Merged Mode (usualy means Unshared Primary)
3298             */
3299            CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL);
3300
3301            ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK;
3302            ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1;
3303
3304            outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl);
3305
3306       } else {
3307            CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL);
3308            CARD32 ulC2CTL = INREG(MGAREG_C2CTL);
3309
3310            ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK;
3311            ucXDispCtrl |= MGA1064_DISP_CTL_DAC1OUTSEL_EN;
3312            ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1;
3313
3314            /* crtcdacsel -> crtc1 */
3315            ulC2CTL &= ~MGAREG_C2CTL_CRTCDACSEL_CRTC2;
3316            ulC2CTL |= MGAREG_C2CTL_CRTCDACSEL_CRTC1;
3317
3318            outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl);
3319            OUTREG(MGAREG_C2CTL, ulC2CTL);
3320       }
3321
3322    } else {
3323        /* Force to close second crtc */
3324        CARD32 ulC2CTL = INREG(MGAREG_C2CTL);
3325
3326        ulC2CTL &= ~MGAREG_C2CTL_C2_EN;
3327
3328        OUTREG(MGAREG_C2CTL, ulC2CTL);
3329    }
3330}
3331
3332/*
3333 * Restore the initial (text) mode.
3334 */
3335static void
3336MGARestore(ScrnInfoPtr pScrn)
3337{
3338    vgaHWPtr hwp = VGAHWPTR(pScrn);
3339    vgaRegPtr vgaReg = &hwp->SavedReg;
3340    MGAPtr pMga = MGAPTR(pScrn);
3341    MGARegPtr mgaReg = &pMga->SavedReg;
3342
3343    if (pScrn->pScreen != NULL)
3344	MGAStormSync(pScrn);
3345
3346    /*
3347     * Restore the second crtc if:
3348     * first and only driver entity
3349     * second entity
3350     * Merged Framebuffer mode (first and only driver entity)
3351     */
3352    if((!xf86IsEntityShared(pScrn->entityList[0]) && !pMga->SecondCrtc)
3353       || pMga->SecondCrtc || pMga->MergedFB) {
3354	/*       if(pMga->MergedFB) {
3355		 if(pMga->pScrn2)
3356                 MGARestoreSecondCrtc(pMga->pScrn2);
3357		 } else*/
3358	MGARestoreSecondCrtc(pScrn);
3359	/* if we are second instance of driver, we've done our job, exit */
3360	if(pMga->SecondCrtc) return;
3361    }
3362
3363    /* Only restore text mode fonts/text for the primary card */
3364    if (pMga->is_G200SE) {
3365	MGAG200SEHWProtect(pScrn,TRUE);
3366    } else {
3367	vgaHWProtect(pScrn, TRUE);
3368    }
3369    if (pMga->Primary) {
3370#ifdef USEMGAHAL
3371	MGA_HAL(
3372	    if(pMga->pBoard != NULL) {
3373		MGASetVgaMode(pMga->pBoard);
3374		MGARestoreVgaState(pMga->pBoard);
3375	    }
3376	    );	/* MGA_HAL */
3377#endif
3378        (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE);
3379    } else {
3380        vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
3381    }
3382
3383    if (pMga->is_G200SE) {
3384	MGAG200SEHWProtect(pScrn,FALSE);
3385    } else {
3386	vgaHWProtect(pScrn,FALSE);
3387    }
3388}
3389
3390
3391/* Workaround for a G400 CRTC2 display problem */
3392static void
3393MGACrtc2FillStrip(ScrnInfoPtr pScrn)
3394{
3395    MGAPtr pMga = MGAPTR(pScrn);
3396
3397    if (pMga->NoAccel) {
3398	/* Clears the whole screen, but ... */
3399	bzero(pMga->FbStart,
3400	    (pScrn->bitsPerPixel >> 3) * pScrn->displayWidth * pScrn->virtualY);
3401    } else {
3402	xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex);
3403	pMga->RestoreAccelState(pScrn);
3404	pMga->SetupForSolidFill(pScrn, 0, GXcopy, 0xFFFFFFFF);
3405	pMga->SubsequentSolidFillRect(pScrn, pScrn->virtualX, 0,
3406				  pScrn->displayWidth - pScrn->virtualX,
3407				  pScrn->virtualY);
3408	MGAStormSync(pScrn);
3409    }
3410}
3411
3412
3413/* Mandatory */
3414
3415/* This gets called at the start of each server generation */
3416
3417static Bool
3418MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
3419{
3420    ScrnInfoPtr pScrn;
3421    vgaHWPtr hwp;
3422    MGAPtr pMga;
3423    MGARamdacPtr MGAdac;
3424    int ret;
3425    VisualPtr visual;
3426    unsigned char *FBStart;
3427    int width, height, displayWidth;
3428    MGAEntPtr pMgaEnt = NULL;
3429    int f;
3430    CARD32 VRTemp, FBTemp;
3431#ifdef XF86DRI
3432    MessageType driFrom = X_DEFAULT;
3433#endif
3434    DPMSSetProcPtr mga_dpms_set_proc = NULL;
3435
3436    /*
3437     * First get the ScrnInfoRec
3438     */
3439    pScrn = xf86Screens[pScreen->myNum];
3440
3441    hwp = VGAHWPTR(pScrn);
3442    pMga = MGAPTR(pScrn);
3443    MGAdac = &pMga->Dac;
3444
3445    if (pMga->is_G200SE) {
3446	VRTemp = pScrn->videoRam;
3447	FBTemp = pMga->FbMapSize;
3448	pScrn->videoRam = 8192;
3449	pMga->FbMapSize = pScrn->videoRam * 1024;
3450    }
3451
3452
3453    /* Map the MGA memory and MMIO areas */
3454    if (!MGAMapMem(pScrn))
3455	return FALSE;
3456
3457
3458    /* Select functions that vary based on the CRTC configureation of the
3459     * screen.
3460     */
3461    if (!pMga->MergedFB) {
3462	if (pMga->SecondCrtc) {
3463	    mga_dpms_set_proc = MGADisplayPowerManagementSetCrtc2;
3464	    pScreen->SaveScreen = MGASaveScreenCrtc2;
3465	}
3466	else {
3467	    mga_dpms_set_proc = MGADisplayPowerManagementSet;
3468	    pScreen->SaveScreen = MGASaveScreen;
3469	}
3470    }
3471    else {
3472        pScreen->SaveScreen = MGASaveScreenMerged;
3473	mga_dpms_set_proc = MGADisplayPowerManagementSetMerged;
3474    }
3475
3476
3477    if ((pMga->Chipset == PCI_CHIP_MGAG100)
3478	|| (pMga->Chipset == PCI_CHIP_MGAG100_PCI))
3479        MGAG100BlackMagic(pScrn);
3480
3481    if (pMga->DualHeadEnabled) {
3482       DevUnion *pPriv;
3483       pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
3484       pMgaEnt = pPriv->ptr;
3485       pMgaEnt->refCount++;
3486#ifdef USEMGAHAL
3487       MGA_HAL(
3488       if(pMgaEnt->refCount == 1) {
3489	   CARD8 MiscCtlReg;
3490	  pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());
3491	  pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));
3492	  pMga->pClientStruct->pMga = (MGAPtr) pMga;
3493
3494	  /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/
3495          MiscCtlReg = inMGAdac(MGA1064_MISC_CTL);
3496	  MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
3497	  outMGAdac(MGA1064_MISC_CTL,MiscCtlReg);
3498	  pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO));
3499	  MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
3500
3501	  /* Detecting for type of display */
3502	  if (pMga->pMgaHwInfo->ulCapsSecondOutput & MGAHWINFOCAPS_OUTPUT_TV) {
3503	  	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TV detected\n");
3504	  }
3505	  if (pMga->pMgaHwInfo->ulCapsFirstOutput &
3506			MGAHWINFOCAPS_OUTPUT_DIGITAL) {
3507	  	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
3508				"Digital Screen detected\n");
3509	  }
3510	  if (pMga->pMgaHwInfo->ulCapsSecondOutput &
3511			MGAHWINFOCAPS_OUTPUT_DIGITAL) {
3512	  	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
3513				"Digital Screen detected\n");
3514	  }
3515
3516	  /* Now copy these to the entitystructure */
3517	  pMgaEnt->pClientStruct = pMga->pClientStruct;
3518	  pMgaEnt->pBoard = pMga->pBoard;
3519	  pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo;
3520       } else { /* Ref count is 2 */
3521	  pMga->pClientStruct = pMgaEnt->pClientStruct;
3522	  pMga->pBoard = pMgaEnt->pBoard;
3523	  pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo;
3524       }
3525       );	/* MGA_HAL */
3526#endif
3527    } else {
3528#ifdef USEMGAHAL
3529	CARD8 MiscCtlReg;
3530
3531	  MGA_HAL(
3532	  pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());
3533	  pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));
3534	  pMga->pClientStruct->pMga = (MGAPtr) pMga;
3535
3536	  MiscCtlReg = inMGAdac(MGA1064_MISC_CTL);
3537	  /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/
3538	  MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
3539	  outMGAdac(MGA1064_MISC_CTL,MiscCtlReg);
3540	  pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO));
3541	  MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
3542	  );	/* MGA_HAL */
3543#endif
3544    }
3545    if (pMga->is_G200SE) {
3546	pScrn->videoRam = VRTemp;
3547	pMga->FbMapSize = FBTemp;
3548    }
3549#ifdef USEMGAHAL
3550    MGA_HAL(
3551	/* There is a problem in the HALlib: set soft reset bit */
3552	/* MATROX: hint, hint. */
3553	if (!pMga->Primary && !pMga->FBDev &&
3554	    (SUBSYS_ID(pMga->PciInfo) == PCI_CARD_MILL_G200_SG)) {
3555	    OUTREG(MGAREG_Reset, 1);
3556	    usleep(200);
3557	    OUTREG(MGAREG_Reset, 0);
3558	}
3559    );	/* MGA_HAL */
3560#endif
3561
3562    /* Initialise the MMIO vgahw functions */
3563    vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET);
3564    vgaHWGetIOBase(hwp);
3565
3566    /* Map the VGA memory when the primary video */
3567    if (!pMga->FBDev) {
3568	if (pMga->Primary) {
3569	    hwp->MapSize = 0x10000;
3570	    if (!vgaHWMapMem(pScrn))
3571		return FALSE;
3572	}
3573
3574	/* Save the current state */
3575	MGASave(pScrn);
3576	/* Initialise the first mode */
3577	if (!MGAModeInit(pScrn, pScrn->currentMode))
3578	    return FALSE;
3579    }
3580    else {
3581	fbdevHWSave(pScrn);
3582	/* Disable VGA core, and leave memory access on */
3583#ifdef XSERVER_LIBPCIACCESS
3584	pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000000,
3585				  PCI_OPTION_REG);
3586#else
3587	pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000);
3588#endif
3589	if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
3590	    return FALSE;
3591
3592        if (!pMga->SecondCrtc && pMga->HWCursor
3593	    && pMga->chip_attribs->hwcursor_1064) {
3594	    outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, pMga->FbCursorOffset >> 10);
3595	    outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, pMga->FbCursorOffset >> 18);
3596	}
3597
3598	MGAStormEngineInit(pScrn);
3599    }
3600
3601    /* Darken the screen for aesthetic reasons and set the viewport
3602     */
3603    (*pScreen->SaveScreen)(pScreen, SCREEN_SAVER_ON);
3604    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
3605
3606
3607    /*
3608     * The next step is to setup the screen's visuals, and initialise the
3609     * framebuffer code.  In cases where the framebuffer's default
3610     * choices for things like visual layouts and bits per RGB are OK,
3611     * this may be as simple as calling the framebuffer's ScreenInit()
3612     * function.  If not, the visuals will need to be setup before calling
3613     * a fb ScreenInit() function and fixed up after.
3614     *
3615     * For most PC hardware at depths >= 8, the defaults that cfb uses
3616     * are not appropriate.  In this driver, we fixup the visuals after.
3617     */
3618
3619    /*
3620     * Reset the visual list.
3621     */
3622    miClearVisualTypes();
3623
3624    /* Setup the visuals we support. */
3625
3626    /* All MGA support DirectColor */
3627    if (pMga->SecondCrtc) {
3628	/* No DirectColor on the second head */
3629	if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
3630			      TrueColor))
3631		return FALSE;
3632	if (!miSetPixmapDepths ())
3633	    return FALSE;
3634    } else {
3635	if (!xf86SetDefaultVisual(pScrn, -1))
3636	    return FALSE;
3637
3638	if (!miSetVisualTypes(pScrn->depth,
3639			      miGetDefaultVisualMask(pScrn->depth),
3640			      pScrn->rgbBits, pScrn->defaultVisual))
3641	    return FALSE;
3642	if (!miSetPixmapDepths ())
3643	    return FALSE;
3644    }
3645
3646    /*
3647     * Call the framebuffer layer's ScreenInit function, and fill in other
3648     * pScreen fields.
3649     */
3650
3651    width = pScrn->virtualX;
3652    height = pScrn->virtualY;
3653    displayWidth = pScrn->displayWidth;
3654
3655
3656    if(pMga->Rotate) {
3657	height = pScrn->virtualX;
3658	width = pScrn->virtualY;
3659    }
3660
3661    if(pMga->ShadowFB) {
3662 	pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
3663	pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height);
3664	displayWidth = pMga->ShadowPitch / (pScrn->bitsPerPixel >> 3);
3665        FBStart = pMga->ShadowPtr;
3666    } else {
3667	pMga->ShadowPtr = NULL;
3668	FBStart = pMga->FbStart;
3669    }
3670
3671#ifdef XF86DRI
3672     /*
3673      * Setup DRI after visuals have been established.
3674      *
3675      * The DRI does not work when textured video is enabled at this time.
3676      */
3677    if (pMga->is_G200SE) {
3678	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3679		   "Not supported by hardware, not initializing the DRI\n");
3680	pMga->directRenderingEnabled = FALSE;
3681	driFrom = X_PROBED;
3682    } else if (!xf86ReturnOptValBool(pMga->Options, OPTION_DRI, TRUE)) {
3683	driFrom = X_CONFIG;
3684    } else if ( pMga->NoAccel ) {
3685       xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
3686		   "Acceleration disabled, not initializing the DRI\n" );
3687       pMga->directRenderingEnabled = FALSE;
3688       driFrom = X_CONFIG;
3689    }
3690    else if ( pMga->TexturedVideo == TRUE ) {
3691       xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
3692		   "Textured video enabled, not initializing the DRI\n" );
3693       pMga->directRenderingEnabled = FALSE;
3694       driFrom = X_CONFIG;
3695    }
3696    else if (pMga->SecondCrtc == TRUE) {
3697       xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
3698		   "Not initializing the DRI on the second head\n" );
3699       pMga->directRenderingEnabled = FALSE;
3700    }
3701    else if ((pMga->FbMapSize /
3702	       (width * (pScrn->bitsPerPixel >> 3))) <= height * 3) {
3703       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3704	  "Static buffer allocation failed, not initializing the DRI\n");
3705       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3706	  "Need at least %d kB video memory at this resolution, bit depth\n",
3707	  (3 * displayWidth * height * (pScrn->bitsPerPixel >> 3)) / 1024 );
3708       pMga->directRenderingEnabled = FALSE;
3709       driFrom = X_PROBED;
3710    }
3711    else {
3712       pMga->directRenderingEnabled = MGADRIScreenInit(pScreen);
3713    }
3714#endif
3715
3716
3717    if (!fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi,
3718		      pScrn->yDpi, displayWidth, pScrn->bitsPerPixel)) {
3719	return FALSE;
3720    }
3721
3722
3723    if (pScrn->bitsPerPixel > 8) {
3724        /* Fixup RGB ordering */
3725        visual = pScreen->visuals + pScreen->numVisuals;
3726        while (--visual >= pScreen->visuals) {
3727	    if ((visual->class | DynamicClass) == DirectColor) {
3728		visual->offsetRed = pScrn->offset.red;
3729		visual->offsetGreen = pScrn->offset.green;
3730		visual->offsetBlue = pScrn->offset.blue;
3731		visual->redMask = pScrn->mask.red;
3732		visual->greenMask = pScrn->mask.green;
3733		visual->blueMask = pScrn->mask.blue;
3734	    }
3735	}
3736    }
3737
3738    /* must be after RGB ordering fixed */
3739    fbPictureInit (pScreen, 0, 0);
3740
3741    xf86SetBlackWhitePixels(pScreen);
3742
3743    pMga->BlockHandler = pScreen->BlockHandler;
3744    pScreen->BlockHandler = MGABlockHandler;
3745
3746    if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */
3747	MGADGAInit(pScreen);
3748
3749    if (!pMga->NoAccel) {
3750#ifdef USE_EXA
3751	if (pMga->Exa)
3752	    mgaExaInit(pScreen);
3753	else
3754#endif
3755#ifdef USE_XAA
3756	    MGAStormAccelInit(pScreen);
3757#endif
3758    }
3759
3760    miInitializeBackingStore(pScreen);
3761    xf86SetBackingStore(pScreen);
3762    xf86SetSilkenMouse(pScreen);
3763
3764    /* Initialize software cursor.
3765	Must precede creation of the default colormap */
3766    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
3767
3768    /* Initialize HW cursor layer.
3769	Must follow software cursor initialization*/
3770    if (pMga->HWCursor) {
3771	if(!MGAHWCursorInit(pScreen))
3772	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3773		"Hardware cursor initialization failed\n");
3774    }
3775    if(pMga->MergedFB) {
3776        /* Rotate and MergedFB are mutiualy exclusive, so we can use this
3777         * variable.
3778         */
3779        if (!pMga->PointerMoved)
3780            pMga->PointerMoved = pScrn->PointerMoved;
3781        pScrn->PointerMoved = MGAMergePointerMoved;
3782
3783    }
3784
3785    /* Initialise default colourmap */
3786    if (!miCreateDefColormap(pScreen))
3787	return FALSE;
3788
3789    /* Initialize colormap layer.
3790	Must follow initialization of the default colormap */
3791    if (!pMga->SecondCrtc)
3792	f = CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH;
3793    else
3794	f = CMAP_RELOAD_ON_MODE_SWITCH;
3795    if(!xf86HandleColormaps(pScreen, 256, 8,
3796	pMga->FBDev ? fbdevHWLoadPaletteWeak() : MGAdac->LoadPalette,
3797	NULL, f))
3798	return FALSE;
3799
3800    if(pMga->ShadowFB) {
3801	RefreshAreaFuncPtr refreshArea = MGARefreshArea;
3802
3803	if(pMga->Rotate) {
3804	    if (!pMga->PointerMoved) {
3805	    pMga->PointerMoved = pScrn->PointerMoved;
3806	    pScrn->PointerMoved = MGAPointerMoved;
3807	    }
3808
3809	   switch(pScrn->bitsPerPixel) {
3810	   case 8:	refreshArea = MGARefreshArea8;	break;
3811	   case 16:	refreshArea = MGARefreshArea16;	break;
3812	   case 24:	refreshArea = MGARefreshArea24;	break;
3813	   case 32:	refreshArea = MGARefreshArea32;	break;
3814	   }
3815	}
3816
3817	ShadowFBInit(pScreen, refreshArea);
3818    }
3819
3820    xf86DPMSInit(pScreen, mga_dpms_set_proc, 0);
3821
3822    pScrn->memPhysBase = pMga->FbAddress;
3823    pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
3824
3825    MGAInitVideo(pScreen);
3826
3827#ifdef XF86DRI
3828    if (pMga->directRenderingEnabled) {
3829       /* Now that mi, drm and others have done their thing,
3830	* complete the DRI setup.
3831	*/
3832       pMga->directRenderingEnabled = MGADRIFinishScreenInit(pScreen);
3833    }
3834    if (pMga->directRenderingEnabled) {
3835        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
3836    } else {
3837        xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n");
3838    }
3839    if (pMga->DualHeadEnabled && pMga->SecondCrtc == FALSE)
3840	pMgaEnt->directRenderingEnabled = pMga->directRenderingEnabled;
3841    pMga->haveQuiescense = 1;
3842#endif
3843
3844    /* Wrap the current CloseScreen function */
3845    pMga->CloseScreen = pScreen->CloseScreen;
3846    pScreen->CloseScreen = MGACloseScreen;
3847
3848    /* Report any unused options (only for the first generation) */
3849    if (serverGeneration == 1) {
3850	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
3851    }
3852
3853    /* For the second head, work around display problem. */
3854    if (!pMga->MergedFB && pMga->SecondCrtc) {
3855	MGACrtc2FillStrip(pScrn);
3856    }
3857
3858    /* Done */
3859    return TRUE;
3860}
3861
3862
3863/* Usually mandatory */
3864Bool
3865MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
3866{
3867#ifdef USEMGAHAL
3868    char sCmdIn[256];
3869    char sCmdOut[256];
3870    FILE* fdIn;
3871# ifdef MATROX_WRITEBACK
3872    FILE* fdOut;
3873# endif
3874#endif
3875
3876    if  (mode->Flags & 0x80000000) {
3877#ifdef USEMGAHAL
3878
3879# ifdef MATROX_WRITEBACK
3880#  define MWB(x) { x; }
3881#  define MWB_COND(x) x
3882# else
3883#  define MWB(x)
3884#  define MWB_COND(x) 1
3885# endif
3886	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
3887
3888	MGA_HAL(
3889	fdIn = fopen("/tmp/mgaDriverIn", "rt");
3890	MWB(fdOut = fopen("/tmp/mgaDriverOut", "wt"))
3891
3892	if(fdIn && MWB_COND(fdOut))
3893	{
3894
3895	    fgets(sCmdIn, 255, fdIn);
3896
3897	    if(sCmdIn)
3898	    {
3899
3900		MGAExecuteEscCmd(xf86Screens[scrnIndex], sCmdIn, sCmdOut, mode);
3901
3902		/* Remove file and close file descriptor */
3903		remove("/tmp/mgaDriverIn");
3904		fclose(fdIn);
3905		MWB(
3906		    /* Write output data to output file for
3907		       calling application */
3908		    fputs(sCmdOut, fdOut);
3909		    fclose(fdOut);
3910		    )
3911		mode->Flags &= 0x7FFFFFFF;
3912		return TRUE;
3913	    }
3914	    else
3915	    {
3916		mode->Flags &= 0x7FFFFFFF;
3917		return FALSE;
3918	    }
3919	}
3920	else
3921	{
3922	    mode->Flags &= 0x7FFFFFFF;
3923	    return FALSE;
3924	}
3925   )
3926#endif
3927 	return FALSE;
3928    }   else
3929	return MGAModeInit(xf86Screens[scrnIndex], mode);
3930}
3931
3932 /* Adjusts coordinates to match Panning granularity.
3933  * does nothing if the HALlib is not loaded
3934  */
3935void
3936MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y)
3937{
3938#ifdef USEMGAHAL
3939    MGA_HAL(
3940	MGAPtr pMga = MGAPTR(pScrn);
3941	MGAPtr pMga2;
3942	int xg = 1;
3943	int yg = 1;
3944	if(pMga->pMgaModeInfo && pMga->pMgaModeInfo->ulPanXGran && pMga->pMgaModeInfo->ulPanYGran) {
3945	    xg = pMga->pMgaModeInfo->ulPanXGran;
3946	    yg = pMga->pMgaModeInfo->ulPanYGran;
3947	}
3948	if(pMga->pScrn2 && (pMga2 = MGAPTR(pMga->pScrn2)) ) {
3949
3950	    if(pMga2->pMgaModeInfo && pMga2->pMgaModeInfo->ulPanXGran && pMga2->pMgaModeInfo->ulPanYGran) {
3951		xg = max(xg,pMga2->pMgaModeInfo->ulPanXGran);
3952		yg = max(yg,pMga2->pMgaModeInfo->ulPanYGran);
3953	    }
3954	}
3955	xg=16; /*ncoder: temporary */
3956	*x -= *x % xg;
3957	*y -= *y % yg;
3958	);
3959#endif
3960}
3961
3962
3963/*
3964 * This function is used to initialize the Start Address - the first
3965 * displayed location in the video memory.
3966 */
3967/* Usually mandatory */
3968void
3969MGAAdjustFrame(int scrnIndex, int x, int y, int flags)
3970{
3971    ScrnInfoPtr pScrn;
3972    int Base, tmp, count;
3973
3974    MGAFBLayout *pLayout;
3975    MGAPtr pMga;
3976
3977
3978    pScrn = xf86Screens[scrnIndex];
3979    pMga = MGAPTR(pScrn);
3980    pLayout = &pMga->CurrentLayout;
3981
3982        /* wanted to improve panning granularity problems without risking
3983         * compatibility issues. Existing code looked hardware dependent.
3984         */
3985#ifdef USEMGAHAL
3986    MGA_HAL(
3987	    pMga->HALGranularityOffX = x;
3988	    pMga->HALGranularityOffY = y;
3989        MGAAdjustGranularity(pScrn,&x,&y);
3990	    pMga->HALGranularityOffX = pMga->HALGranularityOffX - x;
3991	    pMga->HALGranularityOffY = pMga->HALGranularityOffY - y;
3992        HALSetDisplayStart(pMga->pBoard,x,y,0);
3993    );
3994#endif
3995    MGA_NOT_HAL(
3996        if(pMga->ShowCache && y && pScrn->vtSema)
3997            y += pScrn->virtualY - 1;
3998
3999        Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >>
4000                    (3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]);
4001
4002        if (pLayout->bitsPerPixel == 24) {
4003            if (pMga->Chipset == PCI_CHIP_MGAG400
4004                || pMga->Chipset == PCI_CHIP_MGAG550)
4005                Base &= ~1;  /*1 Not sure why */
4006
4007            Base *= 3;
4008        }
4009
4010        /* find start of retrace */
4011        while (INREG8(0x1FDA) & 0x08);
4012        while (!(INREG8(0x1FDA) & 0x08));
4013        /* wait until we're past the start (fixseg.c in the DDK) */
4014        count = INREG(MGAREG_VCOUNT) + 2;
4015        while(INREG(MGAREG_VCOUNT) < count);
4016
4017        OUTREG16(MGAREG_CRTC_INDEX, (Base & 0x00FF00) | 0x0C);
4018        OUTREG16(MGAREG_CRTC_INDEX, ((Base & 0x0000FF) << 8) | 0x0D);
4019        OUTREG8(MGAREG_CRTCEXT_INDEX, 0x00);
4020        tmp = INREG8(MGAREG_CRTCEXT_DATA);
4021        OUTREG8(MGAREG_CRTCEXT_DATA, (tmp & 0xF0) | ((Base & 0x0F0000) >> 16));
4022    );
4023
4024}
4025
4026void
4027MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags)
4028{
4029    ScrnInfoPtr pScrn;
4030    int Base;
4031    MGAFBLayout *pLayout;
4032    MGAPtr pMga;
4033
4034    pScrn = xf86Screens[scrnIndex];
4035    pMga = MGAPTR(pScrn);
4036    pLayout = &pMga->CurrentLayout;
4037#ifdef USEMGAHAL
4038    MGA_HAL(
4039        MGAAdjustGranularity(pScrn,&x,&y);
4040        HALSetDisplayStart(pMga->pBoard,x,y,1);
4041    );
4042#endif
4043    MGA_NOT_HAL(
4044        if(pMga->ShowCache && y && pScrn->vtSema)
4045            y += pScrn->virtualY - 1;
4046
4047        /* 3-85 c2offset
4048            * 3-93 c2startadd0
4049            * 3-96 c2vcount
4050            */
4051
4052        Base = (y * pLayout->displayWidth + x) * pLayout->bitsPerPixel >> 3;
4053        Base += pMga->DstOrg;
4054        Base &= 0x01ffffc0;
4055        OUTREG(MGAREG_C2STARTADD0, Base);
4056    );
4057}
4058
4059/*
4060 * This is called when VT switching back to the X server.  Its job is
4061 * to reinitialise the video mode.
4062 *
4063 * We may wish to unmap video/MMIO memory too.
4064 */
4065
4066/* Mandatory */
4067static Bool
4068MGAEnterVT(int scrnIndex, int flags)
4069{
4070    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4071    MGAPtr pMga;
4072
4073    pMga = MGAPTR(pScrn);
4074
4075#ifdef XF86DRI
4076    if (pMga->directRenderingEnabled) {
4077	if (pMga->irq) {
4078	    /* Need to make sure interrupts are enabled */
4079	    OUTREG(MGAREG_IEN, pMga->reg_ien);
4080	}
4081        DRIUnlock(screenInfo.screens[scrnIndex]);
4082    }
4083#endif
4084
4085    if (!MGAModeInit(pScrn, pScrn->currentMode))
4086	return FALSE;
4087    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
4088
4089    /* For the second head, work around display problem. */
4090   if (pMga->SecondCrtc) {
4091	MGACrtc2FillStrip(pScrn);
4092    }
4093
4094    return TRUE;
4095}
4096
4097static Bool
4098MGAEnterVTFBDev(int scrnIndex, int flags)
4099{
4100    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4101#ifdef XF86DRI
4102    ScreenPtr pScreen;
4103    MGAPtr pMga;
4104
4105    pMga = MGAPTR(pScrn);
4106    if (pMga->directRenderingEnabled) {
4107        pScreen = screenInfo.screens[scrnIndex];
4108        DRIUnlock(pScreen);
4109    }
4110#endif
4111
4112    fbdevHWEnterVT(scrnIndex,flags);
4113    MGAStormEngineInit(pScrn);
4114    return TRUE;
4115}
4116
4117#define RESTORE_TEXTMODE_ON_DVI(x)                      \
4118    if (MGAISGx50(x) &&                                 \
4119       (ISDIGITAL1(x) || ISDIGITAL2(x))) {              \
4120        /* Reset DUALDVI register */                    \
4121        outMGAdac(MGA1064_DVI_PIPE_CTL, 0x0);           \
4122        /* Set Panel mode between 20 and 54 MHz */      \
4123        outMGAdac(MGA1064_PAN_CTL, 0x7);                \
4124    }
4125
4126
4127/*
4128 * This is called when VT switching away from the X server.  Its job is
4129 * to restore the previous (text) mode.
4130 *
4131 * We may wish to remap video/MMIO memory too.
4132 */
4133
4134/* Mandatory */
4135static void
4136MGALeaveVT(int scrnIndex, int flags)
4137{
4138    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4139    vgaHWPtr hwp = VGAHWPTR(pScrn);
4140#ifdef XF86DRI
4141    MGAPtr pMga = MGAPTR(pScrn);
4142    ScreenPtr pScreen;
4143#endif
4144
4145    MGARestore(pScrn);
4146    vgaHWLock(hwp);
4147
4148    if (xf86IsPc98())
4149	outb(0xfac, 0x00);
4150#ifdef XF86DRI
4151    if (pMga->directRenderingEnabled) {
4152        pScreen = screenInfo.screens[scrnIndex];
4153        DRILock(pScreen, 0);
4154    }
4155#endif
4156#ifdef USEMGAHAL
4157    MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); );
4158#endif
4159}
4160
4161
4162/*
4163 * This is called at the end of each server generation.  It restores the
4164 * original (text) mode.  It should also unmap the video memory, and free
4165 * any per-generation data allocated by the driver.  It should finish
4166 * by unwrapping and calling the saved CloseScreen function.
4167 */
4168
4169/* Mandatory */
4170static Bool
4171MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
4172{
4173    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4174    vgaHWPtr hwp = VGAHWPTR(pScrn);
4175    MGAPtr pMga = MGAPTR(pScrn);
4176    MGAEntPtr pMgaEnt = NULL;
4177
4178#ifdef USEMGAHAL
4179    MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); );
4180#endif
4181    if (pMga->MergedFB)
4182         MGACloseScreenMerged(scrnIndex, pScreen);
4183
4184    if (pScrn->vtSema) {
4185	if (pMga->FBDev) {
4186	    fbdevHWRestore(pScrn);
4187	    MGAUnmapMem(pScrn);
4188        } else {
4189	    MGARestore(pScrn);
4190	    vgaHWLock(hwp);
4191	    MGAUnmapMem(pScrn);
4192	    vgaHWUnmapMem(pScrn);
4193	}
4194    }
4195#ifdef XF86DRI
4196   if (pMga->directRenderingEnabled) {
4197       MGADRICloseScreen(pScreen);
4198       pMga->directRenderingEnabled=FALSE;
4199   }
4200#endif
4201
4202   if (pMga->DualHeadEnabled) {
4203       DevUnion *pPriv;
4204       pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
4205       pMgaEnt = pPriv->ptr;
4206       pMgaEnt->refCount--;
4207   }
4208
4209#ifdef USEMGAHAL
4210   MGA_HAL(
4211   if(pMga->DualHeadEnabled) {
4212      if(pMgaEnt->refCount == 0) {
4213	 /* Both boards have closed there screen */
4214	 MGACloseLibrary(pMga->pBoard);
4215
4216	 if (pMga->pBoard)
4217	   xfree(pMga->pBoard);
4218	 if (pMga->pClientStruct)
4219	   xfree(pMga->pClientStruct);
4220	 if (pMga->pMgaModeInfo)
4221	   xfree(pMga->pMgaModeInfo);
4222	 if (pMga->pMgaHwInfo)
4223	   xfree(pMga->pMgaHwInfo);
4224      }
4225   } else {
4226      MGACloseLibrary(pMga->pBoard);
4227
4228      if (pMga->pBoard)
4229	xfree(pMga->pBoard);
4230      if (pMga->pClientStruct)
4231	xfree(pMga->pClientStruct);
4232      if (pMga->pMgaModeInfo)
4233	xfree(pMga->pMgaModeInfo);
4234      if (pMga->pMgaHwInfo)
4235	xfree(pMga->pMgaHwInfo);
4236   }
4237   );	/* MGA_HAL */
4238#endif
4239
4240#ifdef USE_XAA
4241    if (pMga->AccelInfoRec)
4242	XAADestroyInfoRec(pMga->AccelInfoRec);
4243#endif
4244#ifdef USE_EXA
4245    if (pMga->ExaDriver) {
4246	exaDriverFini(pScreen);
4247	xfree(pMga->ExaDriver);
4248    }
4249#endif
4250    if (pMga->CursorInfoRec)
4251    	xf86DestroyCursorInfoRec(pMga->CursorInfoRec);
4252    if (pMga->ShadowPtr)
4253	xfree(pMga->ShadowPtr);
4254    if (pMga->DGAModes)
4255	xfree(pMga->DGAModes);
4256    if (pMga->adaptor)
4257	xfree(pMga->adaptor);
4258    if (pMga->portPrivate)
4259	xfree(pMga->portPrivate);
4260    if (pMga->ScratchBuffer)
4261	xfree(pMga->ScratchBuffer);
4262
4263    pScrn->vtSema = FALSE;
4264
4265    if (xf86IsPc98())
4266	outb(0xfac, 0x00);
4267
4268    xf86ClearPrimInitDone(pScrn->entityList[0]);
4269
4270    if(pMga->BlockHandler)
4271	pScreen->BlockHandler = pMga->BlockHandler;
4272
4273    pScreen->CloseScreen = pMga->CloseScreen;
4274
4275    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
4276}
4277
4278
4279/* Free up any persistent data structures */
4280
4281/* Optional */
4282static void
4283MGAFreeScreen(int scrnIndex, int flags)
4284{
4285
4286    /*
4287     * This only gets called when a screen is being deleted.  It does not
4288     * get called routinely at the end of a server generation.
4289     */
4290    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
4291	vgaHWFreeHWRec(xf86Screens[scrnIndex]);
4292    MGAFreeRec(xf86Screens[scrnIndex]);
4293
4294}
4295
4296#ifndef HAVE_XF86MODEBANDWIDTH
4297
4298#define MODE_BANDWIDTH MODE_BAD
4299
4300/** Calculates the memory bandwidth (in MiB/sec) of a mode. */
4301static unsigned int
4302xf86ModeBandwidth(DisplayModePtr mode, int depth)
4303{
4304    float a_active, a_total, active_percent, pixels_per_second;
4305    int bytes_per_pixel = (depth + 7) / 8;
4306
4307    if (!mode->HTotal || !mode->VTotal || !mode->Clock)
4308	return 0;
4309
4310    a_active = mode->HDisplay * mode->VDisplay;
4311    a_total = mode->HTotal * mode->VTotal;
4312    active_percent = a_active / a_total;
4313    pixels_per_second = active_percent * mode->Clock * 1000.0;
4314
4315    return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024));
4316}
4317#endif
4318
4319/* Checks if a mode is suitable for the selected chipset. */
4320
4321/* Optional */
4322static ModeStatus
4323MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
4324{
4325    int lace;
4326    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4327    MGAPtr pMga = MGAPTR(pScrn);
4328
4329    if (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) {
4330	if (mode->HDisplay > 1600)
4331	    return MODE_VIRTUAL_X;
4332	if (mode->VDisplay > 1200)
4333	    return MODE_VIRTUAL_Y;
4334	if (pMga->reg_1e24 == 0x01 &&
4335	    xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 256)
4336	    return MODE_BANDWIDTH;
4337    } else if (pMga->is_G200WB){
4338        if (mode->Flags & V_DBLSCAN)
4339            return MODE_NO_DBLESCAN;
4340	if (pMga->KVM && mode->HDisplay > 1280)
4341	    return MODE_VIRTUAL_X;
4342	if (pMga->KVM && mode->VDisplay > 1024)
4343	    return MODE_VIRTUAL_Y;
4344	if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 318.77)
4345	    return MODE_BANDWIDTH;
4346    } else if (pMga->is_G200EV
4347	       && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 327)) {
4348        return MODE_BANDWIDTH;
4349    } else if (pMga->is_G200EH
4350               && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 375)) {
4351        return MODE_BANDWIDTH;
4352    }
4353
4354    lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
4355
4356    if ((mode->CrtcHDisplay <= 2048) &&
4357	(mode->CrtcHSyncStart <= 4096) &&
4358	(mode->CrtcHSyncEnd <= 4096) &&
4359	(mode->CrtcHTotal <= 4096) &&
4360	(mode->CrtcVDisplay <= 2048 * lace) &&
4361	(mode->CrtcVSyncStart <= 4096 * lace) &&
4362	(mode->CrtcVSyncEnd <= 4096 * lace) &&
4363	(mode->CrtcVTotal <= 4096 * lace)) {
4364
4365	/* Can't have horizontal panning for second head of G400 */
4366	if (pMga->SecondCrtc) {
4367	    if (flags == MODECHECK_FINAL) {
4368		if (pMga->allowedWidth == 0)
4369		    pMga->allowedWidth = pScrn->virtualX;
4370		if (mode->HDisplay != pMga->allowedWidth)
4371		    return(MODE_ONE_WIDTH);
4372	    }
4373	}
4374
4375	return(MODE_OK);
4376    } else {
4377	return(MODE_BAD);
4378    }
4379}
4380
4381
4382/*
4383 * This routine is required but since we can't easily blank the
4384 * second display without risking powering off the monitor, return
4385 * FALSE and let the X server do something generic.
4386 */
4387static Bool
4388MGASaveScreenCrtc2(ScreenPtr pScreen, int mode)
4389{
4390    return FALSE;
4391}
4392
4393/* Do screen blanking */
4394
4395static Bool
4396MGASaveScreen(ScreenPtr pScreen, int mode)
4397{
4398    return vgaHWSaveScreen(pScreen, mode);
4399}
4400
4401
4402/*
4403 * MGADisplayPowerManagementSet --
4404 *
4405 * Sets VESA Display Power Management Signaling (DPMS) Mode.
4406 *
4407 * XXX This needs fixing for sync-on-green!
4408 */
4409void
4410MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
4411			     int flags)
4412{
4413	MGAPtr pMga = MGAPTR(pScrn);
4414	unsigned char seq1 = 0, crtcext1 = 0;
4415
4416	switch (PowerManagementMode)
4417	{
4418	case DPMSModeOn:
4419	    /* Screen: On; HSync: On, VSync: On */
4420	    seq1 = 0x00;
4421	    crtcext1 = 0x00;
4422	    break;
4423	case DPMSModeStandby:
4424	    /* Screen: Off; HSync: Off, VSync: On */
4425	    seq1 = 0x20;
4426	    crtcext1 = 0x10;
4427	    break;
4428	case DPMSModeSuspend:
4429	    /* Screen: Off; HSync: On, VSync: Off */
4430	    seq1 = 0x20;
4431	    crtcext1 = 0x20;
4432	    break;
4433	case DPMSModeOff:
4434	    /* Screen: Off; HSync: Off, VSync: Off */
4435	    seq1 = 0x20;
4436	    crtcext1 = 0x30;
4437	    break;
4438	}
4439
4440	/* XXX Prefer an implementation that doesn't depend on VGA specifics */
4441	OUTREG8(MGAREG_SEQ_INDEX, 0x01);	/* Select SEQ1 */
4442	seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20;
4443	MGAWAITVSYNC();
4444	MGAWAITBUSY();
4445	OUTREG8(MGAREG_SEQ_DATA, seq1);
4446	usleep(20000);
4447	OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01);	/* Select CRTCEXT1 */
4448	crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
4449	OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1);
4450}
4451
4452
4453void
4454MGADisplayPowerManagementSetCrtc2(ScrnInfoPtr pScrn, int PowerManagementMode,
4455				  int flags)
4456{
4457	MGAPtr pMga = MGAPTR(pScrn);
4458	CARD32 val = INREG(MGAREG_C2CTL);
4459
4460	if (PowerManagementMode==DPMSModeOn) {
4461		/* Enable CRTC2 */
4462		val |= MGAREG_C2CTL_C2_EN;
4463		val &= ~MGAREG_C2CTL_PIXCLKDIS_DISABLE;
4464		OUTREG(MGAREG_C2CTL, val);
4465		/* Restore normal MAVEN values */
4466		if (pMga->Maven) {
4467			/* if TV MODE -- for later implementation
4468				MAVW(MONEN, 0xb3);
4469				MAVW(MONSET, 0x20);
4470				MAVW(OUTMODE, 0x08);    output: SVideo/Composite
4471			        MAVW(STABLE, 0x02);             makes picture stable?
4472				fixme? linux uses 0x14...
4473				MAVW(TEST, (MAVR(TEST) & 0x10));
4474
4475			 */
4476			/* else monitor mode */
4477
4478			xf86I2CWriteByte(pMga->Maven, MGAMAV_MONEN, 0xb2);
4479			/* must be set to this in monitor mode */
4480			xf86I2CWriteByte(pMga->Maven, MGAMAV_MONSET, 0x20);
4481			/* output: monitor mode */
4482			xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x03);
4483			/* makes picture stable? */
4484			xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x22);
4485			/* turn off test signal */
4486			xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x00);
4487		}
4488	}
4489	else {
4490		/* Disable CRTC2 video */
4491		val |= MGAREG_C2CTL_PIXCLKDIS_DISABLE;
4492		val &= ~MGAREG_C2CTL_C2_EN;
4493		OUTREG(MGAREG_C2CTL, val);
4494
4495		/* Disable MAVEN display */
4496		if (pMga->Maven) {
4497		/* In order to blank the 2nd display, we must set some MAVEN registers.
4498		 * It seems that not always the same values work on different hardware so
4499		 * we try a few different (possibly redundant) ones. */
4500			/* xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x6a); */
4501			/* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x03); */
4502			/* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x10); */
4503			xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x80);
4504		}
4505
4506	}
4507}
4508
4509
4510static void
4511MGABlockHandler (
4512    int i,
4513    pointer     blockData,
4514    pointer     pTimeout,
4515    pointer     pReadmask
4516){
4517    ScreenPtr      pScreen = screenInfo.screens[i];
4518    ScrnInfoPtr    pScrn = xf86Screens[i];
4519    MGAPtr         pMga = MGAPTR(pScrn);
4520
4521    if(pMga->PaletteLoadCallback)
4522	(*pMga->PaletteLoadCallback)(pScrn);
4523
4524    pScreen->BlockHandler = pMga->BlockHandler;
4525    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
4526    pScreen->BlockHandler = MGABlockHandler;
4527
4528    if(pMga->VideoTimerCallback) {
4529	UpdateCurrentTime();
4530	(*pMga->VideoTimerCallback)(pScrn, currentTime.milliseconds);
4531    }
4532
4533    if(pMga->RenderCallback)
4534	(*pMga->RenderCallback)(pScrn);
4535}
4536
4537#if defined (EXTRADEBUG)
4538/*
4539 * some functions to track input/output in the server
4540 */
4541
4542CARD8
4543MGAdbg_inreg8(ScrnInfoPtr pScrn,int addr,int verbose, char* func)
4544{
4545    CARD8 ret;
4546
4547    ret = MMIO_IN8(MGAPTR(pScrn)->IOBase,addr);
4548    if(verbose)
4549	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4550			"inreg8 : %s: 0x%8x = 0x%x\n",func, addr,ret);
4551    return ret;
4552}
4553
4554CARD16
4555MGAdbg_inreg16(ScrnInfoPtr pScrn,int addr,int verbose, char* func)
4556{
4557    CARD16 ret;
4558
4559    ret = MMIO_IN16(MGAPTR(pScrn)->IOBase,addr);
4560    if(verbose)
4561	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4562			"inreg16: %s: 0x%8x = 0x%x\n",func, addr,ret);
4563    return ret;
4564}
4565
4566CARD32
4567MGAdbg_inreg32(ScrnInfoPtr pScrn,int addr,int verbose, char* func)
4568{
4569    CARD32 ret;
4570
4571    ret = MMIO_IN32(MGAPTR(pScrn)->IOBase,addr);
4572    if(verbose)
4573	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4574			"inreg32: %s: 0x%8x = 0x%x\n",func, addr,ret);
4575    return ret;
4576}
4577
4578void
4579MGAdbg_outreg8(ScrnInfoPtr pScrn,int addr,int val, char* func)
4580{
4581    CARD8 ret;
4582
4583#if 0
4584    if( addr = MGAREG_CRTCEXT_DATA )
4585    	return;
4586#endif
4587    if( addr != 0x3c00 ) {
4588	ret = MGAdbg_inreg8(pScrn,addr,0,func);
4589	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4590			"outreg8 : %s: 0x%8x = 0x%x was 0x%x\n",
4591			func,addr,val,ret);
4592    }
4593    else {
4594	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg8 : %s: index 0x%x\n",
4595	func,val);
4596    }
4597    MMIO_OUT8(MGAPTR(pScrn)->IOBase,addr,val);
4598}
4599
4600void
4601MGAdbg_outreg16(ScrnInfoPtr pScrn,int addr,int val, char* func)
4602{
4603    CARD16 ret;
4604
4605#if 0
4606    if (addr == MGAREG_CRTCEXT_INDEX)
4607    	return;
4608#endif
4609    ret = MGAdbg_inreg16(pScrn,addr,0, func);
4610    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4611			"outreg16: %s: 0x%8x = 0x%x was 0x%x\n",
4612			func,addr,val,ret);
4613    MMIO_OUT16(MGAPTR(pScrn)->IOBase,addr,val);
4614}
4615
4616void
4617MGAdbg_outreg32(ScrnInfoPtr pScrn,int addr,int val, char* func)
4618{
4619    CARD32 ret;
4620
4621    if (((addr & 0xff00) == 0x1c00)
4622    	&& (addr != 0x1c04)
4623/*    	&& (addr != 0x1c1c) */
4624    	&& (addr != 0x1c20)
4625    	&& (addr != 0x1c24)
4626    	&& (addr != 0x1c80)
4627    	&& (addr != 0x1c8c)
4628    	&& (addr != 0x1c94)
4629    	&& (addr != 0x1c98)
4630    	&& (addr != 0x1c9c)
4631	 ) {
4632	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: refused address 0x%x\n",
4633			func,addr);
4634    	return;
4635    }
4636    ret = MGAdbg_inreg32(pScrn,addr,0, func);
4637    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4638			"outreg32: %s: 0x%8x = 0x%x was 0x%x\n",
4639			func,addr,val,ret);
4640    MMIO_OUT32(MGAPTR(pScrn)->IOBase,addr,val);
4641}
4642#endif /* DEBUG */
4643
4644static void
4645MGAG100BlackMagic(ScrnInfoPtr pScrn)
4646{
4647    MGAPtr pMga = MGAPTR(pScrn);
4648
4649    OUTREG(MGAREG_PLNWT, ~(CARD32)0x0);
4650    /* reset memory */
4651    OUTREG(MGAREG_MACCESS, 1<<15);
4652    usleep(10);
4653}
4654
4655