mga_driver.c revision d7be9c72
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 = 1280;
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    if (i < 1 && pMga->FBDev) {
2466	fbdevHWUseBuildinMode(pScrn);
2467	pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
2468	i = 1;
2469    }
2470    if (i == -1) {
2471	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Validate Modes Failed\n");
2472	MGAFreeRec(pScrn);
2473	return FALSE;
2474    }
2475
2476    /* Prune the modes marked as invalid */
2477    xf86PruneDriverModes(pScrn);
2478
2479    if (i == 0 || pScrn->modes == NULL) {
2480	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
2481	MGAFreeRec(pScrn);
2482	return FALSE;
2483    }
2484#ifdef USEMGAHAL
2485    MGA_HAL(
2486
2487    if(pMga->SecondCrtc == FALSE) {
2488
2489        pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());
2490        pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));
2491        pMga->pClientStruct->pMga = (MGAPtr) pMga;
2492
2493        MGAMapMem(pScrn);
2494	/*
2495	 * For some reason the MGAOPM_DMA_BLIT bit needs to be set
2496	 * on G200 before opening the HALlib. I don't know why.
2497	 * MATROX: hint, hint.
2498	 */
2499	/*if (pMga->Chipset == PCI_CHIP_MGAG200 ||
2500	  pMga->Chipset == PCI_CHIP_MGAG200_PCI) */{
2501	    CARD32 opmode;
2502	    opmode = INREG(MGAREG_OPMODE);
2503	    OUTREG(MGAREG_OPMODE,  MGAOPM_DMA_BLIT | opmode);
2504	}
2505	/* wrapping OpenLibrary to fix broken registers. MATROX: hint, hint. */
2506	MiscCtlReg = inMGAdac(MGA1064_MISC_CTL);
2507        MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
2508	outMGAdac(MGA1064_MISC_CTL,MiscCtlReg);
2509        MGAUnmapMem(pScrn);
2510        pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO));
2511        MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
2512
2513        /* copy the board handles */
2514        if (pMga->DualHeadEnabled) {
2515            pMgaEnt->pClientStruct = pMga->pClientStruct;
2516            pMgaEnt->pBoard = pMga->pBoard;
2517            pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo;
2518        }
2519
2520    } else { /* Second CRTC && entity is shared */
2521        pMga->pBoard = pMgaEnt->pBoard;
2522        pMga->pClientStruct = pMgaEnt->pClientStruct;
2523        pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo;
2524
2525    }
2526
2527    MGAFillModeInfoStruct(pScrn,NULL);
2528    /* Fields usually handled by MGAFillModeInfoStruct, but are unavailable
2529     * because no mode is given
2530     */
2531    pMga->pMgaModeInfo->ulDispWidth = pScrn->virtualX;
2532    pMga->pMgaModeInfo->ulDispHeight = pScrn->virtualY;
2533
2534
2535    if (ISDIGITAL1(pMga))
2536        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2537                    "Digital screen detected on first head.\n");
2538    if (ISTV1(pMga))
2539        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2540                    "TV detected on first head.\n");
2541    if (ISDIGITAL2(pMga))
2542        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2543                    "Digital screen detected on second head.\n");
2544    if (ISTV2(pMga))
2545        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2546                    "TV detected on second head.\n");
2547
2548
2549    if((status = MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo)) != 0) {
2550	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2551		   "MGAValidateMode from HALlib found the mode to be invalid.\n"
2552		   "\tError: 0x%lx\n", status);
2553        return FALSE;
2554    }
2555    pScrn->displayWidth = pMga->pMgaModeInfo->ulFBPitch;
2556    );	/* MGA_HAL */
2557#endif
2558
2559    /* If the Device section explicitly set HasSDRAM, don't bother checking.
2560     */
2561    if (!pMga->HasSDRAM) {
2562	if ((pMga->softbooted || pMga->Primary)
2563	     && pMga->chip_attribs->probe_for_sdram) {
2564	    uint32_t option_reg;
2565
2566#ifdef XSERVER_LIBPCIACCESS
2567	    pci_device_cfg_read_u32(pMga->PciInfo, & option_reg,
2568				    PCI_OPTION_REG);
2569#else
2570	    option_reg = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
2571#endif
2572	    pMga->HasSDRAM = ((option_reg & (1 << 14)) == 0);
2573	}
2574	else {
2575	    pMga->HasSDRAM = pMga->chip_attribs->has_sdram;
2576	}
2577
2578	if (pMga->HasSDRAM) {
2579	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n");
2580	}
2581    }
2582
2583    /*
2584     * Set the CRTC parameters for all of the modes based on the type
2585     * of mode, and the chipset's interlace requirements.
2586     *
2587     * Calling this is required if the mode->Crtc* values are used by the
2588     * driver and if the driver doesn't provide code to set them.  They
2589     * are not pre-initialised at all.
2590     */
2591#ifdef USEMGAHAL
2592    MGA_HAL(xf86SetCrtcForModes(pScrn, 0));
2593#endif
2594    MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V));
2595
2596    /* Set the current mode to the first in the list */
2597    pScrn->currentMode = pScrn->modes;
2598
2599    /* Print the list of modes being used */
2600    xf86PrintModes(pScrn);
2601
2602    /* Set display resolution */
2603    xf86SetDpi(pScrn, 0, 0);
2604
2605    /*
2606     * Compute the byte offset into the linear frame buffer where the
2607     * frame buffer data should actually begin.  According to DDK misc.c
2608     * line 1023, if more than 4MB is to be displayed, YDSTORG must be set
2609     * appropriately to align memory bank switching, and this requires a
2610     * corresponding offset on linear frame buffer access.
2611     * This is only needed for WRAM.
2612     */
2613
2614    pMga->YDstOrg = 0;
2615    if (pMga->chip_attribs->fb_4mb_quirk &&
2616	(pScrn->virtualX * pScrn->virtualY * bytesPerPixel > 4*1024*1024)) {
2617	int offset;
2618	int offset_modulo = (pScrn->bitsPerPixel == 24) ? 12 : 4;
2619	int ydstorg_modulo = 64;
2620
2621
2622	if (pMga->Interleave) {
2623	    offset_modulo <<= 1;
2624	    ydstorg_modulo <<= 1;
2625	}
2626
2627	offset = (4*1024*1024) % (pScrn->displayWidth * bytesPerPixel);
2628	pMga->YDstOrg = offset / bytesPerPixel;
2629
2630	/*
2631	 * When this was unconditional, it caused a line of horizontal garbage
2632	 * at the middle right of the screen at the 4Meg boundary in 32bpp
2633	 * (and presumably any other modes that use more than 4M). But it's
2634	 * essential for 24bpp (it may not matter either way for 8bpp & 16bpp,
2635	 * I'm not sure; I didn't notice problems when I checked with and
2636	 * without.)
2637	 * DRM Doug Merritt 12/97, submitted to XFree86 6/98 (oops)
2638	 */
2639	if (bytesPerPixel < 4) {
2640	    while ((offset % offset_modulo) != 0 ||
2641		   (pMga->YDstOrg % ydstorg_modulo) != 0) {
2642		offset++;
2643		pMga->YDstOrg = offset / bytesPerPixel;
2644	    }
2645	}
2646    }
2647
2648    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n",
2649		   pMga->YDstOrg);
2650    if(pMga->DualHeadEnabled) {
2651        if(pMga->SecondCrtc == FALSE) {
2652	    pMga->FbUsableSize = pMgaEnt->masterFbMapSize;
2653            /* Allocate HW cursor buffer at the end of video ram */
2654	    if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
2655	        if( pScrn->virtualY * pScrn->displayWidth *
2656		    pScrn->bitsPerPixel / 8 <=
2657		    pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
2658		    pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
2659		    pMga->FbCursorOffset =
2660		      pMgaEnt->masterFbMapSize -
2661		      pMga->Dac.CursorOffscreenMemSize;
2662		} else {
2663		    pMga->HWCursor = FALSE;
2664		    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2665			       "Too little offscreen memory for HW cursor; "
2666			       "using SW cursor\n");
2667		}
2668	    }
2669	} else { /* Second CRTC */
2670	    pMga->FbUsableSize = pMgaEnt->slaveFbMapSize;
2671	    pMga->HWCursor = FALSE;
2672	}
2673    } else {
2674        pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel;
2675           /* Allocate HW cursor buffer at the end of video ram */
2676        if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
2677	    if( pScrn->virtualY * pScrn->displayWidth *
2678	        pScrn->bitsPerPixel / 8 <=
2679        	pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
2680	        pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
2681	        pMga->FbCursorOffset =
2682		  pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize;
2683	    } else {
2684	        pMga->HWCursor = FALSE;
2685	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2686			   "Too little offscreen memory for HW cursor; "
2687			   "using SW cursor\n");
2688	    }
2689	}
2690    }
2691    /*
2692     * XXX This should be taken into account in some way in the mode valdation
2693     * section.
2694     */
2695
2696
2697    /* Load the required framebuffer */
2698    if (!xf86LoadSubModule(pScrn, "fb")) {
2699	MGAFreeRec(pScrn);
2700	return FALSE;
2701    }
2702
2703    /* Load XAA if needed */
2704    if (!pMga->NoAccel) {
2705#ifdef USE_EXA
2706	if (pMga->Exa) {
2707	    if (!xf86LoadSubModule(pScrn, "exa")) {
2708		MGAFreeRec(pScrn);
2709		return FALSE;
2710	    }
2711	} else {
2712#endif
2713#ifdef USE_XAA
2714	    if (!xf86LoadSubModule(pScrn, "xaa")) {
2715		MGAFreeRec(pScrn);
2716		return FALSE;
2717	    }
2718#endif
2719#ifdef USE_EXA
2720	}
2721#endif
2722    }
2723
2724    /* Load ramdac if needed */
2725    if (pMga->HWCursor) {
2726	if (!xf86LoadSubModule(pScrn, "ramdac")) {
2727	    MGAFreeRec(pScrn);
2728	    return FALSE;
2729	}
2730    }
2731
2732    /* Load shadowfb if needed */
2733    if (pMga->ShadowFB) {
2734	if (!xf86LoadSubModule(pScrn, "shadowfb")) {
2735	    MGAFreeRec(pScrn);
2736	    return FALSE;
2737	}
2738    }
2739
2740#ifdef XF86DRI
2741    /* Load the dri module if requested. */
2742    if (xf86ReturnOptValBool(pMga->Options, OPTION_DRI, FALSE)) {
2743       xf86LoadSubModule(pScrn, "dri");
2744    }
2745#endif
2746    pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
2747    pMga->CurrentLayout.depth = pScrn->depth;
2748    pMga->CurrentLayout.displayWidth = pScrn->displayWidth;
2749    pMga->CurrentLayout.weight.red = pScrn->weight.red;
2750    pMga->CurrentLayout.weight.green = pScrn->weight.green;
2751    pMga->CurrentLayout.weight.blue = pScrn->weight.blue;
2752    pMga->CurrentLayout.mode = pScrn->currentMode;
2753
2754
2755
2756    if(pMga->MergedFB) {
2757        MGAPreInitMergedFB(pScrn,flags);
2758    };
2759
2760
2761#ifdef USEMGAHAL
2762    MGA_HAL(
2763    /* Close the library after preinit */
2764    /* This needs to only happen after this board has completed preinit
2765     * both times
2766     */
2767
2768      if(pMga->DualHeadEnabled) {
2769	  /* Entity is shared make sure refcount == 2 */
2770	  /* If ref count is 2 then reset it to 0 */
2771	  if(pMgaEnt->refCount == 2) {
2772	      /* Both boards have done there initialization */
2773	      MGACloseLibrary(pMga->pBoard);
2774
2775	      if (pMga->pBoard)
2776	        xfree(pMga->pBoard);
2777	      if (pMga->pClientStruct)
2778	        xfree(pMga->pClientStruct);
2779	      if (pMga->pMgaModeInfo)
2780	        xfree(pMga->pMgaModeInfo);
2781	      if (pMga->pMgaHwInfo)
2782	        xfree(pMga->pMgaHwInfo);
2783	      pMgaEnt->refCount = 0;
2784	  }
2785      } else {
2786	  MGACloseLibrary(pMga->pBoard);
2787
2788	  if (pMga->pBoard)
2789	    xfree(pMga->pBoard);
2790	  if (pMga->pClientStruct)
2791	    xfree(pMga->pClientStruct);
2792	  if (pMga->pMgaModeInfo)
2793	    xfree(pMga->pMgaModeInfo);
2794	  if (pMga->pMgaHwInfo)
2795	    xfree(pMga->pMgaHwInfo);
2796      }
2797
2798    );	/* MGA_HAL */
2799#endif
2800
2801    xf86SetPrimInitDone(pScrn->entityList[0]);
2802
2803    return TRUE;
2804}
2805
2806
2807/*
2808 * Map the framebuffer and MMIO memory.
2809 */
2810
2811static Bool
2812MGAMapMem(ScrnInfoPtr pScrn)
2813{
2814    MGAPtr pMga = MGAPTR(pScrn);
2815#ifdef XSERVER_LIBPCIACCESS
2816    struct pci_device *const dev = pMga->PciInfo;
2817    struct pci_mem_region *region;
2818    void **memory[2];
2819    int i, err;
2820#endif
2821
2822
2823    if (!pMga->FBDev) {
2824#ifdef XSERVER_LIBPCIACCESS
2825        memory[pMga->io_bar] = &pMga->IOBase;
2826        memory[pMga->framebuffer_bar] = &pMga->FbBase;
2827
2828        for (i = 0; i < 2; i++) {
2829            region = &dev->regions[i];
2830            err = pci_device_map_range(dev,
2831                                       region->base_addr, region->size,
2832                                       PCI_DEV_MAP_FLAG_WRITABLE,
2833                                       memory[i]);
2834
2835            if (err) {
2836                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2837                           "Unable to map BAR %i.  %s (%d)\n",
2838                           i, strerror(err), err);
2839                return FALSE;
2840            }
2841        }
2842#else
2843	/*
2844	 * For Alpha, we need to map SPARSE memory, since we need
2845	 * byte/short access.  This is taken care of automatically by the
2846	 * os-support layer.
2847	 */
2848	pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex,
2849				     VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
2850				     pMga->PciTag, pMga->IOAddress, 0x4000);
2851	if (pMga->IOBase == NULL)
2852	    return FALSE;
2853
2854	pMga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
2855				     pMga->PciTag, pMga->FbAddress,
2856				     pMga->FbMapSize);
2857	if (pMga->FbBase == NULL)
2858	    return FALSE;
2859#endif
2860    }
2861    else {
2862	pMga->FbBase = fbdevHWMapVidmem(pScrn);
2863	if (pMga->FbBase == NULL) {
2864	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2865		       "Unable to map framebuffer.\n");
2866	    return FALSE;
2867	}
2868
2869	pMga->IOBase = fbdevHWMapMMIO(pScrn);
2870	if (pMga->IOBase == NULL) {
2871	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to map MMIO.\n");
2872	    return FALSE;
2873	}
2874    }
2875
2876
2877    pMga->FbStart = pMga->FbBase + pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
2878
2879    pMga->ILOADBase = NULL;
2880    if (pMga->iload_bar != -1) {
2881#ifdef XSERVER_LIBPCIACCESS
2882        region = &dev->regions[pMga->iload_bar];
2883        err = pci_device_map_range(dev,
2884                                   region->base_addr, region->size,
2885                                   PCI_DEV_MAP_FLAG_WRITABLE,
2886                                   (void *) &pMga->ILOADBase);
2887	if (err) {
2888	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2889		       "Unable to map BAR 2 (ILOAD region).  %s (%d)\n",
2890		       strerror(err), err);
2891	    return FALSE;
2892	}
2893#else
2894	pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex,
2895					VIDMEM_MMIO | VIDMEM_MMIO_32BIT |
2896					VIDMEM_READSIDEEFFECT,
2897					pMga->PciTag, pMga->ILOADAddress,
2898					0x800000);
2899#endif
2900    }
2901
2902
2903    return TRUE;
2904}
2905
2906
2907/*
2908 * Unmap the framebuffer and MMIO memory.
2909 */
2910
2911static Bool
2912MGAUnmapMem(ScrnInfoPtr pScrn)
2913{
2914    MGAPtr pMga = MGAPTR(pScrn);
2915#ifdef XSERVER_LIBPCIACCESS
2916    struct pci_device * const dev = pMga->PciInfo;
2917#endif
2918
2919
2920    if (!pMga->FBDev) {
2921#ifdef XSERVER_LIBPCIACCESS
2922        pci_device_unmap_range(dev, pMga->IOBase,
2923			       dev->regions[pMga->io_bar].size);
2924        pci_device_unmap_range(dev, pMga->FbBase,
2925			       dev->regions[pMga->framebuffer_bar].size);
2926#else
2927	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000);
2928	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize);
2929#endif
2930    }
2931    else {
2932	fbdevHWUnmapVidmem(pScrn);
2933	fbdevHWUnmapMMIO(pScrn);
2934    }
2935
2936    if ((pMga->iload_bar != -1) && (pMga->ILOADBase != NULL)) {
2937#ifdef XSERVER_LIBPCIACCESS
2938        pci_device_unmap_range(dev, pMga->ILOADBase,
2939			       dev->regions[pMga->iload_bar].size);
2940#else
2941	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->ILOADBase, 0x800000);
2942#endif
2943    }
2944
2945    pMga->IOBase = NULL;
2946    pMga->FbBase = NULL;
2947    pMga->FbStart = NULL;
2948    pMga->ILOADBase = NULL;
2949
2950    return TRUE;
2951}
2952
2953
2954/*
2955 * This function saves the video state.
2956 */
2957static void
2958MGASave(ScrnInfoPtr pScrn)
2959{
2960    vgaHWPtr hwp = VGAHWPTR(pScrn);
2961    vgaRegPtr vgaReg = &hwp->SavedReg;
2962    MGAPtr pMga = MGAPTR(pScrn);
2963    MGARegPtr mgaReg = &pMga->SavedReg;
2964
2965    if(pMga->SecondCrtc == TRUE) return;
2966#ifdef USEMGAHAL
2967    MGA_HAL(if (pMga->pBoard != NULL) MGASaveVgaState(pMga->pBoard));
2968#endif
2969
2970    /* I need to save the registers for the second head also */
2971    /* Save the register for 0x80 to 0xa0 */
2972    /* Could call it dac2Saved */
2973
2974    /* Only save text mode fonts/text for the primary card */
2975    (*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary);
2976}
2977
2978#ifdef USEMGAHAL
2979/* Convert DisplayModeRec parameters in MGAMODEINFO parameters.
2980*  mode parameter optionnal. */
2981void
2982MGAFillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode)
2983{
2984     const char *s;
2985    MGAPtr pMga = MGAPTR(pScrn);
2986
2987    Bool digital1 = FALSE;
2988    Bool digital2 = FALSE;
2989    Bool tv1 = FALSE;
2990    Bool tv2 = FALSE;
2991    Bool swap_head
2992      = xf86ReturnOptValBool(pMga->Options, OPTION_SWAPPED_HEAD, FALSE);
2993
2994    if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) {
2995        mode = pMga->SecondCrtc ?
2996             ((MergedDisplayModePtr)mode->Private)->Monitor2
2997            : ((MergedDisplayModePtr)mode->Private)->Monitor1;
2998    }
2999
3000
3001    if (pMga->pMgaHwInfo)
3002    {
3003	digital1 = ISDIGITAL1(pMga);
3004	digital2 = ISDIGITAL2(pMga);
3005	tv1 = ISTV1(pMga);
3006	tv2 = ISTV2(pMga);
3007    }
3008
3009    /*FIXME: causes segfault elsewhere if not commented*/
3010    /*if(!pMga->pMgaModeInfo)*/ pMga->pMgaModeInfo = xalloc(sizeof(MGAMODEINFO));
3011    pMga->pMgaModeInfo->flOutput = 0;
3012    pMga->pMgaModeInfo->ulDeskWidth = pScrn->virtualX;
3013    pMga->pMgaModeInfo->ulDeskHeight = pScrn->virtualY;
3014    pMga->pMgaModeInfo->ulFBPitch = 0;
3015    pMga->pMgaModeInfo->ulBpp = pScrn->bitsPerPixel;
3016    pMga->pMgaModeInfo->ulZoom = 1;
3017    pMga->pMgaModeInfo->flSignalMode = 0x10;
3018
3019    /* Set TV standard */
3020    if ((s = xf86GetOptValString(pMga->Options, OPTION_TVSTANDARD))) {
3021    	if (!xf86NameCmp(s, "PAL")) {
3022    		pMga->pMgaModeInfo->flSignalMode = 0x00;
3023    		pMga->pMgaModeInfo->ulRefreshRate = 50;
3024    		pMga->pMgaModeInfo->ulTVStandard = TV_PAL;
3025    	} else {
3026    		pMga->pMgaModeInfo->ulRefreshRate = 60;
3027    		pMga->pMgaModeInfo->ulTVStandard = TV_NTSC;
3028    	}
3029    } else {
3030    	pMga->pMgaModeInfo->ulRefreshRate = 0;
3031    	pMga->pMgaModeInfo->ulTVStandard = TV_NTSC;
3032    }
3033
3034    /* Set Cable Type */
3035    if ((s = xf86GetOptValString(pMga->Options, OPTION_CABLETYPE))) {
3036    	if (!xf86NameCmp(s, "SCART_RGB")) {
3037    		pMga->pMgaModeInfo->ulCableType = TV_SCART_RGB;
3038    	} else if (!xf86NameCmp(s, "SCART_COMPOSITE")) {
3039    		pMga->pMgaModeInfo->ulCableType = TV_SCART_COMPOSITE;
3040    	} else if (!xf86NameCmp(s, "SCART_TYPE2")) {
3041    		pMga->pMgaModeInfo->ulCableType = TV_SCART_TYPE2;
3042    	} else {
3043    		pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE;
3044    	}
3045    } else {
3046    	pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE;
3047    }
3048
3049    if(mode) {
3050        pMga->pMgaModeInfo->ulHorizRate = 0;
3051        pMga->pMgaModeInfo->ulDispWidth = mode->HDisplay;
3052        pMga->pMgaModeInfo->ulDispHeight = mode->VDisplay;
3053        pMga->pMgaModeInfo->ulPixClock = mode->Clock;
3054        pMga->pMgaModeInfo->ulHFPorch = mode->HSyncStart - mode->HDisplay;
3055        pMga->pMgaModeInfo->ulHSync = mode->HSyncEnd - mode->HSyncStart;
3056        pMga->pMgaModeInfo->ulHBPorch = mode->HTotal - mode->HSyncEnd;
3057        pMga->pMgaModeInfo->ulVFPorch = mode->VSyncStart - mode->VDisplay;
3058        pMga->pMgaModeInfo->ulVSync = mode->VSyncEnd - mode->VSyncStart;
3059        pMga->pMgaModeInfo->ulVBPorch = mode->VTotal - mode->VSyncEnd;
3060    }
3061    /* Use DstOrg directly */
3062    /* This is an offset in pixels not memory */
3063    pMga->pMgaModeInfo->ulDstOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8);
3064    pMga->pMgaModeInfo->ulDisplayOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8);
3065    pMga->pMgaModeInfo->ulPanXGran = 0;
3066    pMga->pMgaModeInfo->ulPanYGran = 0;
3067
3068    if(pMga->SecondCrtc == TRUE) {
3069	pMga->pMgaModeInfo->flOutput = MGAMODEINFO_SECOND_CRTC |
3070				       MGAMODEINFO_FORCE_PITCH |
3071				       MGAMODEINFO_FORCE_DISPLAYORG;
3072	if (digital2) {
3073	    pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2;
3074	} else if (tv2) {
3075	    pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV;
3076	} else {
3077            if (!swap_head) {
3078	      pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2;
3079            } else {
3080              pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1;
3081            }
3082	}
3083    } else {
3084	pMga->pMgaModeInfo->flOutput = MGAMODEINFO_FORCE_PITCH;
3085        if (digital1) {
3086	    if ((pMga->Chipset == PCI_CHIP_MGAG200) ||
3087		(pMga->Chipset == PCI_CHIP_MGAG200_PCI)) {
3088		pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_FLATPANEL1;
3089		pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2;
3090	    } else {
3091		pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL1;
3092	    }
3093        } else if (tv1) {
3094	    pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV;
3095       	} else {
3096            if (!swap_head) {
3097	        pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1;
3098            } else {
3099                pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2;
3100            }
3101        }
3102    }
3103    pMga->pMgaModeInfo->ulFBPitch = pScrn->displayWidth;
3104}
3105#endif
3106
3107/*
3108 * Initialise a new mode.  This is currently still using the old
3109 * "initialise struct, restore/write struct to HW" model.  That could
3110 * be changed.
3111 */
3112
3113static Bool
3114MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
3115{
3116    vgaHWPtr hwp = VGAHWPTR(pScrn);
3117    vgaRegPtr vgaReg;
3118    MGAPtr pMga = MGAPTR(pScrn);
3119    MGARegPtr mgaReg;
3120
3121#ifdef USEMGAHAL
3122   ULONG status;
3123#endif
3124    vgaHWUnlock(hwp);
3125
3126/*    if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) {
3127        mode = (DisplayModePtr)mode->Private;
3128    }*/
3129
3130    /* Initialise the ModeReg values */
3131    if (!vgaHWInit(pScrn, mode))
3132	return FALSE;
3133    pScrn->vtSema = TRUE;
3134
3135    if (!(*pMga->ModeInit)(pScrn, mode))
3136	return FALSE;
3137
3138    /* Program the registers */
3139    if (pMga->is_G200SE) {
3140	MGAG200SEHWProtect(pScrn, TRUE);
3141    } else {
3142	vgaHWProtect(pScrn, TRUE);
3143    }
3144    vgaReg = &hwp->ModeReg;
3145    mgaReg = &pMga->ModeReg;
3146#ifdef USEMGAHAL
3147    MGA_HAL(
3148        MGAFillModeInfoStruct(pScrn,mode);
3149
3150        /* Validate the parameters */
3151        if ((status = MGAValidateMode(pMga->pBoard, pMga->pMgaModeInfo)) != 0) {
3152            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3153                    "MGAValidateMode from HALlib found the mode to be invalid.\n"
3154                    "\tError: %lx\n", status);
3155            return FALSE;
3156        }
3157
3158        /*
3159         * Find mode for second head.
3160         */
3161        if(pMga->MergedFB) {
3162
3163            MGAFillModeInfoStruct(pMga->pScrn2,mode);
3164            /* Validates the Video parameters */
3165            if ((status = MGAValidateVideoParameters(pMga->pBoard, MGAPTR(pMga->pScrn2)->pMgaModeInfo))
3166                != 0) {
3167                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3168                        "MGAValidateVideoParameters from HALlib found the mode to be invalid.\n\tError: %lx\n", status);
3169                return FALSE;
3170            }
3171        }
3172    );	 /*MGA_HAL */
3173
3174#endif
3175
3176#ifdef USEMGAHAL
3177MGA_HAL(
3178
3179    /*************************** ESC *****************************/
3180    TmpMgaModeInfo[0] =  *pMga->pMgaModeInfo;
3181
3182    if(pMga->SecondCrtc == TRUE)
3183        pMgaModeInfo[1] = pMga->pMgaModeInfo;
3184    else
3185        pMgaModeInfo[0] = pMga->pMgaModeInfo;
3186
3187	TmpMgaModeInfo[0].ulDispWidth = 0;
3188
3189    if(!pMga->MergedFB) /* FIXME: Must deal with this once PowerDesk & MergedFB
3190                           compatibility will exist */
3191        MGAFillDisplayModeStruct(mode, pMga->pMgaModeInfo);
3192    /*************************************************************/
3193
3194);	/* MGA_HAL */
3195#endif
3196
3197#ifdef XF86DRI
3198   if (pMga->directRenderingEnabled) {
3199       DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
3200   }
3201#endif
3202
3203#ifdef USEMGAHAL
3204    MGA_HAL(
3205    /* Initialize the board */
3206    if(MGASetMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) {
3207	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3208		"MGASetMode returned an error."
3209		"  Make sure to validate the mode before.\n");
3210	return FALSE;
3211    }
3212    if(pMga->MergedFB
3213       && MGASetMode(pMga->pBoard,MGAPTR(pMga->pScrn2)->pMgaModeInfo) != 0) {
3214  	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3215		   "MGASetMode returned an error."
3216		   "  Make sure to validate the mode before.\n");
3217    }
3218
3219    );	/* MGA_HAL */
3220
3221    /* getting around bugs in the HAL lib. MATROX: hint, hint. */
3222    MGA_HAL(
3223	    if (pMga->chip_attribs->hwcursor_1064) {
3224		if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) {
3225		outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW,
3226			  pMga->FbCursorOffset >> 10);
3227		outMGAdac(MGA1064_CURSOR_BASE_ADR_HI,
3228			  pMga->FbCursorOffset >> 18);
3229		outMGAdac(MGA1064_CURSOR_CTL, 0x00);
3230	      }
3231	    }
3232    );	/* MGA_HAL */
3233#endif
3234
3235    MGA_NOT_HAL((*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE));
3236
3237    MGAStormSync(pScrn);
3238    MGAStormEngineInit(pScrn);
3239
3240    if (pMga->is_G200SE) {
3241	MGAG200SEHWProtect(pScrn,FALSE);
3242    } else {
3243	vgaHWProtect(pScrn, FALSE);
3244    }
3245
3246    if (xf86IsPc98()) {
3247	if (pMga->Chipset == PCI_CHIP_MGA2064)
3248	    outb(0xfac, 0x01);
3249	else
3250	    outb(0xfac, 0x02);
3251    }
3252
3253    MGA_NOT_HAL(
3254	if (pMga->is_G200SE) {
3255            OUTREG8(0x1FDE, 0x06);
3256	    if (pMga->reg_1e24 == 0x01)
3257		OUTREG8(0x1FDF, 0x03);
3258	    else
3259		OUTREG8(0x1FDF, 0x14);
3260        }
3261    );
3262
3263    pMga->CurrentLayout.mode = mode;
3264
3265    if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) {
3266	pMga->M1currentMode = (DisplayModePtr)mode->Private;
3267    }
3268
3269#ifdef XF86DRI
3270   if (pMga->directRenderingEnabled)
3271     DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
3272#endif
3273#ifdef DEBUG
3274   MGAG450PrintPLL(pScrn);
3275#endif
3276    return TRUE;
3277}
3278
3279static
3280void MGARestoreSecondCrtc(ScrnInfoPtr pScrn)
3281{
3282    MGAPtr pMga = MGAPTR(pScrn);
3283
3284    if (MGAISGx50(pMga)) {
3285        /* Force to return in clone mode */
3286        if (pMga->SecondOutput
3287                && (xf86IsEntityShared(pScrn->entityList[0]) || pMga->SecondCrtc)
3288                && !pMga->MergedFB) {
3289            /* Do this branch if
3290             * SecondOutput
3291             * and not Unshared Primary
3292             * and not Merged Mode (usualy means Unshared Primary)
3293             */
3294            CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL);
3295
3296            ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK;
3297            ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1;
3298
3299            outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl);
3300
3301       } else {
3302            CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL);
3303            CARD32 ulC2CTL = INREG(MGAREG_C2CTL);
3304
3305            ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK;
3306            ucXDispCtrl |= MGA1064_DISP_CTL_DAC1OUTSEL_EN;
3307            ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1;
3308
3309            /* crtcdacsel -> crtc1 */
3310            ulC2CTL &= ~MGAREG_C2CTL_CRTCDACSEL_CRTC2;
3311            ulC2CTL |= MGAREG_C2CTL_CRTCDACSEL_CRTC1;
3312
3313            outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl);
3314            OUTREG(MGAREG_C2CTL, ulC2CTL);
3315       }
3316
3317    } else {
3318        /* Force to close second crtc */
3319        CARD32 ulC2CTL = INREG(MGAREG_C2CTL);
3320
3321        ulC2CTL &= ~MGAREG_C2CTL_C2_EN;
3322
3323        OUTREG(MGAREG_C2CTL, ulC2CTL);
3324    }
3325}
3326
3327/*
3328 * Restore the initial (text) mode.
3329 */
3330static void
3331MGARestore(ScrnInfoPtr pScrn)
3332{
3333    vgaHWPtr hwp = VGAHWPTR(pScrn);
3334    vgaRegPtr vgaReg = &hwp->SavedReg;
3335    MGAPtr pMga = MGAPTR(pScrn);
3336    MGARegPtr mgaReg = &pMga->SavedReg;
3337
3338    if (pScrn->pScreen != NULL)
3339	MGAStormSync(pScrn);
3340
3341    /*
3342     * Restore the second crtc if:
3343     * first and only driver entity
3344     * second entity
3345     * Merged Framebuffer mode (first and only driver entity)
3346     */
3347    if((!xf86IsEntityShared(pScrn->entityList[0]) && !pMga->SecondCrtc)
3348       || pMga->SecondCrtc || pMga->MergedFB) {
3349	/*       if(pMga->MergedFB) {
3350		 if(pMga->pScrn2)
3351                 MGARestoreSecondCrtc(pMga->pScrn2);
3352		 } else*/
3353	MGARestoreSecondCrtc(pScrn);
3354	/* if we are second instance of driver, we've done our job, exit */
3355	if(pMga->SecondCrtc) return;
3356    }
3357
3358    /* Only restore text mode fonts/text for the primary card */
3359    if (pMga->is_G200SE) {
3360	MGAG200SEHWProtect(pScrn,TRUE);
3361    } else {
3362	vgaHWProtect(pScrn, TRUE);
3363    }
3364    if (pMga->Primary) {
3365#ifdef USEMGAHAL
3366	MGA_HAL(
3367	    if(pMga->pBoard != NULL) {
3368		MGASetVgaMode(pMga->pBoard);
3369		MGARestoreVgaState(pMga->pBoard);
3370	    }
3371	    );	/* MGA_HAL */
3372#endif
3373        (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE);
3374    } else {
3375        vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
3376    }
3377
3378    if (pMga->is_G200SE) {
3379	MGAG200SEHWProtect(pScrn,FALSE);
3380    } else {
3381	vgaHWProtect(pScrn,FALSE);
3382    }
3383}
3384
3385
3386/* Workaround for a G400 CRTC2 display problem */
3387static void
3388MGACrtc2FillStrip(ScrnInfoPtr pScrn)
3389{
3390    MGAPtr pMga = MGAPTR(pScrn);
3391
3392    if (pMga->NoAccel) {
3393	/* Clears the whole screen, but ... */
3394	bzero(pMga->FbStart,
3395	    (pScrn->bitsPerPixel >> 3) * pScrn->displayWidth * pScrn->virtualY);
3396    } else {
3397	xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex);
3398	pMga->RestoreAccelState(pScrn);
3399	pMga->SetupForSolidFill(pScrn, 0, GXcopy, 0xFFFFFFFF);
3400	pMga->SubsequentSolidFillRect(pScrn, pScrn->virtualX, 0,
3401				  pScrn->displayWidth - pScrn->virtualX,
3402				  pScrn->virtualY);
3403	MGAStormSync(pScrn);
3404    }
3405}
3406
3407
3408/* Mandatory */
3409
3410/* This gets called at the start of each server generation */
3411
3412static Bool
3413MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
3414{
3415    ScrnInfoPtr pScrn;
3416    vgaHWPtr hwp;
3417    MGAPtr pMga;
3418    MGARamdacPtr MGAdac;
3419    int ret;
3420    VisualPtr visual;
3421    unsigned char *FBStart;
3422    int width, height, displayWidth;
3423    MGAEntPtr pMgaEnt = NULL;
3424    int f;
3425    CARD32 VRTemp, FBTemp;
3426#ifdef XF86DRI
3427    MessageType driFrom = X_DEFAULT;
3428#endif
3429    DPMSSetProcPtr mga_dpms_set_proc = NULL;
3430
3431    /*
3432     * First get the ScrnInfoRec
3433     */
3434    pScrn = xf86Screens[pScreen->myNum];
3435
3436    hwp = VGAHWPTR(pScrn);
3437    pMga = MGAPTR(pScrn);
3438    MGAdac = &pMga->Dac;
3439
3440    if (pMga->is_G200SE) {
3441	VRTemp = pScrn->videoRam;
3442	FBTemp = pMga->FbMapSize;
3443	pScrn->videoRam = 8192;
3444	pMga->FbMapSize = pScrn->videoRam * 1024;
3445    }
3446
3447
3448    /* Map the MGA memory and MMIO areas */
3449    if (!MGAMapMem(pScrn))
3450	return FALSE;
3451
3452
3453    /* Select functions that vary based on the CRTC configureation of the
3454     * screen.
3455     */
3456    if (!pMga->MergedFB) {
3457	if (pMga->SecondCrtc) {
3458	    mga_dpms_set_proc = MGADisplayPowerManagementSetCrtc2;
3459	    pScreen->SaveScreen = MGASaveScreenCrtc2;
3460	}
3461	else {
3462	    mga_dpms_set_proc = MGADisplayPowerManagementSet;
3463	    pScreen->SaveScreen = MGASaveScreen;
3464	}
3465    }
3466    else {
3467        pScreen->SaveScreen = MGASaveScreenMerged;
3468	mga_dpms_set_proc = MGADisplayPowerManagementSetMerged;
3469    }
3470
3471
3472    if ((pMga->Chipset == PCI_CHIP_MGAG100)
3473	|| (pMga->Chipset == PCI_CHIP_MGAG100_PCI))
3474        MGAG100BlackMagic(pScrn);
3475
3476    if (pMga->DualHeadEnabled) {
3477       DevUnion *pPriv;
3478       pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
3479       pMgaEnt = pPriv->ptr;
3480       pMgaEnt->refCount++;
3481#ifdef USEMGAHAL
3482       MGA_HAL(
3483       if(pMgaEnt->refCount == 1) {
3484	   CARD8 MiscCtlReg;
3485	  pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());
3486	  pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));
3487	  pMga->pClientStruct->pMga = (MGAPtr) pMga;
3488
3489	  /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/
3490          MiscCtlReg = inMGAdac(MGA1064_MISC_CTL);
3491	  MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
3492	  outMGAdac(MGA1064_MISC_CTL,MiscCtlReg);
3493	  pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO));
3494	  MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
3495
3496	  /* Detecting for type of display */
3497	  if (pMga->pMgaHwInfo->ulCapsSecondOutput & MGAHWINFOCAPS_OUTPUT_TV) {
3498	  	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TV detected\n");
3499	  }
3500	  if (pMga->pMgaHwInfo->ulCapsFirstOutput &
3501			MGAHWINFOCAPS_OUTPUT_DIGITAL) {
3502	  	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
3503				"Digital Screen detected\n");
3504	  }
3505	  if (pMga->pMgaHwInfo->ulCapsSecondOutput &
3506			MGAHWINFOCAPS_OUTPUT_DIGITAL) {
3507	  	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
3508				"Digital Screen detected\n");
3509	  }
3510
3511	  /* Now copy these to the entitystructure */
3512	  pMgaEnt->pClientStruct = pMga->pClientStruct;
3513	  pMgaEnt->pBoard = pMga->pBoard;
3514	  pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo;
3515       } else { /* Ref count is 2 */
3516	  pMga->pClientStruct = pMgaEnt->pClientStruct;
3517	  pMga->pBoard = pMgaEnt->pBoard;
3518	  pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo;
3519       }
3520       );	/* MGA_HAL */
3521#endif
3522    } else {
3523#ifdef USEMGAHAL
3524	CARD8 MiscCtlReg;
3525
3526	  MGA_HAL(
3527	  pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());
3528	  pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));
3529	  pMga->pClientStruct->pMga = (MGAPtr) pMga;
3530
3531	  MiscCtlReg = inMGAdac(MGA1064_MISC_CTL);
3532	  /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/
3533	  MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
3534	  outMGAdac(MGA1064_MISC_CTL,MiscCtlReg);
3535	  pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO));
3536	  MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
3537	  );	/* MGA_HAL */
3538#endif
3539    }
3540    if (pMga->is_G200SE) {
3541	pScrn->videoRam = VRTemp;
3542	pMga->FbMapSize = FBTemp;
3543    }
3544#ifdef USEMGAHAL
3545    MGA_HAL(
3546	/* There is a problem in the HALlib: set soft reset bit */
3547	/* MATROX: hint, hint. */
3548	if (!pMga->Primary && !pMga->FBDev &&
3549	    (SUBSYS_ID(pMga->PciInfo) == PCI_CARD_MILL_G200_SG)) {
3550	    OUTREG(MGAREG_Reset, 1);
3551	    usleep(200);
3552	    OUTREG(MGAREG_Reset, 0);
3553	}
3554    );	/* MGA_HAL */
3555#endif
3556
3557    /* Initialise the MMIO vgahw functions */
3558    vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET);
3559    vgaHWGetIOBase(hwp);
3560
3561    /* Map the VGA memory when the primary video */
3562    if (!pMga->FBDev) {
3563	if (pMga->Primary) {
3564	    hwp->MapSize = 0x10000;
3565	    if (!vgaHWMapMem(pScrn))
3566		return FALSE;
3567	}
3568
3569	/* Save the current state */
3570	MGASave(pScrn);
3571	/* Initialise the first mode */
3572	if (!MGAModeInit(pScrn, pScrn->currentMode))
3573	    return FALSE;
3574    }
3575    else {
3576	fbdevHWSave(pScrn);
3577	/* Disable VGA core, and leave memory access on */
3578#ifdef XSERVER_LIBPCIACCESS
3579	pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000000,
3580				  PCI_OPTION_REG);
3581#else
3582	pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000);
3583#endif
3584	if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
3585	    return FALSE;
3586
3587        if (!pMga->SecondCrtc && pMga->HWCursor
3588	    && pMga->chip_attribs->hwcursor_1064) {
3589	    outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, pMga->FbCursorOffset >> 10);
3590	    outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, pMga->FbCursorOffset >> 18);
3591	}
3592
3593	MGAStormEngineInit(pScrn);
3594    }
3595
3596    /* Darken the screen for aesthetic reasons and set the viewport
3597     */
3598    (*pScreen->SaveScreen)(pScreen, SCREEN_SAVER_ON);
3599    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
3600
3601
3602    /*
3603     * The next step is to setup the screen's visuals, and initialise the
3604     * framebuffer code.  In cases where the framebuffer's default
3605     * choices for things like visual layouts and bits per RGB are OK,
3606     * this may be as simple as calling the framebuffer's ScreenInit()
3607     * function.  If not, the visuals will need to be setup before calling
3608     * a fb ScreenInit() function and fixed up after.
3609     *
3610     * For most PC hardware at depths >= 8, the defaults that cfb uses
3611     * are not appropriate.  In this driver, we fixup the visuals after.
3612     */
3613
3614    /*
3615     * Reset the visual list.
3616     */
3617    miClearVisualTypes();
3618
3619    /* Setup the visuals we support. */
3620
3621    /* All MGA support DirectColor */
3622    if (pMga->SecondCrtc) {
3623	/* No DirectColor on the second head */
3624	if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
3625			      TrueColor))
3626		return FALSE;
3627	if (!miSetPixmapDepths ())
3628	    return FALSE;
3629    } else {
3630	if (!xf86SetDefaultVisual(pScrn, -1))
3631	    return FALSE;
3632
3633	if (!miSetVisualTypes(pScrn->depth,
3634			      miGetDefaultVisualMask(pScrn->depth),
3635			      pScrn->rgbBits, pScrn->defaultVisual))
3636	    return FALSE;
3637	if (!miSetPixmapDepths ())
3638	    return FALSE;
3639    }
3640
3641    /*
3642     * Call the framebuffer layer's ScreenInit function, and fill in other
3643     * pScreen fields.
3644     */
3645
3646    width = pScrn->virtualX;
3647    height = pScrn->virtualY;
3648    displayWidth = pScrn->displayWidth;
3649
3650
3651    if(pMga->Rotate) {
3652	height = pScrn->virtualX;
3653	width = pScrn->virtualY;
3654    }
3655
3656    if(pMga->ShadowFB) {
3657 	pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
3658	pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height);
3659	displayWidth = pMga->ShadowPitch / (pScrn->bitsPerPixel >> 3);
3660        FBStart = pMga->ShadowPtr;
3661    } else {
3662	pMga->ShadowPtr = NULL;
3663	FBStart = pMga->FbStart;
3664    }
3665
3666#ifdef XF86DRI
3667     /*
3668      * Setup DRI after visuals have been established.
3669      *
3670      * The DRI does not work when textured video is enabled at this time.
3671      */
3672    if (pMga->is_G200SE) {
3673	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3674		   "Not supported by hardware, not initializing the DRI\n");
3675	pMga->directRenderingEnabled = FALSE;
3676	driFrom = X_PROBED;
3677    } else if (!xf86ReturnOptValBool(pMga->Options, OPTION_DRI, TRUE)) {
3678	driFrom = X_CONFIG;
3679    } else if ( pMga->NoAccel ) {
3680       xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
3681		   "Acceleration disabled, not initializing the DRI\n" );
3682       pMga->directRenderingEnabled = FALSE;
3683       driFrom = X_CONFIG;
3684    }
3685    else if ( pMga->TexturedVideo == TRUE ) {
3686       xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
3687		   "Textured video enabled, not initializing the DRI\n" );
3688       pMga->directRenderingEnabled = FALSE;
3689       driFrom = X_CONFIG;
3690    }
3691    else if (pMga->SecondCrtc == TRUE) {
3692       xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
3693		   "Not initializing the DRI on the second head\n" );
3694       pMga->directRenderingEnabled = FALSE;
3695    }
3696    else if ((pMga->FbMapSize /
3697	       (width * (pScrn->bitsPerPixel >> 3))) <= height * 3) {
3698       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3699	  "Static buffer allocation failed, not initializing the DRI\n");
3700       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3701	  "Need at least %d kB video memory at this resolution, bit depth\n",
3702	  (3 * displayWidth * height * (pScrn->bitsPerPixel >> 3)) / 1024 );
3703       pMga->directRenderingEnabled = FALSE;
3704       driFrom = X_PROBED;
3705    }
3706    else {
3707       pMga->directRenderingEnabled = MGADRIScreenInit(pScreen);
3708    }
3709#endif
3710
3711
3712    if (!fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi,
3713		      pScrn->yDpi, displayWidth, pScrn->bitsPerPixel)) {
3714	return FALSE;
3715    }
3716
3717
3718    if (pScrn->bitsPerPixel > 8) {
3719        /* Fixup RGB ordering */
3720        visual = pScreen->visuals + pScreen->numVisuals;
3721        while (--visual >= pScreen->visuals) {
3722	    if ((visual->class | DynamicClass) == DirectColor) {
3723		visual->offsetRed = pScrn->offset.red;
3724		visual->offsetGreen = pScrn->offset.green;
3725		visual->offsetBlue = pScrn->offset.blue;
3726		visual->redMask = pScrn->mask.red;
3727		visual->greenMask = pScrn->mask.green;
3728		visual->blueMask = pScrn->mask.blue;
3729	    }
3730	}
3731    }
3732
3733    /* must be after RGB ordering fixed */
3734    fbPictureInit (pScreen, 0, 0);
3735
3736    xf86SetBlackWhitePixels(pScreen);
3737
3738    pMga->BlockHandler = pScreen->BlockHandler;
3739    pScreen->BlockHandler = MGABlockHandler;
3740
3741    if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */
3742	MGADGAInit(pScreen);
3743
3744    if (!pMga->NoAccel) {
3745#ifdef USE_EXA
3746	if (pMga->Exa)
3747	    mgaExaInit(pScreen);
3748	else
3749#endif
3750#ifdef USE_XAA
3751	    MGAStormAccelInit(pScreen);
3752#endif
3753    }
3754
3755    miInitializeBackingStore(pScreen);
3756    xf86SetBackingStore(pScreen);
3757    xf86SetSilkenMouse(pScreen);
3758
3759    /* Initialize software cursor.
3760	Must precede creation of the default colormap */
3761    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
3762
3763    /* Initialize HW cursor layer.
3764	Must follow software cursor initialization*/
3765    if (pMga->HWCursor) {
3766	if(!MGAHWCursorInit(pScreen))
3767	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3768		"Hardware cursor initialization failed\n");
3769    }
3770    if(pMga->MergedFB) {
3771        /* Rotate and MergedFB are mutiualy exclusive, so we can use this
3772         * variable.
3773         */
3774        if (!pMga->PointerMoved)
3775            pMga->PointerMoved = pScrn->PointerMoved;
3776        pScrn->PointerMoved = MGAMergePointerMoved;
3777
3778    }
3779
3780    /* Initialise default colourmap */
3781    if (!miCreateDefColormap(pScreen))
3782	return FALSE;
3783
3784    /* Initialize colormap layer.
3785	Must follow initialization of the default colormap */
3786    if (!pMga->SecondCrtc)
3787	f = CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH;
3788    else
3789	f = CMAP_RELOAD_ON_MODE_SWITCH;
3790    if(!xf86HandleColormaps(pScreen, 256, 8,
3791	pMga->FBDev ? fbdevHWLoadPaletteWeak() : MGAdac->LoadPalette,
3792	NULL, f))
3793	return FALSE;
3794
3795    if(pMga->ShadowFB) {
3796	RefreshAreaFuncPtr refreshArea = MGARefreshArea;
3797
3798	if(pMga->Rotate) {
3799	    if (!pMga->PointerMoved) {
3800	    pMga->PointerMoved = pScrn->PointerMoved;
3801	    pScrn->PointerMoved = MGAPointerMoved;
3802	    }
3803
3804	   switch(pScrn->bitsPerPixel) {
3805	   case 8:	refreshArea = MGARefreshArea8;	break;
3806	   case 16:	refreshArea = MGARefreshArea16;	break;
3807	   case 24:	refreshArea = MGARefreshArea24;	break;
3808	   case 32:	refreshArea = MGARefreshArea32;	break;
3809	   }
3810	}
3811
3812	ShadowFBInit(pScreen, refreshArea);
3813    }
3814
3815    xf86DPMSInit(pScreen, mga_dpms_set_proc, 0);
3816
3817    pScrn->memPhysBase = pMga->FbAddress;
3818    pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
3819
3820    MGAInitVideo(pScreen);
3821
3822#ifdef XF86DRI
3823    if (pMga->directRenderingEnabled) {
3824       /* Now that mi, drm and others have done their thing,
3825	* complete the DRI setup.
3826	*/
3827       pMga->directRenderingEnabled = MGADRIFinishScreenInit(pScreen);
3828    }
3829    if (pMga->directRenderingEnabled) {
3830        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
3831    } else {
3832        xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n");
3833    }
3834    if (pMga->DualHeadEnabled && pMga->SecondCrtc == FALSE)
3835	pMgaEnt->directRenderingEnabled = pMga->directRenderingEnabled;
3836    pMga->haveQuiescense = 1;
3837#endif
3838
3839    /* Wrap the current CloseScreen function */
3840    pMga->CloseScreen = pScreen->CloseScreen;
3841    pScreen->CloseScreen = MGACloseScreen;
3842
3843    /* Report any unused options (only for the first generation) */
3844    if (serverGeneration == 1) {
3845	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
3846    }
3847
3848    /* For the second head, work around display problem. */
3849    if (!pMga->MergedFB && pMga->SecondCrtc) {
3850	MGACrtc2FillStrip(pScrn);
3851    }
3852
3853    /* Done */
3854    return TRUE;
3855}
3856
3857
3858/* Usually mandatory */
3859Bool
3860MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
3861{
3862#ifdef USEMGAHAL
3863    char sCmdIn[256];
3864    char sCmdOut[256];
3865    FILE* fdIn;
3866# ifdef MATROX_WRITEBACK
3867    FILE* fdOut;
3868# endif
3869#endif
3870
3871    if  (mode->Flags & 0x80000000) {
3872#ifdef USEMGAHAL
3873
3874# ifdef MATROX_WRITEBACK
3875#  define MWB(x) { x; }
3876#  define MWB_COND(x) x
3877# else
3878#  define MWB(x)
3879#  define MWB_COND(x) 1
3880# endif
3881	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
3882
3883	MGA_HAL(
3884	fdIn = fopen("/tmp/mgaDriverIn", "rt");
3885	MWB(fdOut = fopen("/tmp/mgaDriverOut", "wt"))
3886
3887	if(fdIn && MWB_COND(fdOut))
3888	{
3889
3890	    fgets(sCmdIn, 255, fdIn);
3891
3892	    if(sCmdIn)
3893	    {
3894
3895		MGAExecuteEscCmd(xf86Screens[scrnIndex], sCmdIn, sCmdOut, mode);
3896
3897		/* Remove file and close file descriptor */
3898		remove("/tmp/mgaDriverIn");
3899		fclose(fdIn);
3900		MWB(
3901		    /* Write output data to output file for
3902		       calling application */
3903		    fputs(sCmdOut, fdOut);
3904		    fclose(fdOut);
3905		    )
3906		mode->Flags &= 0x7FFFFFFF;
3907		return TRUE;
3908	    }
3909	    else
3910	    {
3911		mode->Flags &= 0x7FFFFFFF;
3912		return FALSE;
3913	    }
3914	}
3915	else
3916	{
3917	    mode->Flags &= 0x7FFFFFFF;
3918	    return FALSE;
3919	}
3920   )
3921#endif
3922 	return FALSE;
3923    }   else
3924	return MGAModeInit(xf86Screens[scrnIndex], mode);
3925}
3926
3927 /* Adjusts coordinates to match Panning granularity.
3928  * does nothing if the HALlib is not loaded
3929  */
3930void
3931MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y)
3932{
3933#ifdef USEMGAHAL
3934    MGA_HAL(
3935	MGAPtr pMga = MGAPTR(pScrn);
3936	MGAPtr pMga2;
3937	int xg = 1;
3938	int yg = 1;
3939	if(pMga->pMgaModeInfo && pMga->pMgaModeInfo->ulPanXGran && pMga->pMgaModeInfo->ulPanYGran) {
3940	    xg = pMga->pMgaModeInfo->ulPanXGran;
3941	    yg = pMga->pMgaModeInfo->ulPanYGran;
3942	}
3943	if(pMga->pScrn2 && (pMga2 = MGAPTR(pMga->pScrn2)) ) {
3944
3945	    if(pMga2->pMgaModeInfo && pMga2->pMgaModeInfo->ulPanXGran && pMga2->pMgaModeInfo->ulPanYGran) {
3946		xg = max(xg,pMga2->pMgaModeInfo->ulPanXGran);
3947		yg = max(yg,pMga2->pMgaModeInfo->ulPanYGran);
3948	    }
3949	}
3950	xg=16; /*ncoder: temporary */
3951	*x -= *x % xg;
3952	*y -= *y % yg;
3953	);
3954#endif
3955}
3956
3957
3958/*
3959 * This function is used to initialize the Start Address - the first
3960 * displayed location in the video memory.
3961 */
3962/* Usually mandatory */
3963void
3964MGAAdjustFrame(int scrnIndex, int x, int y, int flags)
3965{
3966    ScrnInfoPtr pScrn;
3967    int Base, tmp, count;
3968
3969    MGAFBLayout *pLayout;
3970    MGAPtr pMga;
3971
3972
3973    pScrn = xf86Screens[scrnIndex];
3974    pMga = MGAPTR(pScrn);
3975    pLayout = &pMga->CurrentLayout;
3976
3977        /* wanted to improve panning granularity problems without risking
3978         * compatibility issues. Existing code looked hardware dependent.
3979         */
3980#ifdef USEMGAHAL
3981    MGA_HAL(
3982	    pMga->HALGranularityOffX = x;
3983	    pMga->HALGranularityOffY = y;
3984        MGAAdjustGranularity(pScrn,&x,&y);
3985	    pMga->HALGranularityOffX = pMga->HALGranularityOffX - x;
3986	    pMga->HALGranularityOffY = pMga->HALGranularityOffY - y;
3987        HALSetDisplayStart(pMga->pBoard,x,y,0);
3988    );
3989#endif
3990    MGA_NOT_HAL(
3991        if(pMga->ShowCache && y && pScrn->vtSema)
3992            y += pScrn->virtualY - 1;
3993
3994        Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >>
3995                    (3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]);
3996
3997        if (pLayout->bitsPerPixel == 24) {
3998            if (pMga->Chipset == PCI_CHIP_MGAG400
3999                || pMga->Chipset == PCI_CHIP_MGAG550)
4000                Base &= ~1;  /*1 Not sure why */
4001
4002            Base *= 3;
4003        }
4004
4005        /* find start of retrace */
4006        while (INREG8(0x1FDA) & 0x08);
4007        while (!(INREG8(0x1FDA) & 0x08));
4008        /* wait until we're past the start (fixseg.c in the DDK) */
4009        count = INREG(MGAREG_VCOUNT) + 2;
4010        while(INREG(MGAREG_VCOUNT) < count);
4011
4012        OUTREG16(MGAREG_CRTC_INDEX, (Base & 0x00FF00) | 0x0C);
4013        OUTREG16(MGAREG_CRTC_INDEX, ((Base & 0x0000FF) << 8) | 0x0D);
4014        OUTREG8(MGAREG_CRTCEXT_INDEX, 0x00);
4015        tmp = INREG8(MGAREG_CRTCEXT_DATA);
4016        OUTREG8(MGAREG_CRTCEXT_DATA, (tmp & 0xF0) | ((Base & 0x0F0000) >> 16));
4017    );
4018
4019}
4020
4021void
4022MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags)
4023{
4024    ScrnInfoPtr pScrn;
4025    int Base;
4026    MGAFBLayout *pLayout;
4027    MGAPtr pMga;
4028
4029    pScrn = xf86Screens[scrnIndex];
4030    pMga = MGAPTR(pScrn);
4031    pLayout = &pMga->CurrentLayout;
4032#ifdef USEMGAHAL
4033    MGA_HAL(
4034        MGAAdjustGranularity(pScrn,&x,&y);
4035        HALSetDisplayStart(pMga->pBoard,x,y,1);
4036    );
4037#endif
4038    MGA_NOT_HAL(
4039        if(pMga->ShowCache && y && pScrn->vtSema)
4040            y += pScrn->virtualY - 1;
4041
4042        /* 3-85 c2offset
4043            * 3-93 c2startadd0
4044            * 3-96 c2vcount
4045            */
4046
4047        Base = (y * pLayout->displayWidth + x) * pLayout->bitsPerPixel >> 3;
4048        Base += pMga->DstOrg;
4049        Base &= 0x01ffffc0;
4050        OUTREG(MGAREG_C2STARTADD0, Base);
4051    );
4052}
4053
4054/*
4055 * This is called when VT switching back to the X server.  Its job is
4056 * to reinitialise the video mode.
4057 *
4058 * We may wish to unmap video/MMIO memory too.
4059 */
4060
4061/* Mandatory */
4062static Bool
4063MGAEnterVT(int scrnIndex, int flags)
4064{
4065    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4066    MGAPtr pMga;
4067
4068    pMga = MGAPTR(pScrn);
4069
4070#ifdef XF86DRI
4071    if (pMga->directRenderingEnabled) {
4072	if (pMga->irq) {
4073	    /* Need to make sure interrupts are enabled */
4074	    OUTREG(MGAREG_IEN, pMga->reg_ien);
4075	}
4076        DRIUnlock(screenInfo.screens[scrnIndex]);
4077    }
4078#endif
4079
4080    if (!MGAModeInit(pScrn, pScrn->currentMode))
4081	return FALSE;
4082    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
4083
4084    /* For the second head, work around display problem. */
4085   if (pMga->SecondCrtc) {
4086	MGACrtc2FillStrip(pScrn);
4087    }
4088
4089    return TRUE;
4090}
4091
4092static Bool
4093MGAEnterVTFBDev(int scrnIndex, int flags)
4094{
4095    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4096#ifdef XF86DRI
4097    ScreenPtr pScreen;
4098    MGAPtr pMga;
4099
4100    pMga = MGAPTR(pScrn);
4101    if (pMga->directRenderingEnabled) {
4102        pScreen = screenInfo.screens[scrnIndex];
4103        DRIUnlock(pScreen);
4104    }
4105#endif
4106
4107    fbdevHWEnterVT(scrnIndex,flags);
4108    MGAStormEngineInit(pScrn);
4109    return TRUE;
4110}
4111
4112#define RESTORE_TEXTMODE_ON_DVI(x)                      \
4113    if (MGAISGx50(x) &&                                 \
4114       (ISDIGITAL1(x) || ISDIGITAL2(x))) {              \
4115        /* Reset DUALDVI register */                    \
4116        outMGAdac(MGA1064_DVI_PIPE_CTL, 0x0);           \
4117        /* Set Panel mode between 20 and 54 MHz */      \
4118        outMGAdac(MGA1064_PAN_CTL, 0x7);                \
4119    }
4120
4121
4122/*
4123 * This is called when VT switching away from the X server.  Its job is
4124 * to restore the previous (text) mode.
4125 *
4126 * We may wish to remap video/MMIO memory too.
4127 */
4128
4129/* Mandatory */
4130static void
4131MGALeaveVT(int scrnIndex, int flags)
4132{
4133    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4134    vgaHWPtr hwp = VGAHWPTR(pScrn);
4135#ifdef XF86DRI
4136    MGAPtr pMga = MGAPTR(pScrn);
4137    ScreenPtr pScreen;
4138#endif
4139
4140    MGARestore(pScrn);
4141    vgaHWLock(hwp);
4142
4143    if (xf86IsPc98())
4144	outb(0xfac, 0x00);
4145#ifdef XF86DRI
4146    if (pMga->directRenderingEnabled) {
4147        pScreen = screenInfo.screens[scrnIndex];
4148        DRILock(pScreen, 0);
4149    }
4150#endif
4151#ifdef USEMGAHAL
4152    MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); );
4153#endif
4154}
4155
4156
4157/*
4158 * This is called at the end of each server generation.  It restores the
4159 * original (text) mode.  It should also unmap the video memory, and free
4160 * any per-generation data allocated by the driver.  It should finish
4161 * by unwrapping and calling the saved CloseScreen function.
4162 */
4163
4164/* Mandatory */
4165static Bool
4166MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
4167{
4168    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4169    vgaHWPtr hwp = VGAHWPTR(pScrn);
4170    MGAPtr pMga = MGAPTR(pScrn);
4171    MGAEntPtr pMgaEnt = NULL;
4172
4173#ifdef USEMGAHAL
4174    MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); );
4175#endif
4176    if (pMga->MergedFB)
4177         MGACloseScreenMerged(scrnIndex, pScreen);
4178
4179    if (pScrn->vtSema) {
4180	if (pMga->FBDev) {
4181	    fbdevHWRestore(pScrn);
4182	    MGAUnmapMem(pScrn);
4183        } else {
4184	    MGARestore(pScrn);
4185	    vgaHWLock(hwp);
4186	    MGAUnmapMem(pScrn);
4187	    vgaHWUnmapMem(pScrn);
4188	}
4189    }
4190#ifdef XF86DRI
4191   if (pMga->directRenderingEnabled) {
4192       MGADRICloseScreen(pScreen);
4193       pMga->directRenderingEnabled=FALSE;
4194   }
4195#endif
4196
4197   if (pMga->DualHeadEnabled) {
4198       DevUnion *pPriv;
4199       pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
4200       pMgaEnt = pPriv->ptr;
4201       pMgaEnt->refCount--;
4202   }
4203
4204#ifdef USEMGAHAL
4205   MGA_HAL(
4206   if(pMga->DualHeadEnabled) {
4207      if(pMgaEnt->refCount == 0) {
4208	 /* Both boards have closed there screen */
4209	 MGACloseLibrary(pMga->pBoard);
4210
4211	 if (pMga->pBoard)
4212	   xfree(pMga->pBoard);
4213	 if (pMga->pClientStruct)
4214	   xfree(pMga->pClientStruct);
4215	 if (pMga->pMgaModeInfo)
4216	   xfree(pMga->pMgaModeInfo);
4217	 if (pMga->pMgaHwInfo)
4218	   xfree(pMga->pMgaHwInfo);
4219      }
4220   } else {
4221      MGACloseLibrary(pMga->pBoard);
4222
4223      if (pMga->pBoard)
4224	xfree(pMga->pBoard);
4225      if (pMga->pClientStruct)
4226	xfree(pMga->pClientStruct);
4227      if (pMga->pMgaModeInfo)
4228	xfree(pMga->pMgaModeInfo);
4229      if (pMga->pMgaHwInfo)
4230	xfree(pMga->pMgaHwInfo);
4231   }
4232   );	/* MGA_HAL */
4233#endif
4234
4235#ifdef USE_XAA
4236    if (pMga->AccelInfoRec)
4237	XAADestroyInfoRec(pMga->AccelInfoRec);
4238#endif
4239#ifdef USE_EXA
4240    if (pMga->ExaDriver) {
4241	exaDriverFini(pScreen);
4242	xfree(pMga->ExaDriver);
4243    }
4244#endif
4245    if (pMga->CursorInfoRec)
4246    	xf86DestroyCursorInfoRec(pMga->CursorInfoRec);
4247    if (pMga->ShadowPtr)
4248	xfree(pMga->ShadowPtr);
4249    if (pMga->DGAModes)
4250	xfree(pMga->DGAModes);
4251    if (pMga->adaptor)
4252	xfree(pMga->adaptor);
4253    if (pMga->portPrivate)
4254	xfree(pMga->portPrivate);
4255    if (pMga->ScratchBuffer)
4256	xfree(pMga->ScratchBuffer);
4257
4258    pScrn->vtSema = FALSE;
4259
4260    if (xf86IsPc98())
4261	outb(0xfac, 0x00);
4262
4263    xf86ClearPrimInitDone(pScrn->entityList[0]);
4264
4265    if(pMga->BlockHandler)
4266	pScreen->BlockHandler = pMga->BlockHandler;
4267
4268    pScreen->CloseScreen = pMga->CloseScreen;
4269
4270    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
4271}
4272
4273
4274/* Free up any persistent data structures */
4275
4276/* Optional */
4277static void
4278MGAFreeScreen(int scrnIndex, int flags)
4279{
4280
4281    /*
4282     * This only gets called when a screen is being deleted.  It does not
4283     * get called routinely at the end of a server generation.
4284     */
4285    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
4286	vgaHWFreeHWRec(xf86Screens[scrnIndex]);
4287    MGAFreeRec(xf86Screens[scrnIndex]);
4288
4289}
4290
4291#ifndef HAVE_XF86MODEBANDWIDTH
4292
4293#define MODE_BANDWIDTH MODE_BAD
4294
4295/** Calculates the memory bandwidth (in MiB/sec) of a mode. */
4296static unsigned int
4297xf86ModeBandwidth(DisplayModePtr mode, int depth)
4298{
4299    float a_active, a_total, active_percent, pixels_per_second;
4300    int bytes_per_pixel = (depth + 7) / 8;
4301
4302    if (!mode->HTotal || !mode->VTotal || !mode->Clock)
4303	return 0;
4304
4305    a_active = mode->HDisplay * mode->VDisplay;
4306    a_total = mode->HTotal * mode->VTotal;
4307    active_percent = a_active / a_total;
4308    pixels_per_second = active_percent * mode->Clock * 1000.0;
4309
4310    return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024));
4311}
4312#endif
4313
4314/* Checks if a mode is suitable for the selected chipset. */
4315
4316/* Optional */
4317static ModeStatus
4318MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
4319{
4320    int lace;
4321    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
4322    MGAPtr pMga = MGAPTR(pScrn);
4323
4324    if (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) {
4325	if (mode->HDisplay > 1600)
4326	    return MODE_VIRTUAL_X;
4327	if (mode->VDisplay > 1200)
4328	    return MODE_VIRTUAL_Y;
4329	if (pMga->reg_1e24 == 0x01 &&
4330	    xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 244)
4331	    return MODE_BANDWIDTH;
4332    } else if (pMga->is_G200WB){
4333        if (mode->Flags & V_DBLSCAN)
4334            return MODE_NO_DBLESCAN;
4335	if (pMga->KVM && mode->HDisplay > 1280)
4336	    return MODE_VIRTUAL_X;
4337	if (pMga->KVM && mode->VDisplay > 1024)
4338	    return MODE_VIRTUAL_Y;
4339	if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 318.77)
4340	    return MODE_BANDWIDTH;
4341    } else if (pMga->is_G200EV
4342	       && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 327)) {
4343        return MODE_BANDWIDTH;
4344    } else if (pMga->is_G200EH
4345               && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 375)) {
4346        return MODE_BANDWIDTH;
4347    }
4348
4349    lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
4350
4351    if ((mode->CrtcHDisplay <= 2048) &&
4352	(mode->CrtcHSyncStart <= 4096) &&
4353	(mode->CrtcHSyncEnd <= 4096) &&
4354	(mode->CrtcHTotal <= 4096) &&
4355	(mode->CrtcVDisplay <= 2048 * lace) &&
4356	(mode->CrtcVSyncStart <= 4096 * lace) &&
4357	(mode->CrtcVSyncEnd <= 4096 * lace) &&
4358	(mode->CrtcVTotal <= 4096 * lace)) {
4359
4360	/* Can't have horizontal panning for second head of G400 */
4361	if (pMga->SecondCrtc) {
4362	    if (flags == MODECHECK_FINAL) {
4363		if (pMga->allowedWidth == 0)
4364		    pMga->allowedWidth = pScrn->virtualX;
4365		if (mode->HDisplay != pMga->allowedWidth)
4366		    return(MODE_ONE_WIDTH);
4367	    }
4368	}
4369
4370	return(MODE_OK);
4371    } else {
4372	return(MODE_BAD);
4373    }
4374}
4375
4376
4377/*
4378 * This routine is required but since we can't easily blank the
4379 * second display without risking powering off the monitor, return
4380 * FALSE and let the X server do something generic.
4381 */
4382static Bool
4383MGASaveScreenCrtc2(ScreenPtr pScreen, int mode)
4384{
4385    return FALSE;
4386}
4387
4388/* Do screen blanking */
4389
4390static Bool
4391MGASaveScreen(ScreenPtr pScreen, int mode)
4392{
4393    return vgaHWSaveScreen(pScreen, mode);
4394}
4395
4396
4397/*
4398 * MGADisplayPowerManagementSet --
4399 *
4400 * Sets VESA Display Power Management Signaling (DPMS) Mode.
4401 *
4402 * XXX This needs fixing for sync-on-green!
4403 */
4404void
4405MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
4406			     int flags)
4407{
4408	MGAPtr pMga = MGAPTR(pScrn);
4409	unsigned char seq1 = 0, crtcext1 = 0;
4410
4411	switch (PowerManagementMode)
4412	{
4413	case DPMSModeOn:
4414	    /* Screen: On; HSync: On, VSync: On */
4415	    seq1 = 0x00;
4416	    crtcext1 = 0x00;
4417	    break;
4418	case DPMSModeStandby:
4419	    /* Screen: Off; HSync: Off, VSync: On */
4420	    seq1 = 0x20;
4421	    crtcext1 = 0x10;
4422	    break;
4423	case DPMSModeSuspend:
4424	    /* Screen: Off; HSync: On, VSync: Off */
4425	    seq1 = 0x20;
4426	    crtcext1 = 0x20;
4427	    break;
4428	case DPMSModeOff:
4429	    /* Screen: Off; HSync: Off, VSync: Off */
4430	    seq1 = 0x20;
4431	    crtcext1 = 0x30;
4432	    break;
4433	}
4434
4435	/* XXX Prefer an implementation that doesn't depend on VGA specifics */
4436	OUTREG8(MGAREG_SEQ_INDEX, 0x01);	/* Select SEQ1 */
4437	seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20;
4438	MGAWAITVSYNC();
4439	MGAWAITBUSY();
4440	OUTREG8(MGAREG_SEQ_DATA, seq1);
4441	usleep(20000);
4442	OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01);	/* Select CRTCEXT1 */
4443	crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
4444	OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1);
4445}
4446
4447
4448void
4449MGADisplayPowerManagementSetCrtc2(ScrnInfoPtr pScrn, int PowerManagementMode,
4450				  int flags)
4451{
4452	MGAPtr pMga = MGAPTR(pScrn);
4453	CARD32 val = INREG(MGAREG_C2CTL);
4454
4455	if (PowerManagementMode==DPMSModeOn) {
4456		/* Enable CRTC2 */
4457		val |= MGAREG_C2CTL_C2_EN;
4458		val &= ~MGAREG_C2CTL_PIXCLKDIS_DISABLE;
4459		OUTREG(MGAREG_C2CTL, val);
4460		/* Restore normal MAVEN values */
4461		if (pMga->Maven) {
4462			/* if TV MODE -- for later implementation
4463				MAVW(MONEN, 0xb3);
4464				MAVW(MONSET, 0x20);
4465				MAVW(OUTMODE, 0x08);    output: SVideo/Composite
4466			        MAVW(STABLE, 0x02);             makes picture stable?
4467				fixme? linux uses 0x14...
4468				MAVW(TEST, (MAVR(TEST) & 0x10));
4469
4470			 */
4471			/* else monitor mode */
4472
4473			xf86I2CWriteByte(pMga->Maven, MGAMAV_MONEN, 0xb2);
4474			/* must be set to this in monitor mode */
4475			xf86I2CWriteByte(pMga->Maven, MGAMAV_MONSET, 0x20);
4476			/* output: monitor mode */
4477			xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x03);
4478			/* makes picture stable? */
4479			xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x22);
4480			/* turn off test signal */
4481			xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x00);
4482		}
4483	}
4484	else {
4485		/* Disable CRTC2 video */
4486		val |= MGAREG_C2CTL_PIXCLKDIS_DISABLE;
4487		val &= ~MGAREG_C2CTL_C2_EN;
4488		OUTREG(MGAREG_C2CTL, val);
4489
4490		/* Disable MAVEN display */
4491		if (pMga->Maven) {
4492		/* In order to blank the 2nd display, we must set some MAVEN registers.
4493		 * It seems that not always the same values work on different hardware so
4494		 * we try a few different (possibly redundant) ones. */
4495			/* xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x6a); */
4496			/* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x03); */
4497			/* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x10); */
4498			xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x80);
4499		}
4500
4501	}
4502}
4503
4504
4505static void
4506MGABlockHandler (
4507    int i,
4508    pointer     blockData,
4509    pointer     pTimeout,
4510    pointer     pReadmask
4511){
4512    ScreenPtr      pScreen = screenInfo.screens[i];
4513    ScrnInfoPtr    pScrn = xf86Screens[i];
4514    MGAPtr         pMga = MGAPTR(pScrn);
4515
4516    if(pMga->PaletteLoadCallback)
4517	(*pMga->PaletteLoadCallback)(pScrn);
4518
4519    pScreen->BlockHandler = pMga->BlockHandler;
4520    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
4521    pScreen->BlockHandler = MGABlockHandler;
4522
4523    if(pMga->VideoTimerCallback) {
4524	UpdateCurrentTime();
4525	(*pMga->VideoTimerCallback)(pScrn, currentTime.milliseconds);
4526    }
4527
4528    if(pMga->RenderCallback)
4529	(*pMga->RenderCallback)(pScrn);
4530}
4531
4532#if defined (EXTRADEBUG)
4533/*
4534 * some functions to track input/output in the server
4535 */
4536
4537CARD8
4538MGAdbg_inreg8(ScrnInfoPtr pScrn,int addr,int verbose, char* func)
4539{
4540    CARD8 ret;
4541
4542    ret = MMIO_IN8(MGAPTR(pScrn)->IOBase,addr);
4543    if(verbose)
4544	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4545			"inreg8 : %s: 0x%8x = 0x%x\n",func, addr,ret);
4546    return ret;
4547}
4548
4549CARD16
4550MGAdbg_inreg16(ScrnInfoPtr pScrn,int addr,int verbose, char* func)
4551{
4552    CARD16 ret;
4553
4554    ret = MMIO_IN16(MGAPTR(pScrn)->IOBase,addr);
4555    if(verbose)
4556	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4557			"inreg16: %s: 0x%8x = 0x%x\n",func, addr,ret);
4558    return ret;
4559}
4560
4561CARD32
4562MGAdbg_inreg32(ScrnInfoPtr pScrn,int addr,int verbose, char* func)
4563{
4564    CARD32 ret;
4565
4566    ret = MMIO_IN32(MGAPTR(pScrn)->IOBase,addr);
4567    if(verbose)
4568	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4569			"inreg32: %s: 0x%8x = 0x%x\n",func, addr,ret);
4570    return ret;
4571}
4572
4573void
4574MGAdbg_outreg8(ScrnInfoPtr pScrn,int addr,int val, char* func)
4575{
4576    CARD8 ret;
4577
4578#if 0
4579    if( addr = MGAREG_CRTCEXT_DATA )
4580    	return;
4581#endif
4582    if( addr != 0x3c00 ) {
4583	ret = MGAdbg_inreg8(pScrn,addr,0,func);
4584	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4585			"outreg8 : %s: 0x%8x = 0x%x was 0x%x\n",
4586			func,addr,val,ret);
4587    }
4588    else {
4589	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg8 : %s: index 0x%x\n",
4590	func,val);
4591    }
4592    MMIO_OUT8(MGAPTR(pScrn)->IOBase,addr,val);
4593}
4594
4595void
4596MGAdbg_outreg16(ScrnInfoPtr pScrn,int addr,int val, char* func)
4597{
4598    CARD16 ret;
4599
4600#if 0
4601    if (addr == MGAREG_CRTCEXT_INDEX)
4602    	return;
4603#endif
4604    ret = MGAdbg_inreg16(pScrn,addr,0, func);
4605    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4606			"outreg16: %s: 0x%8x = 0x%x was 0x%x\n",
4607			func,addr,val,ret);
4608    MMIO_OUT16(MGAPTR(pScrn)->IOBase,addr,val);
4609}
4610
4611void
4612MGAdbg_outreg32(ScrnInfoPtr pScrn,int addr,int val, char* func)
4613{
4614    CARD32 ret;
4615
4616    if (((addr & 0xff00) == 0x1c00)
4617    	&& (addr != 0x1c04)
4618/*    	&& (addr != 0x1c1c) */
4619    	&& (addr != 0x1c20)
4620    	&& (addr != 0x1c24)
4621    	&& (addr != 0x1c80)
4622    	&& (addr != 0x1c8c)
4623    	&& (addr != 0x1c94)
4624    	&& (addr != 0x1c98)
4625    	&& (addr != 0x1c9c)
4626	 ) {
4627	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: refused address 0x%x\n",
4628			func,addr);
4629    	return;
4630    }
4631    ret = MGAdbg_inreg32(pScrn,addr,0, func);
4632    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4633			"outreg32: %s: 0x%8x = 0x%x was 0x%x\n",
4634			func,addr,val,ret);
4635    MMIO_OUT32(MGAPTR(pScrn)->IOBase,addr,val);
4636}
4637#endif /* DEBUG */
4638
4639static void
4640MGAG100BlackMagic(ScrnInfoPtr pScrn)
4641{
4642    MGAPtr pMga = MGAPTR(pScrn);
4643
4644    OUTREG(MGAREG_PLNWT, ~(CARD32)0x0);
4645    /* reset memory */
4646    OUTREG(MGAREG_MACCESS, 1<<15);
4647    usleep(10);
4648}
4649
4650