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