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