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