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