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