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